C ++程序需要一个文件关联

我正在发行一个免费软件产品,用一个独特的扩展名来读写文本文件。 我希望双击这样的文件会自动启动应用程序。

Windows 7 Professional上开发时,我通过双击打开文件,方法是右键单击文件 – >打开方式…->select默认程序…->浏览…,然后“总是使用选定的程序来打开这种types的文件。” 好。 它只是做了它需要的。 我准备发布我的程序,并提供给用户相同的说明。

但是,当我移动二进制文件的位置时,我看到“总是使用”现在变成灰色/不敏感,所以虽然我可以浏览到新的二进制文件,但我不能将其设置为默认值。 由于我认为我的用户也会遇到麻烦,所以我想看看是否可以安装或运行程序来处理映射。

我看了Windows安装程序大约5分钟,然后确定它比我需要更多的权力和复杂性(为了我的需要,一个zip文件将是足够的,除了这个文件映射。

所以我看了一下,让我的程序在启动的时候,如果已经不存在的话,就build立映射本身。 (我知道如果我们谈论的是一个普通的文件types,如.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,并确认(并在需要时更改)默认文本是对文件的精确描述(replace一些文本,这些文本可能在我手动关联时默认创build夏季)。 但是,当创buildHKEY_CLASSES_ROOT \ firm.app.1 \ shell \ open \ command时,我的RegCreateKeyEx()包装程序正常工作以更改\ .blahblah的值,现在给出返回代码5,显然是缺less权限。

在进一步的研究看来,权限模型可能会导致所有这样的请求失败。 任何人都可以证实或否认这一点? 如果确认,是否有一个很好的参考我应该研究这个问题?

否则,有什么build议? 我应该咬紧牙关学习Windows Installer吗? 还是有办法获得我自己的软件第一次启动时需要编辑registry的权限?

注意我正在使用Windows 7 Professional上的Visual Studio 2008进行开发,尽pipe仍然是一个业余的Windows程序员,但自80年代以来,我一直在从事Unix / Linux的C ++工作。

好吧,我知道了,我会分享我学到的东西。

1)决定一个ProgID。 根据文档,它应该是vender.app.versionnumber,但注册表显示实际上没有任何供应商遵循该规则。 我虽然。

2)关于这个主题的大多数MSFT文档讨论在HKEY_CLASSES_ROOT下创建条目,但是我在http://msdn.microsoft.com/en-us/library/cc144148(v=vs.85).aspx上找到了重要的信息:

有关文件类型的重要注意事项包括:HKEY_CLASSES_ROOT子树是通过合并HKEY_CURRENT_USER \ Software \ Classes和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行比写更简单配置安装程序。 这是一个alpha版本,我会观看这个主题,以获得更好的未来版本的想法。

注册表更改和所有需要更高权限的操作应在安装阶段完成,而不是在应用程序启动时完成。 您可能想要使用安装软件。 否则,你的软件将会造成严重的安全漏洞。