在 MFC 中注册文件关联在 Windows 7 上不起作用

Posted

技术标签:

【中文标题】在 MFC 中注册文件关联在 Windows 7 上不起作用【英文标题】:Registering file associations in MFC doesn't work on Windows 7 【发布时间】:2011-12-08 22:08:34 【问题描述】:

我遇到的这个问题很容易重现。使用 Visual Studio 2010 创建文件扩展名为 .xyz 的基本 MFC MDI 应用程序。应用程序默认代码通过调用轻松注册文件关联:

 // Enable DDE Execute open
 EnableShellOpen();
 RegisterShellFileTypes(TRUE);

问题是在RegisterShellFileTypes(TRUE)里面,下面的调用失败了:

if (!_AfxSetRegKey(strFileTypeId, strFileTypeName))
   continue;       // just skip it

该文件显然没有被注册并且它没有采用应用程序分配的文件图标。我想要的是当我双击注册的文件类型(在本例中为 .xyz)时,它应该在应用程序中打开,但它没有。可能缺少什么..如何使这项工作?

【问题讨论】:

不知道!我的应用程序假设可以在任何 Windows 7 机器上运行,所以我更喜欢通用解决方案。 注册应用扩展需要管理员权限。如果您以管理员身份运行应用程序,它会工作吗? 我在 PC 上拥有管理员权限,所以我相信应用程序是以管理员身份运行的。 即使您的用户具有管理员权限,您的程序也不会拥有这些权限,除非清单特别要求它们。您可能仍需要单击一个框以允许程序以这些权限运行。 【参考方案1】:

多年来,Microsoft 已经改变了注册扩展的概念。从 Vista 开始,预计将在安装时使用具有管理员权限的安装应用程序注册扩展。将扩展映射到应用程序所需的注册表项现在位于注册表的受保护区域中。你所要求的已经不可能了。

【讨论】:

您可能想要提及 UAC 提升而不是管理员权限。成为管理员是不够的。【参考方案2】:

您需要管理员权限才能完成此操作。通常,您应该让安装程序注册您的文件。但是,如果您在注册文件类型之前显式提升(并重新运行)进程,则可以做到这一点:

// In your InitInstance, do the following:
OSVERSIONINFOEX osvi;
osvi.dwOSVersionInfoSize = sizeof OSVERSIONINFOEX;
GetVersionEx((OSVERSIONINFO*)&osvi);

if (osvi.dwMajorVersion >= 6) // XP or Vista/elevated?

    TCHAR exePath[MAX_PATH];
    GetModuleFileName(NULL, exePath, MAX_PATH);
    ShellExecute(NULL, _T("runas"), exePath, NULL, NULL, SW_SHOWNORMAL);
    return FALSE;

【讨论】:

这会启动我的应用程序的一个新实例,这是不可取的。我想用相同的实例注册文件。【参考方案3】:

正如 Parapura Rajkumar 提到的,如果你把这段代码放在你的 init 实例中:

 // Enable DDE Execute open
 EnableShellOpen();
 RegisterShellFileTypes(TRUE);

应用程序应至少以管理员身份运行一次(右键单击并以管理员身份运行)以在 Windows 注册表中注册文件类型。

【讨论】:

以上是关于在 MFC 中注册文件关联在 Windows 7 上不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Windows 7 中 C++/MFC 对话框的视觉风格?

MFC中的消息处理函数

Windows核心编程——MFC下注册表操作和管理

Windows核心编程——MFC下注册表操作和管理

在 MFC CPropertySheet 中添加 ActiveX 控件的问题(Windows 7 64 位和 Windows 2008 Server)

读写windows注册表