アプリケーションもWindowsとMacを出来る限り合わせる
Macにインストールしたアプリ
Windows版、Mac版があるもの
日本語IM
セキュリティソフト
- ESET Cyber Security
画像・動画編集
- Adobe CC
ローカル仮想環境
- VirtualBox(Windws8.1では落ちるので使えなかった。WindowsではVM Wareを使用)
Mac用しかないアプリ
Mac用のみリリースされているアプリ
・homebrew
Debian系のパッケージ管理ツールのaptと同じように使えるMac用パッケージ管理ツール
・Alfred2
ランチャー(アプリを起動するためのもの)かと思っていたら、マシン内やEvernoteからWikipediaやAmazonなど、何でも対象に検索してくれる優れもの。
無料版を使ってみて、即有料版にアップグレードした。
・BetterTouchTool
トラックパッドをメチャ便利にしてくれる優れもの
・Microsoft Remote Desktop
リモートでWindowsデスクトップが操作できるアプリ。無ければVNCでも良かった。
・iTerm2
画面が2分割、4分割、タブで開くなど便利なターミナル。
Windows版しかないもの
- Internet Explore 表示確認に必要
- Visual Studio 2013
- Rlogin Windows用のターミナル
以上で、ほぼ使い勝手を統一できて、開発については、Windowsとそれ以外でマシンの使い分けができるようになりました。
C# アプリケーションのスタート時にフォームを開かないでシステムトレイに入れる
実装
- 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を使うことにした。
実環境
実際の環境は、
のように、狭い机の上に、配置している。
- 27inchモニタを横置きでメインに
- RealforceのUS配列キーボード
を、WindowsとMac OS XにKVMスイッチで切り替えて使っている。
- 24inchの縦置きモニタは、HDMIの切替機で切替
なので、縦型にWindowsの画面を出してマウスで操作しながら、メイン画面のMacをキーボードで操作と言うことも出来る。
Windowsマシン
OS:Windows 8.1
VS2013を使ってWindows Formを使ったアプリの開発に使う
キーボード操作の共通化(US配列のキーボードを使用)
今まではWindowsがメインだったので、
- 日本語:英数切替 → 左Alt + 左バッククォート
- コピぺなど → CtrlキーとC,V,X,Zなどの組合せ
が、Mac OSでは、
- 日本語:英数切替 → コマンド + スペース
- コピぺなど → コマンドキーとC,V,X,Zなどの組合せ
となっている。
現在使用中のUS配列のWindwos用キーボードだと、コマンドキーがWindowsキーとなる。
操作が違うため、いちいち作業が中断する。慣れれば良いのかもしれないが、今までのクセは抜けない。
Mac VS Windows
最近は、Macのシェアが伸びてきたせいか、FirefoxやChromeなどをはじめとしてWindows、Macともに動作するアプリが沢山あります。
- Adobe CC
は、毎日使うので同じ操作で使えるのはメチャ便利です。もうOSの違いを意識しないでも良いのかと思うくらいです。
Macの方が優れていること
使い始めて3週間くらいですが、現在はVS2013を使う以外は、ほぼMac状態です。
理由は
MacはUnix系との親和性が高すぎ
ベースが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サービスを作る
初めてWindowsサービスを作ることになった。
とりあえず資料を漁る。
MSDN
方法 : Windows サービスを作成する
方法 : Windows サービス アプリケーションをデバッグする
Windows サービス アプリケーションの開発
後は、やってみてハマれば書くことにする。
Windows Phone Emulator と VMWare
Microsoftが、やっとのことで、WindowsXPのサポートを終了してくれたので、動作チェックの対象が、ひとつ減った。
ひとつ減ったとは言え、インストール・動作チェックを行うために、VMWare Wordkstationを使って
- Windows Vista 32bit/64bit
- Windows7 32bit/64bit
- Windows8.1 64bit
の環境を作成している。
この前、Visual Studio 2013のUpdate2が公開されたとのことなので、インストールする際に、その他のアップデートチェックを行った。
すると、
と、出たのでアップデートを行う。
すると・・・・・・
「Hyper-Vは・・・・・」
とエラーになって起動しません。
最近行った変更は、上記とWindows Updateのみなので、Windows Phone SDKがクサいと思い、アンインストールをしようと思ったが、
VSの[ツール]-[拡張機能と更新プログラム]からでは、Windows Phome SDKはアンインストール出来ない。
「Windowsのコントロールパネルのプログラムから行え」
と、書いてある。
でも、コントロールパネルのプログラムには、Windows Phone SDKがない・・・・・
しかたないので、ググってみると、
ページを見つけたので、実行してみる。
コントロールパネルの
→プログラムと機能
→Windowsの機能の有効化または無効化
で、ウィンドウを開いて、Hyper-VのチェックボックスをOFFにする。
再起動を求められるので、再起動。
誰か同じ地雷を踏んだ方のために・・・・
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に任せていたら、一緒にアンインストールされるので、データは別なところへ置かないと、気軽にアンインストール出来なくなる。