首页 > 解决方案 > Windows 7 中的 NSIS 文件关联更改

问题描述

在使用 NSIS 安装应用程序时,我需要(强制)更改特定文件类型(扩展名“.theext”)的文件关联以使用“myapp.exe”打开。

我已经阅读了一些关于如何实现这一点的建议,所以 currentky 这就是我在 NSIS 脚本中的内容:

DeleteRegKey HKCR ".theext" 
DeleteRegKey HKLM ".theext" 
DeleteRegKey HKCU ".theext" 

WriteRegStr HKCR ".theext" "" "theextfile"

WriteRegStr HKCR "theextfile" "" "My App Document"

WriteRegStr HKCR "theextfile\DefaultIcon" "" "$INSTDIR\${EXENAME}.exe,0"

WriteRegStr HKCR "theextfile\shell\open\command" "" '"$INSTDIR\${EXENAME}.exe" "%1"'

WriteRegStr HKCR "theextfile\shell\print\command" "" '"$INSTDIR\${EXENAME}.exe" /p "%1"'

WriteRegStr HKLM "Software\RegisteredApplications" "${EXENAME}" "$INSTDIR\${EXENAME}.exe"

WriteRegStr HKCU "Software\RegisteredApplications" "${EXENAME}" "$INSTDIR\${EXENAME}.exe"



WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.theext\OpenWithList" "a" "$INSTDIR\${EXENAME}.exe"   

为了测试这一点,我使用 WIndows 7 Explorer 将文件 assoc 设置为 GVIM.exe。

由于这样做,每次我运行安装程序时,Windows 7 仍然使用 GVim 双击打开文件,而不是“MyApp.exe”。

但是当我按如下方式检查文件关联时,一切似乎都很好:

ftype | findstr /i theext

给出:

theextfile="C:\Program File (x86)\My App\myapp.exe" "%1"

标签: nsisfile-extensionfile-association

解决方案


你正在做你应该做的一切,如果扩展名尚未被其他人注册,你将成为默认。不过,您实际上不应该首先删除旧密钥(它可能会破坏系统,但它永远不会帮助您成为默认密钥)。强迫某事是邪恶的,用户应该处于控制之中。

因为过去人们强迫这样做,微软开始让更改默认设置变得更加困难。未记录的FileExts密钥将用户选择的默认值存储在UserChoice子密钥中。在较新版本的 Windows(8+?)中,默认值通过一些秘密哈希进行验证,因此您无法覆盖它。

IApplicationAssociationRegistration界面不适用于较新版本的 Windows,但它可能适用于 Windows 7:

!include Win\COM.nsh
!include WinCore.nsh
!insertmacro ComHlpr_CreateInProcInstance ${CLSID_ApplicationAssociationRegistration} ${IID_IApplicationAssociationRegistration} r0 ""
${If} $0 P<> 0
    ${IApplicationAssociationRegistration::SetAppAsDefault} $0 '("MyApp", ".myext", ${AT_FILEEXTENSION})'
    ${IUnknown::Release} $0 ""
${EndIf}

在 Windows 8 中,您所能做的就是启动通用 UI:

!include Win\COM.nsh
!insertmacro ComHlpr_CreateInProcInstance ${CLSID_ApplicationAssociationRegistrationUI} ${IID_IApplicationAssociationRegistrationUI} r0 ""
${If} $0 P<> 0
    ${IApplicationAssociationRegistrationUI::LaunchAdvancedAssociationUI} $0 '("Wordpad")' ; Replace with your name from the RegisteredApplications key
    ${IUnknown::Release} $0 ""
${EndIf}

在 Windows 10 中,即使这已经消失,如果您调用 LaunchAdvancedAssociationUI,它只会显示一个 toast,告诉用户更改他们的设置。

ftype不知道真正的默认值,只有当 Windows 实际在 shell 中运行关联代码时才知道默认值。IApplicationAssociationRegistration::QueryCurrentDefault更好地猜测默认值,但如果默认值实际上是覆盖默认值的 COM shell 扩展,即使它也可能失败。


推荐阅读