いまさら聞けない「log4net」の使い方
新人君も4ヶ月近く当社での経験を積んだので、成長の証にLog4netをプロジェクトへ導入する手順を書かせた。
ソリューションへNugetを使って、Packageをインストール
メニューの
ツール > Nugetパッケージ マネージャー > ソリューションのNugetパッケージ管理
から、オンラインで「log4net」を検索して、該当プロジェクトへインストールする。
#設定ファイルをAssemblyInfo.csへ記述
該当プロジェクトの
Properties > AssemblyInfo.csを開いて
//Log4Net設定ファイルを指定
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "./設定ファイル名.xml", Watch = true)]
プログラム開始時に、Log4netの設定ファイルの読込ませる
該当プロジェクトのProgram.csに
//アプリケーションのグローバル変数設定
string logFolderName = ログ書込用フォルダのPath;
Environment.SetEnvironmentVariable("グローバル変数名", logFolderName);
//Log4net設定ファイルを読込
//設定ファイルは、AssembleInfo.csへ記述済み
XmlConfigurator.Configure();
Log4netの設定ファイルを作成
AssemblyInfo.csに記述したPathへ、設定ファイルを作成する。
設定
appender ログを出力するモジュール相当 用意されているタイプを設定
・コンソール
・ファイル
など。
appenderへ
・layout
・File名(Path含む)
・日付フォーマット
・ファイル切替
などを設定
<?xml version="1.0" encoding="utf-8" ?> <configuration> <log4net> <!-- コンソール出力用 (VS 上 [出力] ウインドウへの出力) --> <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender"> <!-- 出力文字列のフォーマット --> <layout type="log4net.Layout.PatternLayout"> <param name="ConversionPattern" value="@%-5level>> %message%newline" /> </layout> </appender> <!-- 通常ログ:単一ファイル出力 --> <appender name="InfoLogDailyAppender" type="log4net.Appender.RollingFileAppender"> <!-- ファイル名は日付ごと グローバル変数名で設定したフォルダのLogs¥Info_yyyyMMdd.logで出力--> <param name="File" value="${グローバル変数名}\Logs\Info_" /> <param name="DatePattern" value='yyyyMMdd".log"' /> <param name="RollingStyle" value="date" /> <param name="StaticLogFileName" value="false" /> <AppendToFile value="true" /> <filter type="log4net.Filter.LevelRangeFilter"> <param name="LevelMax" value="Error" /> <param name="LevelMin" value="Trace" /> </filter> <layout type="log4net.Layout.PatternLayout"> <ConversionPattern value="%date [%-5level] - %message%n" /> </layout> </appender> <!-- エラーログ:分割ファイル出力 --> <appender name="ErrorLogDailyAppender" type="log4net.Appender.RollingFileAppender"> <!-- ファイル名は日付ごと --> <param name="File" value="${グローバル変数名}\Logs\Error_" /> <param name="DatePattern" value='yyyyMMdd".log"' /> <param name="RollingStyle" value="date" /> <param name="StaticLogFileName" value="false" /> <param name="AppendToFile" value="true" /> <filter type="log4net.Filter.LevelRangeFilter"> <param name="LevelMax" value="FATAL" /> <param name="LevelMin" value="Warn" /> </filter> <param name="MaximumFileSize" value="10MB" /> <param name="MaxSizeRollBackups" value="10" /> <layout type="log4net.Layout.PatternLayout"> <ConversionPattern value="%date [%-5level] %class %method - %message%n" /> </layout> </appender> <root> <!-- 使用する Appender --> <appender-ref ref="ConsoleAppender" /> <appender-ref ref="InfoLogDailyAppender" /> <appender-ref ref="ErrorLogDailyAppender" /> </root> </log4net> </configuration>
以上で設定は完了。
ClickOnceで困った 2
本日、クライアントから電話があり
「XXXアプリのアップデートが失敗します。」
とのこと。
クライアントは数百台あるのだが、一発目のサポート依頼である。
ClickOnceで配布しているアプリを、昨日修正したので
本日起動すると、最初にアップデートのダイアログが出る。
アップデートをダウンロード中にエラーで止まると言う症状である。
ClickOnceで困った・・・sumurai993.hatenablog.com
のように、アンインストール、再インストールしても
エラーが出るらしい。
Google先生にお願いすると、
ClickOnceでインストールしたアプリにはWindowsレジストリに
アンインストール情報があるとのこと。
HKEY_CURRENT_USER
-Software\
-Microsoft
-Windows
-CurrentVersion
-Uninstall
ここにあるキーを調べて、ShortcutFileNameがアプリ名のものを削除
次に
インストールデータ
HKEY_CURRENT_USER
Software
Classes
Software
Microsoft
Windows
CurrentVersion
Deployment
SideBySide
2.0
PackageMetadata
の下にあるキーの下にあるキーでアプリ名が推測できるようなキーを削除
以上で再インストールが出来ました。
ClickOnceで、またも半日ツブす。
「はじめてのことだから、
上手くいかなくても、いいんだよ。」
と、新入社員と自分に言い聞かせながら・・・・
1. ClickOnceのURLは、ケースセンシティブ?
新人君へのOJTで、テスト用サーバーにClickOnceのインストーラーを置くためのフォルダを作成してもらった。
すぐに、
「http://sample.example.com/Test1/」
を作成しましたと、報告がきました。
こちらは、インストールURLを
「http://samaple.example.com/text1/」
と、していました。
セットアップを発行して、FTPでアップロード。
クリーンなマシンから、アクセスして[インストール]ボタンをクリック。
何度やっても途中で、
URLDownloadToCacheFile failed with HRESULT '-2146697210'
Error: 'http://sample.example.com/Test1/Sample1.application' をダウンロードしようとしてエラーが発生しました。
で、止まる。
Google先生にお伺いして、見つけたものを次々と試すが進展なし。
お昼食べて、ふっと思いついたのが
「ダウンロード失敗とは、パスが違う?????? ってこと?」
と、言うことで、試しに、サーバー側フォルダを"test1"に書き換えると、
すんなりとインストールできました。
やれやれ・・・・・
2. ClickOnceで配布するexeのコンパイルは気を付けよう。
今回のアプリは、メインのexeの他に十本ちょいのクラスライブラリと、フォームを持ち、メインとは別スレッドで動作する必要のあるexeがあります。
そして、これもClickOnceで配布するのですが、何度やっても
"デプロイメント内の参照が、アプリケーション マニフェスト内で定義された ID と一致しません"
と、エラーになる。
又も、Google先生にお伺いして、見つけた中に回答がありました。
ClickOnceでメインと一緒に配布するexeは、
- プロジェクトのプロパティ
- アプリケーション
- リソース
- アイコンとマニフェスト
- リソース
- アプリケーション
の部分で、マニフェストの欄を
[マニフェストなしでアプリケーションを作成します]。
を選択します。
これで、メインを発行して問題無くインストールできました。
しかし、ClickOnceのエラーは、もう少し分かり易くはならないのい?
アプリケーションも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 サービス アプリケーションの開発
後は、やってみてハマれば書くことにする。