2009-09-07 9 views
38

Chciałbym poznać najczystszy sposób rejestracji rozszerzenia pliku przy użyciu mojej aplikacji C++, aby po dwukrotnym kliknięciu pliku danych skojarzonego z moim programem aplikacja została otwarta i nazwa pliku jest przekazywana jako parametr do aplikacji.Utwórz wpis rejestru, aby skojarzyć rozszerzenie pliku z aplikacją w C++

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

Co więcej, czy to oznacza, że ​​jeśli aplikacja zostanie usunięta, nieużywane wpisy w rejestrze pozostaną w pobliżu?

Odpowiedz

68

Twój podstawowy przegląd procesu znajduje się w this MSDN article. Główne części są na dole listy:

  • Zarejestruj ProgID

ProgID (zasadniczo, klucz rejestru typ pliku) jest to, co zawiera ważnych właściwości typów plików, takich jak ikony, opis i elementy menu kontekstowego, w tym aplikacji używanej po dwukrotnym kliknięciu pliku. Wiele rozszerzeń może mieć ten sam typ pliku. Że mapowanie odbywa się w następnym etapie:

  • Zarejestruj rozszerzenie nazwy pliku dla typu pliku

Tutaj ustawić wartość rejestru dla rozszerzenia, ustawienie tego rozszerzenia jest typ pliku do ProgID ciebie utworzone w poprzednim kroku.

Minimalna ilość pracy wymaganej do otwarcia pliku przez aplikację polega na ustawieniu/utworzeniu dwóch kluczy rejestru. W tym przykładzie plik .reg utworzę typ pliku (blergcorp.blergapp.v1) i skojarzę 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 prawdopodobnie chcesz to zrobić programowo. Aby być całkowicie koszernym, możesz sprawdzić istnienie tych kluczy i odpowiednio zmienić swoje zachowanie programowe, szczególnie jeśli chodzi o kontrolę nad popularnym rozszerzeniem pliku. Jednak cel można osiągnąć, ustawiając te dwa klucze za pomocą funkcji SetValue.

Nie jestem pewien dokładnej składni C++, ale w C# składnia wygląda 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 otworzyć każdy klawisz sub, ręcznie utworzyć ProgID i przedłużenie podklucz, i następnie ustaw wartość klucza, ale miłą rzeczą w funkcji SetValue jest to, że jeśli klucze lub wartości nie istnieją, zostaną automatycznie utworzone. Bardzo przydatny.

Teraz szybkie słowo o tym, którego ula użyć. Wiele przykładów skojarzeń plików w Internecie, w tym w MSDN, pokazuje, że klucze te są ustawione na HKEY_CLASSES_ROOT. Nie polecam tego robić. Ta gałąź jest połączonym, wirtualnym widokiem HKEY_LOCAL_MACHINE\Software\Classes (ustawienia domyślne systemu) i HKEY_CURRENT_USER\Software\Classes (ustawienia dla każdego użytkownika) i zapisywane w dowolnym podkluczu w ulu są przekierowywane na ten sam klucz w HKEY_LOCAL_MACHINE\Software\Classes. Teraz nie ma bezpośredniego problemu z tym, ale możesz napotkać ten problem: Jeśli napiszesz do HKCR (przekierowanego do HKLM), a użytkownik określił te same klucze o różnych wartościach w HKCU, wartości HKCU będą miały pierwszeństwo. Dlatego twoje zapisy się powiodą, ale nie zobaczysz żadnych zmian, ponieważ ustawienia HKEY_CURRENT_USER mają pierwszeństwo przed ustawieniami HKEY_LOCAL_MACHINE.

Dlatego należy wziąć to pod uwagę przy projektowaniu aplikacji. Teraz, po drugiej stronie, możesz napisać tylko do HKEY_CURRENT_USER, co pokazują moje przykłady tutaj. Jednak ustawienie powiązania 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 powinno być porządnym podkładem do tego, co chcesz zrobić. Dla dalszego czytania Proponuję

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

+3

Aby edytować klucz (domyślny), należy użyć: @ = "c: \\ ścieżka \\ do \\ app.exe \ "% 1 \" " Uwaga: doble" \\ " – Fraga

+0

Uważam, że dodanie tych elementów rejestru w kodzie zastąpi wszystkie istniejące z innych aplikacji. Lubię kopać moje kopie bez zastępowania istniejących. -the pozycje używają dodatkowych kluczy, takich jak "OpenWithList". Czy muszę je ręcznie tworzyć, jeśli istnieje istniejący klucz, czy jest prostsza metoda? A może lepiej zapytam o to w moim własnym pytaniu SO? –

+0

Odpowiadając na moje własne pytanie: wymyśliłem to. Jeśli potrzebujesz odpowiedzi, skieruj mnie do odpowiedniego pytania SO, a ja go wypełnię. –

7

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 jest częścią programu napisany w C#, który kojarzy rozszerzenie pliku. Nie jest to C++, ale myślę, że to jest proste wystarczających wyjaśnić sobie i AFAIK to verv simmilar jeśli nie identyczne do kodu 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(); 
 
5

Nie wiem, dlaczego ludzie ciągle powtarzają tę wartość domyślną (która przekieruje cię do innej (stworzonej przez program) klasy.

To działa, ale zostanie ona zastąpiona przez

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

I wierzę, firma Microsoft zaleca ćwiczenia w drugą, bo to, co wbudowany „otwarte” robi. Wartość klucza Progid jest równa domyślnej wartości HKEY_CURRENT_USER\Software\Classes\<.ext> w tym przypadku:

Powiązane problemy