ソースの表示以前のリビジョンバックリンク全て展開する/折り畳む文書の先頭へ Share via Share via... Twitter LinkedIn Facebook Pinterest Telegram WhatsApp Yammer Reddit Teams最近の変更Send via e-Mail印刷パーマリンク × 目次 C# Tips メンバ名を文字列で取得したい コマンドラインオプションを解析したい Excel.Applicationがゾンビプロセスになる問題の対策 ファイルの上書きコピーでUnauthorizedAccessExceptionが出る enumを64ビットフラグとして使う C# Tips メンバ名を文字列で取得したい nameofで取れる。nameofが使えなければ、Expressionとラムダ式を組み合わせると取れる。 コマンドラインオプションを解析したい NDesk.Optionsが超便利。MIT/X11ライセンスなのも素敵。 Excel.Applicationがゾンビプロセスになる問題の対策 Microsoft.Office.Interop.Excel.Applicationでエクセルのシートを操作中に、例外などで異常終了するとexcel.exeがゾンビプロセス化し残り続ける事がある。更に悪い事にExcel.Applicationのプロセスはタスクバーには表れないので、気づいた時には大量のゾンビexcel.exeが存在し、1つずつタスクマネージャで殺していく簡単なお仕事に追われることになる。 この問題は中々根が深くて──というか原因はCOMの解放漏れなんだけど、解放漏れがCでいう所のfreeし忘れなんて明白なものではなく“コードの書き方”ひとつで出来てしまうのが困り物。というわけで、少々行儀は悪いが強制的にガベコレを走らせ、それでもプロセスが残っていたらkillする方向で対策する。 class KillExcelApp { using Excel = Microsoft.Office.Interop.Excel; void ProcExcel() { Excel.Application excelApp = null; System.Diagnostics.Process excelProcess = null; try { excelApp = new Excel.Application(); excelProcess = GetExcelProcess(excelApp); // Excel.Applicationを使った処理 ... // Excel.Applicationを閉じる excelApp.Quit(); excelApp = null; // 念のため待ってみる System.Threading.Thread.Sleep(2000); GC.Collect(); System.Threading.Thread.Sleep(2000); } finally { GC.Collect(); // Excelが残ってたら強制終了 if (excelProcess.HasExited == false) { excelProcess.Kill(); } } } [DllImport("user32.dll")] static extern int GetWindowThreadProcessId(int hWnd, out int lpdwProcessId); System.Diagnostics.Process GetExcelProcess(Excel.Application excelApp) { int id; GetWindowThreadProcessId(excelApp.Hwnd, out id); return System.Diagnostics.Process.GetProcessById(id); } } 他にいい方法があったら教えてください。 参考サイト: C# Excel 操作 EXEが残り続ける c# - Getting excel application process id - Stack Overflow ファイルの上書きコピーでUnauthorizedAccessExceptionが出る パーミッション的には全く問題ない場所で、System.IO.File.Copyで新たにファイルをコピーしたあと、同じファイルに上書きコピーしようとするとSystem.UnauthorizedAccessException例外が発生する事がある。 そんな時はCopyで作成したファイルに対してFile.SetAttributes(file, FileAttributes.Normal)してやる。 enumを64ビットフラグとして使う C#の列挙型は何もしなければint型なので32bit以上の値は扱えないが、longないしulongでenumを作る(正しいC#用語は何と言うんだろう?)と64bitになる。更にフラグの定義では「1L」を使うのがミソ。ただの「1」だと32bit値と見なされ、32ビット以上のシフトが回転してしまう。 enum Flag64 : long { Bit0 = 1 << 0, Bit1 = 1 << 1, Bit32 = 1 << 32, Bit33 = 1L << 33, } Flag64 b0 = Flag64.b0; // b0 == Flag64.Bit0, (long)b0 == 1 Flag64 b1 = Flag64.b1; // b1 == Flag64.Bit1, (long)b1 == 2 Flag64 b32 = Flag64.b32; // b32 == Flag64.Bit0, (long)b32 == 1 Flag64 b33 = Flag64.b33; // b33 == Flag64.Bit33, (long)b33 == 8589934592 programming/cs/cs_tips.txt 最終更新: 2017-12-13 11:37by Decomo