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

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

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

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


person Seth    schedule 07.09.2009    source источник


Ответы (4)


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

Теперь несколько слов о том, какой улей использовать. Многие примеры ассоциации файлов в Интернете, в том числе в 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.

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

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

person Factor Mystic    schedule 15.01.2010
comment
Чтобы отредактировать ключ (по умолчанию), вы должны использовать: @ = c: \\ path \\ to \\ app.exe \% 1 \ Примечание: doble \\ - person Fraga; 12.04.2011
comment
Я обнаружил, что добавление этих элементов реестра в код перезаписывает любые существующие элементы из других приложений. Мне нравится добавлять свои, не заменяя существующие. regedit показывает мне, что в этих записях с множественным выбором используются дополнительные ключи, такие как OpenWithList. Нужно ли мне создавать их вручную, если есть существующий ключ, или есть более простой метод? Или мне лучше задать это в моем собственном SO-вопросе? - person Thomas Tempelmann; 20.11.2012
comment
Отвечая на свой вопрос: я понял это. Если вам нужен ответ, укажите мне подходящий вопрос SO, и я заполню его. - person Thomas Tempelmann; 20.11.2012
comment
@ThomasTempelmann - это нормально задавать и отвечать на свой вопрос по SO, так что продолжайте, опубликуйте его и свяжите здесь для потомков - person Factor Mystic; 20.11.2012
comment
Есть ли способ передать некоторые аргументы приложению (в данном случае - c: \ path \ to \ app.exe)? - person Apparao; 20.01.2016

Я не знаю, почему люди продолжают говорить, что 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>.

person fireattack    schedule 19.08.2014

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

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

Ниже приведена часть программы, написанной на C #, которая связывает расширение файла. Это не С ++, но я думаю, что это достаточно просто, чтобы объяснить себя, и AFAIK это очень похоже, если не идентично коду в С ++

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

person beermann    schedule 09.09.2009

При попытке манипулировать ассоциациями с помощью C # я обнаружил следующее:

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

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

person Meghdad    schedule 30.04.2019