web-dev-qa-db-ja.com

レジストリエントリを作成して、ファイル拡張子をC ++のアプリケーションに関連付けます

プログラムに関連付けられているデータファイルをダブルクリックすると、アプリケーションが開かれ、ファイル名がパラメーターとしてアプリケーションに渡されるように、C++アプリケーションにファイル拡張子を登録する最もクリーンな方法を知りたいです。

現在、wixインストーラーを使用してこれを行っていますが、アプリケーションがユーザーのコンピューターにインストールされない場合があるため、アプリケーションを介してレジストリキーを作成するオプションも必要です。

また、これは、アプリケーションが削除された場合、レジストリ内の未使用のエントリが横たわったままになることも意味しますか?

41
Seth

プロセスの基本的な概要は このMSDN記事 にあります。重要な部分はリストの下部にあります。

  • ProgIDを登録します

ProgID(基本的に、ファイルタイプレジストリキー)は、アイコン、説明、ファイルをダブルクリックしたときに使用されるアプリケーションを含むコンテキストメニュー項目など、重要なファイルタイププロパティを含むものです。多くの拡張子には同じファイルタイプがあります。そのマッピングは次のステップで行われます:

  • ファイルタイプのファイル名拡張子を登録します

ここでは、拡張機能のレジストリ値を設定し、その拡張機能のファイルタイプを前の手順で作成したProgIDに設定します。

アプリケーションでファイルを開くために必要な最小限の作業は、2つのレジストリキーを設定/作成することです。この例の.regファイルでは、ファイルタイプ(blergcorp.blergapp.v1)を作成し、ファイル拡張子(.blerg)を関連付けます。

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Classes\blergcorp.blergapp.v1\Shell\open\command]
@="c:\path\to\app.exe \"%1\""
[HKEY_CURRENT_USER\Software\Classes\.blerg]
@="blergcorp.blergapp.v1"

今、あなたはおそらくこれをプログラムで達成したいでしょう。絶対にコーシャになるために、これらのキーの存在を確認し、それに応じてプログラムの動作を変更することができます。特に一般的なコントロールを想定している場合はファイル拡張子。ただし、これらの2つのキーをSetValue関数を使用して設定することにより、目標を達成できます。

私は正確なC++構文には賛成ではありませんが、C#では構文は次のようになります。

Registry.SetValue(@"HKEY_CURRENT_USER\Software\Classes\blergcorp.blergapp.v1\Shell\open\command", null, @"c:\path\to\app.exe \"%1\"");
Registry.SetValue(@"HKEY_CURRENT_USER\Software\Classes\.blerg", null, "blergcorp.blergapp.v1");

もちろん、各サブキーを手動で開き、ProgIDと拡張サブキーを手動で作成し、thenキー値を設定できますが、SetValue関数は、キーまたは値が存在しない場合、自動的に作成されることです。とても便利な。

次に、どのHiveを使用するかについての簡単なWordです。 MSDNのファイルを含むオンラインの多くのファイル関連付けの例では、これらのキーがHKEY_CLASSES_ROOTで設定されています。これはお勧めしません。そのHiveはHKEY_LOCAL_MACHINE\Software\Classes(システムのデフォルト)とHKEY_CURRENT_USER\Software\Classes(ユーザーごとの設定)のマージされた仮想ビューであり、Hiveのサブキーへの書き込みはHKEY_LOCAL_MACHINE\Software\Classesの同じキーにリダイレクトされます。これを行う直接的な問題はありませんが、この問題に遭遇する可能性があります:HKCR(HKLMにリダイレクト)に書き込み、ユーザーがHKCUで異なる値を持つ同じキーを指定した場合、HKCU値が優先されます。したがって、HKEY_CURRENT_USER設定はHKEY_LOCAL_MACHINE設定より優先されるため、書き込みは成功しますが、変更は表示されません。

したがって、アプリケーションを設計するときには、これを考慮に入れる必要があります。さて、ここでの私の例が示すように、逆に、HKEY_CURRENT_USERのみに書き込むことができます。ただし、そのファイルの関連付け設定は現在のユーザーに対してのみ読み込まれ、アプリケーションがすべてのユーザーにインストールされている場合、他のユーザーがWindowsでファイルを開いてもアプリケーションは起動しません。

それはあなたがしたいことのきちんとした入門書になるはずです。さらに読むために私はお勧めします

また、同様の質問に対する同様の回答も参照してください。

76
Factor Mystic

これは2段階のプロセスです。

 1.拡張を処理するプログラムを定義します:(既存のものを使用する場合を除き)
 1.1たとえば、「HKCU \\ Software \\ Classes \\」にキーを作成します
 "Software \\ Classes \\ YourProgramName.file.ext" 
 1.2サブキー "Software \\ Classes \\ YourProgramName.file.ext \\ DefaultIcon" 
 1.2.1 setを作成しますデフォルト値( "")からアプリケーションのフルパスへのリソース
アイコンをリソース
から1.3サブキー「Software \\ Classes \\ YourProgramName.file.ext \\ Shell \\ OperationName \\を作成」 Command "
 OperationName =たとえば、Open、PrintまたはOther 
 1.3.1アプリケーションのフルパスにデフォルト値(" ")を設定+オプションの実行時パラメーター(ファイル名)
 
 2。ファイル拡張子をプログラムに関連付けます。
 2.1キーを作成しますHKCU \\ Software \\ Classes \\。ext-ここに拡張子を入力します
 2.2プログラム定義キーにデフォルト値を設定します
( "YourProgramName.file.ext")
 

以下は、ファイル拡張子を関連付けるc#で記述されたプログラムの一部です。それはc ++ではありませんが、それ自体を説明するのは十分に簡単だと思いますし、c ++のコードと同一でなければ、それはverv simmilarです

1。


    RegistryKey keyPFCTExt0 = Registry.CurrentUser.OpenSubKey("Software\\Classes\\PFCT.file.enc", true);
        if (keyPFCTExt0 == null)
        {
            keyPFCTExt0 = Registry.CurrentUser.CreateSubKey("Software\\Classes\\PFCT.file.enc");
            keyPFCTExt0.CreateSubKey("DefaultIcon");
                RegistryKey keyPFCTExt0ext = Registry.CurrentUser.OpenSubKey("Software\\Classes\\PFCT.file.enc\\DefaultIcon", true);
                    keyPFCTExt0ext.SetValue("", Application.ExecutablePath +",0");
                keyPFCTExt0ext.Close();
            keyPFCTExt0.CreateSubKey("Shell\\PFCT_Decrypt\\Command");
        }
    keyPFCTExt0.SetValue("", "PFCT.file.enc");
    keyPFCTExt0.Close();

2。


    RegistryKey keyPFCTExt1 = Registry.CurrentUser.OpenSubKey("Software\\Classes\\PFCT.file.enc\\Shell\\PFCT_Decrypt\\Command", true);
        if (keyPFCTExt1 == null)
            keyPFCTExt1 = Registry.CurrentUser.CreateSubKey("Software\\Classes\\PFCT.file.enc\\Shell\\PFCT_Decrypt\\Command");
        keyPFCTExt1.SetValue("", Application.ExecutablePath + " !d %1"); //!d %1 are optional params, here !d string and full file path
        keyPFCTExt1.Close(); 
7
beermann

人々がHKEY_CURRENT_USER\Software\Classes\<.ext>のデフォルト値(別の(ソフトウェアで作成された)クラスにリダイレクトする)と言っている理由がわかりません。

動作しますが、それによってオーバーライドされます

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\<.ext>\UserChoice

そして、Microsoftは2番目のプラクティスを推奨していると考えています。これは、組み込みの "open with"が行っていることだからです。この場合、Progid "キーの値はHKEY_CURRENT_USER\Software\Classes\<.ext>のデフォルト値と等しくなります。

6
fireattack

C#を使用して関連付けを操作しようとすると、次のことがわかりました。

  • hkcu\software\Microsoft\windows\currentVersion\Explorer\fileexts.reg\userchoice->ユーザー固有の設定。 openWithProgIdsキーの値は、hkcrのキーを指します。
  • hkcr\xfile\Shell\open\muiVerb値またはhkcr\xfile\Shell\open\command\default値->オープンハンドラーに影響します。これは、プログラムへのパスを含む値です。
  • hkcr\.x->は、コンテキストメニュー(新しいx)に影響しますが、特にメニューに関連するものがあります。

私はC++コードを知りませんが、これらの情報が与えられたら、レジストリAPIを使用してレジストリを操作できる必要があります。

0
Meghdad