Подтвердить что ты не робот

Создать запись реестра для связывания расширения файла с приложением в С++

Я хотел бы знать самый чистый способ регистрации расширения файла с моим С++-приложением, так что, когда файл данных, связанный с моей программой, дважды щелкнут, приложение открывается и имя файла передается в качестве параметра для приложения.

В настоящее время я делаю это через мой установщик wix, но есть некоторые случаи, когда приложение не будет установлено на компьютер пользователя, поэтому мне также нужна возможность создания раздела реестра с помощью приложения.

Кроме того, будет ли это также означать, что если приложение будет удалено, неиспользуемые записи в реестре останутся лежащими?

4b9b3361

Ответ 1

Ваш основной обзор процесса находится в этой статье MSDN. Ключевые части находятся внизу списка:

  • Зарегистрировать ProgID

ProgID (по сути, раздел реестра типа файла) - это то, что содержит важные свойства типа файла, такие как значок, описание и элементы контекстного меню, включая приложение, используемое при двойном щелчке файла. Многие расширения могут иметь одинаковый тип файла. Это сопоставление выполняется на следующем шаге:

  • Зарегистрируйте расширение имени файла для типа файла

Здесь вы устанавливаете значение реестра для своего расширения, устанавливая тип файла расширения равным ProgID, который вы создали на предыдущем шаге.

Минимальный объем работы, необходимый для открытия файла в вашем приложении, - это установка/создание двух разделов реестра. В этом примере файла .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"

Теперь вы, вероятно, хотите сделать это программно. Чтобы быть абсолютно кошерным, вы можете проверить наличие этих ключей и соответствующим образом изменить поведение вашей программы, особенно если вы берете под контроль какое-то общее расширение файла. Однако цель может быть достигнута путем установки этих двух клавиш с помощью функции SetValue.

Я не уверен в точном синтаксисе 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 и дополнительный ключ расширения, а затем установить значение ключа, но приятной SetValue функции SetValue является то, что если ключи или значения не существуют, они будут созданы автоматически., Очень кстати.

Теперь короткое слово о том, какой улей использовать. Многие примеры сопоставления файлов в Интернете, в том числе на MSDN, показывают, что эти ключи установлены в HKEY_CLASSES_ROOT. Я не рекомендую делать это. Этот куст представляет собой объединенное виртуальное представление HKEY_LOCAL_MACHINE\Software\Classes (системные значения по умолчанию) и HKEY_CURRENT_USER\Software\Classes (индивидуальные настройки пользователя), и записи в любой подраздел в кусте перенаправляются на тот же ключ в HKEY_LOCAL_MACHINE\Software\Classes. Теперь нет прямой проблемы с этим, но вы можете столкнуться с этой проблемой: если вы пишете в HKCR (перенаправленный в HKLM), и пользователь указал те же ключи с разными значениями в HKCU, значения HKCU будут иметь приоритет. Следовательно, ваши записи будут выполнены успешно, но вы не увидите никаких изменений, потому что настройки HKEY_CURRENT_USER имеют приоритет над настройками HKEY_LOCAL_MACHINE.

Поэтому вы должны принять это во внимание при разработке вашего приложения. Теперь, с другой стороны, вы можете писать только в HKEY_CURRENT_USER, как показывают мои примеры. Однако этот параметр сопоставления файлов будет загружен только для текущего пользователя, и если ваше приложение было установлено для всех пользователей, оно не запустится, когда этот другой пользователь откроет файл в Windows.

Это должно быть достойным учебником для того, что вы хотите сделать. Для дальнейшего чтения предлагаю

И посмотрите также мой аналогичный ответ на аналогичный вопрос:

Ответ 2

Это двухэтапный процесс:

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

Ниже приведена часть программы, написанной на С#, которая связывает расширение файла. Это не С++, но я думаю, что это достаточно просто, чтобы объяснить себя и AFAIK, это 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(); 

Ответ 3

Я не знаю, почему люди продолжают говорить, что HKEY_CURRENT_USER\Software\Classes\<.ext> Значение по умолчанию (которое перенаправит вас в другой (созданный софтом) класс.

Он работает, но он будет переопределен

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

И я считаю, что Microsoft рекомендует вторую практику, потому что это то, что делает встроенный "open with". Значение ключа Progid "в этом случае равно значению по умолчанию HKEY_CURRENT_USER\Software\Classes\<.ext>.

Ответ 4

Я нашел следующее при попытке манипулировать ассоциациями с помощью С#:

  • hkcu\software\microsoft\windows\currentVersion\explorer\fileexts.reg\userchoice → для пользовательских настроек. Значения в ключе openWithProgIds указывают на ключи в hkcr.
  • Значение hkcr\xfile\shell\open\muiVerb или hkcr\xfile\shell\open\command\default value → влияет на открытый обработчик. Это значение, которое содержит путь к программе.
  • hkcr\.x → влияет на контекстное меню (новое x) среди прочего, связанного с меню.

Я не знаю код C++, но, учитывая эту информацию, вы должны иметь возможность манипулировать реестром с помощью API реестра.