61

特定のファイルタイプを編集するプログラムを作成しました。起動時にアプリケーションをこのファイルタイプのデフォルトのエディターとして設定するオプションをユーザーに提供したいと考えています (インストーラーが必要ないため)。

HKEY_CLASSES_ROOT にキーを追加して、ファイルを関連付ける再利用可能なメソッドを作成しようとしましたが (できれば、Vista を実行していますが、どの OS でも可能です)、アプリケーションでそれを使用していますが、そうではありません。動作するようです。

public static void SetAssociation(string Extension, string KeyName, string OpenWith, string FileDescription)
{
    RegistryKey BaseKey;
    RegistryKey OpenMethod;
    RegistryKey Shell;
    RegistryKey CurrentUser;

    BaseKey = Registry.ClassesRoot.CreateSubKey(Extension);
    BaseKey.SetValue("", KeyName);

    OpenMethod = Registry.ClassesRoot.CreateSubKey(KeyName);
    OpenMethod.SetValue("", FileDescription);
    OpenMethod.CreateSubKey("DefaultIcon").SetValue("", "\"" + OpenWith + "\",0");
    Shell = OpenMethod.CreateSubKey("Shell");
    Shell.CreateSubKey("edit").CreateSubKey("command").SetValue("", "\"" + OpenWith + "\"" + " \"%1\"");
    Shell.CreateSubKey("open").CreateSubKey("command").SetValue("", "\"" + OpenWith + "\"" + " \"%1\"");
    BaseKey.Close();
    OpenMethod.Close();
    Shell.Close();

    CurrentUser = Registry.CurrentUser.CreateSubKey(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\" + Extension);
    CurrentUser = CurrentUser.OpenSubKey("UserChoice", RegistryKeyPermissionCheck.ReadWriteSubTree, System.Security.AccessControl.RegistryRights.FullControl);
    CurrentUser.SetValue("Progid", KeyName, RegistryValueKind.String);
    CurrentUser.Close();
}

なぜそれが機能しないのですか?使用例は次のとおりです。

SetAssociation(".ucs", "UCS_Editor_File", Application.ExecutablePath, "UCS File"); 

「CurrentUser」を使用するメソッドの部分は、regedit を使用して同じことを行うと機能するようですが、アプリケーションを使用すると機能しません。

4

9 に答える 9

37

答えは思っていたよりずっと簡単でした。Windows エクスプローラーには、アプリケーションで開くための独自のオーバーライドがあり、コードの最後の行でそれを変更しようとしていました。エクスプローラーのオーバーライドを削除するだけで、ファイルの関連付けが機能します。

SHChangeNotify()また、 P/Invoke を使用してアンマネージ関数を呼び出してファイルの関連付けを変更したことをエクスプローラーに伝えました。

public static void SetAssociation(string Extension, string KeyName, string OpenWith, string FileDescription)
{
    // The stuff that was above here is basically the same

    // Delete the key instead of trying to change it
    var CurrentUser = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\" + Extension, true);
    CurrentUser.DeleteSubKey("UserChoice", false);
    CurrentUser.Close();

    // Tell explorer the file association has been changed
    SHChangeNotify(0x08000000, 0x0000, IntPtr.Zero, IntPtr.Zero);
}

[DllImport("shell32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern void SHChangeNotify(uint wEventId, uint uFlags, IntPtr dwItem1, IntPtr dwItem2);
于 2010-04-23T10:30:46.103 に答える
18

ClickOnce を介して管理された方法でそれを行うことができます。自分でレジストリをいじる必要はありません。これは、プロジェクト プロパティ => 発行 => オプション => ファイルの関連付けの VS2008 以降 (Express を含む) のツール (つまり、xml なし) を介して利用できます。

于 2010-04-21T10:30:42.977 に答える
8

HKEY_CURRENT_USER\Software\Classesの代わりにキーを書き込む場合、HKEY_CLASSES_ROOTVista以降では管理者権限がなくても機能するはずです。

于 2010-04-21T13:02:13.507 に答える
4

古いバージョンのVisualStudioを使用している場合、Vistaはプログラムを「レガシー」Windowsアプリとして扱います。そして、作成したレジストリ書き込みをリダイレクトします。プログラムにマニフェストを含めて、 Vistaに対応しているように見せます。このマニフェストは、VS2008以降に自動的に含まれます。

これでもユーザーの問題は解決しないことに注意してください。ユーザーがUACをオフにしてアプリを実行する可能性はほとんどありません。リンクされたマニフェストを持ち、管理者権限を要求する別のアプリを作成する必要があります。これには、requestedExecutionLevelがrequireAdministratorに設定されたマニフェストが必要です。

于 2010-04-21T12:52:36.227 に答える