Я распространяю бесплатный продукт, который читает и пишет текстовые файлы с уникальным расширением. Я надеялся, что двойной щелчок по такому файлу автоматически запустит приложение.
Разрабатывая в Windows 7 Professional, я настроил ассоциацию для открытия моих файлов по двойному щелчку, щелкнув правой кнопкой мыши файл-> Открыть с помощью …-> Выбрать программу по умолчанию …-> Обзор …, а затем Msgstr «Всегда использовать выбранную программу, чтобы открыть этот тип файла.» Хорошо. Он сделал только то, что нужно. Я собирался отправить мою программу с инструкциями для пользователей, чтобы сделать то же самое.
Тем не менее, когда я переместил местоположение двоичного файла, я вижу, что «Всегда использовать» теперь неактивен / нечувствителен, поэтому, хотя я мог просматривать новый двоичный файл, я не мог установить его по умолчанию. Так как я думал, что у моих пользователей тоже будут с этим проблемы, я хотел посмотреть, смогу ли я установить или запустить программу, чтобы позаботиться о сопоставлении.
Я посмотрел на установщик Windows примерно на 5 минут, прежде чем определить, что он гораздо сложнее и сложнее, чем мне нужно (для моих нужд будет достаточно zip-файла, за исключением этого сопоставления файлов).
Поэтому я посмотрел на то, чтобы моя программа, при запуске, настроила само отображение, если его там еще не было. (Я знаю, что это было бы очень плохим поведением, если бы мы говорили о распространенном типе файла, таком как .html или .jpg, но в этом случае у него есть расширение .blahblah, которое наверняка больше никто не использует.)
На основании информации на http://www.cplusplus.com/forum/windows/26987/ а также http://msdn.microsoft.com/en-us/library/cc144148(v=vs.85).aspx Мне удалось при запуске моей программы открыть HKEY_CLASSES_ROOT \ .blahblah и подтвердить (и изменить при необходимости) текст по умолчанию, чтобы он был точным описанием файла (заменив некоторый текст, который мог быть создан по умолчанию, когда я делал ручное объединение прошлым летом). Однако, когда дело дошло до создания команды HKEY_CLASSES_ROOT \ firm.app.1 \ shell \ open \, моя оболочка RegCreateKeyEx (), которая прекрасно работает для изменения значения \ .blahblah, теперь дает код возврата 5, очевидно, отсутствие разрешения.
После дальнейших исследований кажется, что модель разрешений может вызвать сбой всех таких запросов. Кто-нибудь может подтвердить или опровергнуть это? Если подтвердите, есть ли хорошая рекомендация, которую я должен изучить по этому вопросу?
В противном случае, каковы предложения? Стоит ли кусать пулю и изучать установщик Windows? Или есть способ получить разрешения, необходимые для редактирования реестра при первом запуске моего собственного программного обеспечения?
Заметьте, я занимаюсь разработкой Visual Studio 2008 для Windows 7 Professional, и хотя я все еще начинающий программист Windows, я занимался C ++ с 80-х годов на Unix / Linux …
Хорошо, я получил это работает, и я поделюсь тем, что я узнал.
1) Определите ProgID. Это должен быть vender.app.versionnumber в соответствии с документами, но regedit показывает, что практически никто из поставщиков не следует этому правилу. Я сделал, хотя.
2) Большинство документов MSFT по этой теме говорят о создании записей в HKEY_CLASSES_ROOT, но я нашел важную информацию о http://msdn.microsoft.com/en-us/library/cc144148(v=vs.85).aspx:
Важные соображения о типах файлов:
HKEY_CLASSES_ROOT поддерево — это представление, образованное слиянием
HKEY_CURRENT_USER \ Программное обеспечение \ Классы и
HKEY_LOCAL_MACHINE \ Software \ Classes Как правило, HKEY_CLASSES_ROOT — это
предназначен для чтения, но не для записи. Для получения дополнительной информации см.
статья HKEY_CLASSES_ROOT.
3) чтобы ассоциация появилась без перезагрузки, вы должны вызвать SHChangeNotify (). (Это бросило меня, потому что даже когда у меня был правильный код, результаты не отображались правильно в Проводнике.)
Вот код, которым я закончил. Если я перехожу через REGEDIT и удаляю все упоминания .moselle (мое расширение) и MoselleIDE (мое приложение), а затем запускаю мою программу один раз вручную, я получаю поведение «нажми и открывай», значок файла становится таким же, как приложение, и т.д. Обратите внимание, что в коде используется функция ведения журнала, и он также подробно сообщает, какой тип успеха у него есть: 1) переменная уже верна, 2) переменная изменена, 3) переменная не существует.
void RegSet( HKEY hkeyHive, const char* pszVar, const char* pszVa
lue ) {
HKEY hkey;
char szValueCurrent[1000];
DWORD dwType;
DWORD dwSize = sizeof( szValueCurrent );
int iRC = RegGetValue( hkeyHive, pszVar, NULL, RRF_RT_ANY, &dwType, szValueCurrent, &dwSize );
bool bDidntExist = iRC == ERROR_FILE_NOT_FOUND;
if ( iRC != ERROR_SUCCESS && !bDidntExist )
AKS( AKSFatal, "RegGetValue( %s ): %s", pszVar, strerror( iRC ) );
if ( !bDidntExist ) {
if ( dwType != REG_SZ )
AKS( AKSFatal, "RegGetValue( %s ) found type unhandled %d", pszVar, dwType );
if ( strcmp( szValueCurrent, pszValue ) == 0 ) {
AKS( AKSTrace, "RegSet( \"%s\" \"%s\" ): already correct", pszVar, pszValue );
return;
}
}
DWORD dwDisposition;
iRC = RegCreateKeyEx( hkeyHive, pszVar, 0, 0, 0, KEY_ALL_ACCESS, NULL, &hkey, &dwDisposition );
if ( iRC != ERROR_SUCCESS )
AKS( AKSFatal, "RegCreateKeyEx( %s ): %s", pszVar, strerror( iRC ) );
iRC = RegSetValueEx( hkey, "", 0, REG_SZ, (BYTE*) pszValue, strlen( pszValue ) + 1 );
if ( iRC != ERROR_SUCCESS )
AKS( AKSFatal, "RegSetValueEx( %s ): %s", pszVar, strerror( iRC ) );
if ( bDidntExist )
AKS( AKSTrace, "RegSet( %s ): set to \"%s\"", pszVar, pszValue );
else
AKS( AKSTrace, "RegSet( %s ): changed \"%s\" to \"%s\"", pszVar, szValueCurrent, pszValue );
RegCloseKey(hkey);
}int SetUpRegistry() {
//app doesn't have permission for this when run as normal user, but may for Admin? Anyway, not needed.
//RegSet( HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\MoselleIDE.exe", "C:\\Moselle\\bin\\MoselleIDE.exe" );
RegSet( HKEY_CURRENT_USER, "Software\\Classes\\.moselle", "Moselle.MoselleIDE.1" );
// Not needed.
RegSet( HKEY_CURRENT_USER, "Software\\Classes\\.moselle\\Content Type", "text/plain" );
RegSet( HKEY_CURRENT_USER, "Software\\Classes\\.moselle\\PerceivedType", "text" );
//Not needed, but may be be a way to have wordpad show up on the default list.
//RegSet( HKEY_CURRENT_USER, "Software\\Classes\\.moselle\\OpenWithProgIds\\Moselle.MoselleIDE.1", "" );
RegSet( HKEY_CURRENT_USER, "Software\\Classes\\Moselle.MoselleIDE.1", "Moselle IDE" );
RegSet( HKEY_CURRENT_USER, "Software\\Classes\\Moselle.MoselleIDE.1\\Shell\\Open\\Command", "C:\\Moselle\\bin\\MoselleIDE.exe %1" );
SHChangeNotify( SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL );
return 0;
}
Наконец, да, я знаю, что мне нужно найти установщик, но я эксперт C ++, а не специалист по конфигурации и терминологии Windows, и мне гораздо проще написать вышеупомянутые 50 строк, чем даже начать понимать, как настроить установщик. Это для альфа-релиза, и я буду наблюдать за этой темой для лучших идей для будущих выпусков.
Изменения в реестре и все действия, требующие более высоких разрешений, должны выполняться на этапе установки, а не при запуске приложения. Вы, вероятно, хотите использовать монтаж программного обеспечения. В противном случае ваше программное обеспечение приведет к серьезным нарушениям безопасности.