Utwórz wpis rejestru, aby skojarzyć rozszerzenie pliku z aplikacją w C++

Chciałbym poznać najczystszy sposób rejestracji rozszerzenia pliku w mojej aplikacji C++ tak, że gdy plik danych skojarzony z moim programem jest dwukrotnie kliknięty, aplikacja jest otwarta, a nazwa pliku jest przekazywana jako parametr do aplikacji.

Obecnie robię to za pomocą mojego instalatora wix, ale są przypadki, w których aplikacja nie zostanie zainstalowana na komputerze tego użytkownika, więc potrzebuję również opcji tworzenia klucza rejestru przez podanie.

DODATKOWO, czy oznacza to również, że jeśli aplikacja zostanie usunięta, nieużywane wpisy w rejestrze zostaną pozostawione?

Author: Seth, 2009-09-07

3 answers

Twój podstawowy przegląd procesu znajduje się w ten artykuł MSDN. Najważniejsze części znajdują się na dole listy:

  • Zarejestruj się

A ProgID (zasadniczo, klucz rejestru typu pliku) jest tym, co zawiera Twoje ważne właściwości typu pliku, takie jak ikona, opis i elementy menu kontekstowego, w tym aplikacja używana, gdy plik jest dwukrotnie kliknięty. Wiele rozszerzeń może mieć ten sam typ pliku. Że mapowanie odbywa się w następnym krok:

  • Zarejestruj rozszerzenie nazwy pliku dla typu pliku

Tutaj ustawiasz wartość rejestru dla swojego rozszerzenia, ustawiając Typ pliku tego rozszerzenia na ProgID, które utworzyłeś w poprzednim kroku.

Minimalna ilość pracy wymaganej do otwarcia pliku za pomocą aplikacji to ustawienie/utworzenie dwóch kluczy rejestru. W tym przykładzie .reg tworzymy Typ pliku (blergcorp.blergapp.v1) i łączymy z nim rozszerzenie pliku (.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"

Teraz ty prawdopodobnie chce to osiągnąć programowo. Aby być absolutnie koszernym, możesz sprawdzić istnienie tych kluczy i odpowiednio zmienić zachowanie programu, , szczególnie , jeśli przejmujesz kontrolę nad popularnym rozszerzeniem pliku. Jednak cel można osiągnąć poprzez ustawienie tych dwóch klawiszy za pomocą funkcji SetValue.

Nie jestem pewien dokładnej składni C++, ale w C# składnia wygląda mniej więcej Tak:

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");

Oczywiście można ręcznie otwórz każdy klucz podrzędny, ręcznie Utwórz klucz podrzędny i rozszerzenie, a następnie ustaw wartość klucza, ale fajną rzeczą w funkcji SetValue jest to, że jeśli klucze lub wartości nie istnieją, zostaną one automatycznie utworzone. Bardzo poręczne.

Teraz krótkie słowo o tym, który UL użyć. Wiele przykładów asocjacji plików online, w tym te na MSDN, pokazuje te klucze ustawione w HKEY_CLASSES_ROOT. Nie polecam tego robić. Ten Ul jest połączonym, wirtualnym widokiem HKEY_LOCAL_MACHINE\Software\Classes (domyślnie system) i HKEY_CURRENT_USER\Software\Classes (ustawienia dla każdego użytkownika), a zapis do dowolnego podklucza w ulu jest przekierowywany do tego samego klucza w HKEY_LOCAL_MACHINE\Software\Classes. Teraz nie ma bezpośredniego problemu z zrobieniem tego, ale możesz napotkać ten problem: jeśli napiszesz do HKCR (przekierowany do HKLM), a użytkownik poda te same klucze z różnymi wartościami w HKCU, wartości HKCU będą miały pierwszeństwo. W związku z tym Twój zapis się powiedzie, ale nie zobaczysz żadnej zmiany, ponieważ ustawienia HKEY_CURRENT_USER mają pierwszeństwo przed ustawieniami HKEY_LOCAL_MACHINE.

Dlatego ty należy wziąć to pod uwagę przy projektowaniu aplikacji. Z drugiej strony możesz pisać tylko do HKEY_CURRENT_USER, Jak pokazują moje przykłady tutaj. Jednak to ustawienie skojarzenia plików zostanie załadowane tylko dla bieżącego użytkownika, a jeśli aplikacja została zainstalowana dla wszystkich użytkowników, aplikacja nie uruchomi się, gdy ten inny użytkownik otworzy plik w systemie Windows.

To powinien być porządny podkład do tego, co chcesz zrobić. Do dalszej lektury proponuję

I zobacz też moją podobną odpowiedź na podobne pytanie:

 71
Author: Factor Mystic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:56

Jest to proces dwuetapowy:

 1. Define a program that would take care of extension: (unless you want to use existing one)
      1.1 create a key in "HKCU\\Software\\Classes\\" for example 
          "Software\\Classes\\YourProgramName.file.ext"
      1.2 create subkey "Software\\Classes\\YourProgramName.file.ext\\DefaultIcon"
        1.2.1 set default value ("") to your application full path to get
              icon from resources
      1.3 create a subkey "Software\\Classes\\YourProgramName.file.ext\\Shell\\OperationName\\Command"
          OperationName = for example Open, Print or Other
        1.3.1 set default value ("") to your application full path +optional runtime params (filename)

2.Associate file extension with program.
  2.1 create a key HKCU\\Software\\Classes\\.ext   - here goes your extension
  2.2 set default value to the program definition key
    ("YourProgramName.file.ext")

Poniżej znajduje się część programu napisanego w języku c#, który kojarzy rozszerzenie pliku. Nie jest to c++ ale wydaje mi się, że wystarczy się wytłumaczyć i AFAIK jest to verv, jeśli nie identyczny z kodem w c++

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
Author: beermann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-09 21:52:16

Nie wiem, dlaczego ludzie ciągle powtarzają, że HKEY_CURRENT_USER\Software\Classes\<.ext>'S Domyślna wartość (która przekieruje Cię do innej (stworzonej przez oprogramowanie) klasy.

To działa, ale zostanie nadpisane przez

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

A ja uważam, że Microsoft zaleca drugą praktykę-bo to właśnie robi wbudowany "open with". Wartość klucza Progid " jest równa domyślnej wartości HKEY_CURRENT_USER\Software\Classes\<.ext> w tym przypadku.

 6
Author: fireattack,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-10 08:33:25