ラベル C# の投稿を表示しています。 すべての投稿を表示
ラベル C# の投稿を表示しています。 すべての投稿を表示

2011年6月14日火曜日

[C#]サービス作成時、デバッグするときにデバッガを立ち上げる。

C#でWindowsサービスを作成するにあたって、ステップ実行でのデバッグがしたかったので、以下のようにちょっと工夫をしてみた。
Debugモードでビルドされているときに限り、デバッガ選択画面を立ち上がり、アタッチできます。

/// <summary>
/// サービス起動
/// </summary>
/// <param name="args"></param>
protected override void OnStart(string[] args)
{
    //デバッグ時のみデバッガを起動します。
    DebuggingProcess();

    //以降サービス起動時に行う処理
}

/// <summary>
/// [デバッグ属性メソッド]デバッガ起動
/// </summary>
[Conditional("DEBUG")]
private void DebuggingProcess()
{
    System.Diagnostics.Debugger.Launch();
}

メソッドにデバッグ時のみ実行される属性を付けます。
[Conditional("DEBUG")]

この属性の付いたメソッドは、Relaseモードで実行された場合には実行されません。
処理自体空振りします。

実行すると、デバッガはどれでデバッグしますか?的なウィンドウが現れ、指定したツールでアタッチできます。
ビルドしてインストールしてサービス立ち上げてデバッガ立ち上げてなんて…サービスのデバッグはホント面倒ですね。

2011年4月30日土曜日

Adobe Acrobat か Reader の実行ファイルパスをレジストリから取得する

PDFファイルを印刷したいという要望があり、それの補助用メソッドです。

public static string GetPdfViewerPath()
{
    string path = String.Empty;
    Microsoft.Win32.RegistryKey rKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\Acrobat.exe");
    if (rKey == null) rKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\AcroRd32.exe");

    try
    {
        // レジストリから読み込み
        path = rKey.GetValue("").ToString();
    }
    catch (System.Security.SecurityException) { throw; } //レジストリキーからの読み取りに必要なアクセス許可がユーザーにありません。
    catch (System.UnauthorizedAccessException) { throw; } //必要なレジストリ権限がユーザーにありません。
    //catch (System.ObjectDisposedException) { throw; } //破棄されたキーを参照した場合
    //catch (System.IO.IOException) { throw; }
    catch
    {
        throw new ApplicationException("AdobeR AcrobatR もしくは ReaderR がインストールされていないため、PDFファイルの印刷ができません。");
    }
    finally
    {
        rKey.Close();
        rKey = null;
    }

    return path;
}

途中、try-catchでSystem.ObjectDisposedExceptionとSystem.IO.IOExceptionの捕捉をコメントにしているのは、その2つの例外が発生した場合にもインストールされていないと判断するためです。


以下余談

Adobe Reader単体でコマンド引数を使用して直接印刷をかけるのは止めたほうがいいと個人的には思う。
何故かというと、Adobe Readerに直接PDFファイルのパスを渡して印刷する方法だと、Adobe Reader自体の画面表示させないように設定してもバックグラウンドで動かなかったり、印刷完了しても画面が閉じられずプロセスが残ってしまうことがあるからです。
印刷はできるけどね。

こればかりは何ともいえないところですが、回避策としてとりあえず2点。
1. タイムアウトを指定して、印刷されたであろう時間が経過した後にプロセスをkillする
2. プリンタのキューを監視してプリンタへの印刷指示が完了したことを確認後プロセスをkillする


出来れば、Adobe Acrobat SDKでそれ用のプログラムを作成することをおすすめする。

なんかいい方法ないもんかね。