アプリケーションもWindowsとMacを出来る限り合わせる

Macにインストールしたアプリ

Windows版、Mac版があるもの

日本語IM
セキュリティソフト
  • ESET Cyber Security
ブラウザ

 メール環境は会社でGoogle Apps使用のためブラウザ上で使用する。

  • Firefow
クラウド(全デバイスでデータを同期させるため)
  • Pocket
  • oneDrive
テキストエディタ
IDE
  • phpStorm
  • pyCharm
ツール
  • Wire Shark(パケットモニタ)
  • Source Tree(gitクライアント)
画像・動画編集
ローカル仮想環境

Mac版がないので、代替を探したもの

 出来る限り使い勝手が同じ(見栄えや操作)ようになるようにした。

Mac用しかないアプリ

 Mac用のみリリースされているアプリ

Xcode
 ご存じAppleが提供しているIDE

・homebrew
 Debian系のパッケージ管理ツールのaptと同じように使えるMac用パッケージ管理ツール

・Alfred2
 ランチャー(アプリを起動するためのもの)かと思っていたら、マシン内やEvernoteからWikipediaAmazonなど、何でも対象に検索してくれる優れもの。

 無料版を使ってみて、即有料版にアップグレードした。

・BetterTouchTool
 トラックパッドをメチャ便利にしてくれる優れもの

・Sequel Pro
 MySQLGUIクライアント

Microsoft Remote Desktop
リモートでWindowsデスクトップが操作できるアプリ。無ければVNCでも良かった。

・iTerm2
画面が2分割、4分割、タブで開くなど便利なターミナル。

Windows版しかないもの


以上で、ほぼ使い勝手を統一できて、開発については、Windowsとそれ以外でマシンの使い分けができるようになりました。

C# アプリケーションのスタート時にフォームを開かないでシステムトレイに入れる

やりたいこと

セキュリティソフトなどのように、起動したらフォームを開かないで、Windowsのシステムトレイにアイコンを表示する。

例)20秒毎に何かを行い、システムトレイにバルーンでお知らせする。

実装

  • ウィザードで、C#Windowsフォームプロジェクトを作成する。
  • Form1にtimerコントロールを貼る。
  • timerコントロールのIntervalを20000ミリ秒に設定
  • Form1のShowInTaskbarプロパティをFalseに設定
  • Program.csを開いて、以下のように変更する。

  [STAThread]
  static void Main()
  {
    //ここの2行は変更なし
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

    //二重起動を防ぐ
    //Mutexクラスの作成
    //"MyName"の部分を適当な文字列に変える
    System.Threading.Mutex mutex =
       new System.Threading.Mutex(true, "MyName", out createdNew);
    if (createdNew == false)
    {
      //起動させない
      return;
    }

    using (NotifyIcon icon = new NotifyIcon())
    {
      icon.Icon =  System.Drawing.Icon.ExtractAssociatedIcon(Application.ExecutablePath);

      //フォームのインスタンスを作成する
      Form1 form1 = new Form1();
      //Form1のNotifyIconメンバーに、このNotifyIconのインスタンスを登録
      form1.NotifyIcon = icon;

      //システムトレイのアイコンの右クリックメニュー登録
      icon.ContextMenu = new ContextMenu(new MenuItem[] {
        new MenuItem("ウィンドウを開く", (s, e) => {form1.ShowForm();}),
        new MenuItem("終了", (s, e) => { Application.Exit(); }),
      });
      icon.Visible = true;

      Application.Run();
      icon.Visible = false;
    }
    //ミューテックスを解放する
    mutex.ReleaseMutex();
  }
 


Form1の実装

 
    internal NotifyIcon NotifyIcon { get; set; }


    private void timer1_Tick(object sender, EventArgs e)
    {
      //balloonTip表示
      NotifyIcon.BalloonTipIcon = ToolTipIcon.Info;
      NotifyIcon.BalloonTipTitle = "20秒経ちましたよ!";
      NotifyIcon.BalloonTipText = "お知らせの本文ですよ!";
      //3秒表示
      NotifyIcon.ShowBalloonTip(3000);
    }

    //アイコン右クリックの「ウィンドウを開く」で呼ばれるメソッド
    public void ShowForm()
    {
      // フォームの表示
      this.Visible = true;
      if (this.WindowState == FormWindowState.Minimized)
      {
        // 最小化をやめる
        this.WindowState = FormWindowState.Normal;
      }

      // Notifyアイコン非表示
      NotifyIcon.Visible = false;
      this.Activate();
    }
      
    //フォームのイベント(ボタンクリックなど)で再度システムトレイに格納
    private void ShowIconSystemTray()
    {
      //フォームを非表示に
      this.Visible = false;
      //最小化
      this.WindowState = FormWindowState.Minimized;
      //システムトレイのアイコン表示
      NotifyIcon.Visible = true;
    }

Yosemiteが出たのでMacも併用を始めたらWindows捨てる気になった

[2015/07/22 追記]

背景

 Django利用のサービスやWordPressのPluginなどのサーバー側の開発も管理するようになったが、

  • Windowsでは、サーバー側の開発環境を作成するのがメンドウ
  • 丁度良いタイミングでYosemiteがリリースされた

ため、長い間インテリア化していたMac miniを使うことにした。

実環境

実際の環境は、
f:id:kz1114inazuma:20141122084856p:plain

のように、狭い机の上に、配置している。

  • 27inchモニタを横置きでメインに

を、WindowsMac OS XKVMスイッチで切り替えて使っている。

  • 24inchの縦置きモニタは、HDMIの切替機で切替
  • マウスはWindows用、トラックパッドはMac

なので、縦型にWindowsの画面を出してマウスで操作しながら、メイン画面のMacをキーボードで操作と言うことも出来る。

Windowsマシン

 OS:Windows 8.1
 
 VS2013を使ってWindows Formを使ったアプリの開発に使う

Mac mini

 OS:Yosemiteクリーンインストール

 2年前にメモリ8Gに増設し、ハードディスクはSSDに換装済みで放置してあったマシン

 後述するアプリをインストールして、サーバーサイド側の開発に使う

キーボード操作の共通化(US配列のキーボードを使用)


 今まではWindowsがメインだったので、

  • 日本語:英数切替 → 左Alt + 左バッククォート
  • コピぺなど → CtrlキーとC,V,X,Zなどの組合せ

が、Mac OSでは、

  • 日本語:英数切替 → コマンド + スペース
  • コピぺなど → コマンドキーとC,V,X,Zなどの組合せ

となっている。

 現在使用中のUS配列のWindwos用キーボードだと、コマンドキーがWindowsキーとなる。
操作が違うため、いちいち作業が中断する。慣れれば良いのかもしれないが、今までのクセは抜けない。

解決策

 Mac側に以下のアプリをインストールして操作をWindowsに合わせた。それぞれの使い方は
こちらMac - seil と Karabiner で日本語入力をカスタマイズする - Qiita
にあります(感謝)。
 

Karabiner

f:id:kz1114inazuma:20141122093253p:plain

これでWindwsキーとCtrlキーを入替ることで、Windowsと同じCtrl + C,V,X,Zなどが実現出来た。

ただ、iTerm2などでコマンド実行を中断する場合には、仕方ないのでWindowsキー + Cで行う。

Seil

f:id:kz1114inazuma:20141122093817p:plain


これで、設定ファイルに[Alt + バッククォート]を追加して、日本語:英数切替が出来るようになった。

Mac VS Windows

 最近は、Macのシェアが伸びてきたせいか、FirefoxChromeなどをはじめとしてWindowsMacともに動作するアプリが沢山あります。

は、毎日使うので同じ操作で使えるのはメチャ便利です。もうOSの違いを意識しないでも良いのかと思うくらいです。

Macの方が優れていること

 使い始めて3週間くらいですが、現在はVS2013を使う以外は、ほぼMac状態です。

理由は

Macは画面がキレイ過ぎる

 特に同じモニタを切り替えて使っているので差が歴然としている。目の疲れ方が全然違う。正直Windowsに戻れない。

MacUnix系との親和性が高すぎ

 ベースがBSDなので当然かもしれませんが、homebrewがあるので、Unix系のコマンド、アプリ、言語は全てOKな上にiTerm2で画面分割が強力。

 開発環境を作成するために使う、Vagrant(VertualBox)が便利過ぎ(Windows8.1ではVertualBoxが動かなかった)。

トラックパッド離せない

 BetterTouchToolとの組合せは卑怯なくらい便利過ぎ。


 このままWindowsを使わなくても良くなるのなら、VSを使うプロジェクトから抜ける方法を考えなくてはならない。

Macでチョっと困っていること

 タイミング的にいつなのか特定出来ないのだが、レインボーくるくるが出て操作を受け付けなることが、1日に数回ある。

 休憩しろと言うことなのかも知れないが、正直急いでいるときに限って出るので困っている。



 メイン画面は横画像、サブ画面は縦長の画像をデスクトップ背景として使っているが、再起動すると、それぞれに指定している壁紙フォルダがズレる。

 メイン画面に縦長画像が一部拡大表示され、サブ画面に横画像が一部拡大表示されるので都度設定し直しとなる。



[2015/07/22 追記]

 アップデートで最近は、レインボーくるくる(正式名は未だに知らない)は出なくなった。


再起動すると、縦壁紙の指定フォルダが切り替わる件は、使用しているHDMI切替機と私の使用方法が原因でした。

Yosemiteをシャットダウンする際に、シャットダウン完了前にWindowsに切替えると
Macからみれば、縦モニタがいなくなったと判断するようです。

その時点で、Macからは横モニタだけとなり、壁紙設定も横モニタだけになる。

次回、マルチモニタで起動しても、壁紙設定は、横しか残っていない。


対策
 Macシャットダウン時は、完了まで両モニタを切り替えない。



Windows!さようなら。君との付き合いもこれまでかな?

  • MS-Dos 3.x(詳しいバージョンは覚えていない)〜MS-Dox 5.x

と、Windowsと人生過ごしてきたが、この年にしてMacに切替とは・・・・思ってもいませんでした。


以上、ただの独り言です。



 

Windowsサービスを作る

初めてWindowsサービスを作ることになった。

とりあえず資料を漁る。

MSDN
方法 : Windows サービスを作成する
方法 : Windows サービス アプリケーションをデバッグする
Windows サービス アプリケーションの開発

後は、やってみてハマれば書くことにする。

Windows Phone Emulator と VMWare

 Microsoftが、やっとのことで、WindowsXPのサポートを終了してくれたので、動作チェックの対象が、ひとつ減った。

 ひとつ減ったとは言え、インストール・動作チェックを行うために、VMWare Wordkstationを使って

 の環境を作成している。


 この前、Visual Studio 2013のUpdate2が公開されたとのことなので、インストールする際に、その他のアップデートチェックを行った。

 すると、

 「Windows Phone SDKもアップデートあり」

と、出たのでアップデートを行う。




すると・・・・・・


 VMWareを起動して、仮想マシンをONにしたところ

 「Hyper-Vは・・・・・」

とエラーになって起動しません。



 最近行った変更は、上記とWindows Updateのみなので、Windows Phone SDKがクサいと思い、アンインストールをしようと思ったが、

 VSの[ツール]-[拡張機能と更新プログラム]からでは、Windows Phome SDKはアンインストール出来ない。

 「Windowsのコントロールパネルのプログラムから行え」

 と、書いてある。


 でも、コントロールパネルのプログラムには、Windows Phone SDKがない・・・・・



 しかたないので、ググってみると、

 「Windows8Hyper-Vを無効にする」

ページを見つけたので、実行してみる。


 コントロールパネルの
  →プログラムと機能
   →Windowsの機能の有効化または無効化

で、ウィンドウを開いて、Hyper-VチェックボックスをOFFにする。


 再起動を求められるので、再起動。


 無事に、VMWareを起動し、仮想マシンも起動出来た。


 誰か同じ地雷を踏んだ方のために・・・・

FTPでファイルのダウンロードと進行状況の表示

C#Windows上のフォームから、FTPでファイルをダウンロードする必要があったので、以下で実装しました。

 

前提条件として、

  • ダウンロード中の進行状況の表示
  • ユーザによる途中キャンセル

が、ありました。

 

以下、フォームに

が、貼ってあるものとします。

 

キャンセルボタンのEnable化などは省略

 

>|cs|

        //ダウンロード中のフラグ
  private bool onDownloading = false;
  //ダウンロード用のWebClient
        private WebClient wc = null;

        //ダウンロードボタンクリック
        private void downloadButton_Click(object sender, EventArgs e)
        {
            Uri uri = new Uri("ダウンロード先のパス ftp://example.com/example.txt");
            if (wc == null)
            {
                wc = new WebClient();               

               //webClientに進行状況、完了時のイベントハンドラを追加
                wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged);
                wc.DownloadFileCompleted += new AsyncCompletedEventHandler(wc_DownloadFileCompleted);
            }

   //ダウンロード開始
             wc.DownloadFileAsync(uri, "保存先のローカルパス")
             onDownloading = true;
        }

        //ダウンロードの進歩イベント
        private void wc_DownloadProgressChanged(Object sender, DownloadProgressChangedEventArgs e)
        {
            progressBar1.Value = e.ProgressPercentage;
        }

        //完了時のイベント
        private void wc_DownloadFileCompleted(Object sender, AsyncCompletedEventArgs e)
        {
            if ( (e.Error != null) && (!e.Cancelled) )
            {
                MessageBox.Show("ダウンロード中にエラーが発生しました。内容:" + e.Error.Message, "エラー",
                            MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else if (e.Cancelled)
            {
                MessageBox.Show("ダウンロードがキャンセルされました。", "完了", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                MessageBox.Show("データのダウンロードが完了しました。", "完了", MessageBoxButtons.OK, MessageBoxIcon.Information); 
            }
            onDownloading = false;
        }

 

        //キャンセルボタンクリック
        private void cancelButton_Click(object sender, EventArgs e)
        {
            //ダウンロード中なら、ダウンロードをキャンセルする
            if (onDownloading)
            {
                if (wc != null)
                {
                    wc.CancelAsync();
                }
            }
        }

ClickOnceで困った・・・

過去の遺物だと思っていた「dll hell」の再来か??????

 

ClickOnceって、内部でどのように動いているのかまで理解していない(もっとも、普通のmsiのセットアップだとて理解出来ていない)が、非常に便利なので、標準で使っている。

 

特に、修正を行ったとき、「サーバーに上げてお仕舞い!」の手軽さが最高だった。

 

しかし、本日は、困った。

 

いつものように、

 ・バージョン番号を確認して

 ・発行して

 ・サーバーに上げて

 ・テストマシンで、対象アプリを起動すると

 ・いつものように、アップデートのダイアログが出て

 ・OKをクリックすると

 

エラーになった・・・・・・・

 

 

詳細ボタンをクリックすると

エラーの詳細
    この操作中に次のエラーが検出されました。
    * [2014/03/13 10:59:11] System.ArgumentException
        - 値が有効な範囲にありません。
        - ソース:System.Deployment
        - スタック トレース:
            場所 System.Deployment.Internal.Isolation.IStore.LockApplicationPath(UInt32 Flags, IDefinitionAppId ApId, IntPtr& Cookie)
            場所 System.Deployment.Application.ComponentStore.LockApplicationPath(DefinitionAppId definitionAppId)
            場所 System.Deployment.Application.SubscriptionStore.LockApplicationPath(DefinitionAppId definitionAppId)
            場所 System.Deployment.Application.FileDownloader.PatchFiles(SubscriptionState subState)
            場所 System.Deployment.Application.FileDownloader.Download(SubscriptionState subState)

 

こんなスタックトレースでは、わからん。

 

ぐぐっても、

インストールされる

C:\Users\ユーザ名\AppData\Local\Apps\2.0

以下のフォルダを削除しろ!

 

とか、バカなことしか見つからない。

 

削除したら、他のClickOnceアプリとデータが吹っ飛ぶでしょうが?

 

 

Gitで、以前のアップデートリリース時点まで戻り

再度、ファイルを修正して発行しても同じ。

 

 

発行したセットアップファイルに問題があるのか?

インストールしたテストマシンに問題があるのか?

 

誰か、教えて下さい。

 

追記

 

エラーの出るマシンと出ないマシンとがある。

結局は、エラーの出るマシンは、アンインストール、再インストールで対応する。

 

しかし、データをClickOnceに任せていたら、一緒にアンインストールされるので、データは別なところへ置かないと、気軽にアンインストール出来なくなる。