2018年1月30日火曜日

C#で、キックする実行モジュールのフルパスをレジストリから取得する(環境変数は登録されていない)


・処理対象のファイルの拡張子は分かっている
・実行モジュールは指定したい
・実行モジュールがどこにインストールされているか分からない
・環境変数に登録されていない

そんな状況なんですが、目的としてはDXFファイルをSVGファイルに変換したい。
その為には、Inkscapeをコマンドで呼び出し処理させる。
だけれど、拡張子「DXF」はAutocadなどに関連付いている可能性がある、と。

UACの絡みとかも有り、シンプルで確実に動く方法が意外と見つからなかった。
最終的に上手くいったコードが以下。

レジストリの構成を説明してくれている記事があったので、手順的にはその内容を使っていますが、、どこのページか分からなくなってしまいました。すまそ。

例) テキストファイル(拡張子:.txt)
「HKEY_CLASSES_ROOT\.txt」の値は「txtfile」。
引き続き「HKEY_CLASSES_ROOT\txtfile」配下のパス、
「HKEY_CLASSES_ROOT\txtfile\shell\open\command」の値は「%SystemRoot%\system32\NOTEPAD.EXE %1」
これを文字列操作して取得。

/// <summary>
/// 実行モジュールのフルパスを探す
/// </summary>
/// <param name="characteristic">見つけたいモジュールのモジュール名</param>
/// <param name="exts">関連付けられている可能性のある拡張子(複数可能)</param>
/// <returns>モジュールのフルパス</returns>
private string FindFullPath(string characteristic, string[] exts)
{
    RegistryKey regKey1 = null;
    RegistryKey regKey2 = null;
    try
    {
        for (int i = 0; i <= exts.Length; i++)
        {
            // キーのパスを指定してレジストリを開く
            regKey1 = Registry.ClassesRoot.OpenSubKey(exts[i]);
            // レジストリの値を取得
            string regValue1 = (string)regKey1.GetValue(null);
            regKey1.Close();
            // 確認
            if (string.IsNullOrEmpty(regValue1) == true) { continue; }
            // キーのパスを指定してレジストリを開く
            regKey2 = Registry.ClassesRoot.OpenSubKey(regValue1 + "\\shell\\open\\command");
            // レジストリの値を取得
            string regValue2 = (string)regKey2.GetValue(null);
            regKey2.Close();
            // 確認
            if (string.IsNullOrEmpty(regValue2) == true) { continue; }
            // 一致の確認
            int pos = regValue2.IndexOf(characteristic);
            if (pos < 0) { continue; }
            // 文字列操作して返す
            return regValue2.Substring(1, pos + characteristic.Length - 2);
        }
    }
    catch (Exception ex)
    {
        try { regKey1.Close(); } catch { }
        try { regKey2.Close(); } catch { }
    }
    return null;       // 抜けていたので追加
}

※動作しているコードを編集しました
※編集後のコンパイル/動作確認は行っていません

0 件のコメント:

コメントを投稿