Inno Setup 中的文件关联
Posted
技术标签:
【中文标题】Inno Setup 中的文件关联【英文标题】:File association in Inno Setup 【发布时间】:2014-12-19 14:09:21 【问题描述】:我正在使用 Inno Setup 并尝试关联位于 Windows 7 中 Program Files (x86)
中的程序。我有以下内容:
#define MyAppName "MyView"
#define MyAppExeName "MyView.exe"
[Setup]
AppName=#MyAppName
[Registry]
Root: HKCR; Subkey: ".mpl"; ValueType: string; ValueName: ""; ValueData: "MyView"; Flags: uninsdeletevalue
Root: HKCR; Subkey: "MyView"; ValueType: string; ValueName: ""; ValueData: "MyView"; Flags: uninsdeletekey
Root: HKCR; Subkey: "MyView\delta.ico"; ValueType: string; ValueName: ""; ValueData: "app\GeoView.EXE,0"
Root: HKCR; Subkey: "MyView\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """app\MYVIEW.EXE"" ""%1"""
关于为什么协会不起作用的任何建议?
【问题讨论】:
此问题的答案中描述的技术已过时。它们不应在现代版本的 Windows 上使用,除非您将应用程序与您的自定义文件类型相关联。这些技术绝不能用于常见类型,因为您的应用程序会与其他应用程序竞争。见Associate my QT application with video/image files in Inno Setup。 【参考方案1】:这行得通:
Root: HKCR; Subkey: ".mpl"; ValueType: string; ValueName: ""; ValueData: "#MyAppName"; Flags: uninsdeletevalue
Root: HKCR; Subkey: ".tvd"; ValueType: string; ValueName: ""; ValueData: "#MyAppName"; Flags: uninsdeletevalue
Root: HKCR; Subkey: ".log"; ValueType: string; ValueName: ""; ValueData: "#MyAppName"; Flags: uninsdeletevalue
Root: HKCR; Subkey: "#MyAppName"; ValueType: string; ValueName: ""; ValueData: "MyView"; Flags: uninsdeletekey
Root: HKCR; Subkey: "#MyAppName\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "app\delta.ico,0"
Root: HKCR; Subkey: "#MyAppName\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """app\#MyAppExeName"" ""%1"""
【讨论】:
【参考方案2】:如果您想将程序与扩展相关联,只需在您的 iss 文件中添加此指令:
在部分
[Setup]
ChangesAssociations = yes
^-Setup 将告诉 Explorer 在安装结束时刷新其文件关联信息,而 Uninstall 将在卸载结束时执行相同的操作。
在部分
[Registry]
Root: HKCR; Subkey: ".mpl"; ValueData: "#MyAppName"; Flags: uninsdeletevalue; ValueType: string; ValueName: ""
Root: HKCR; Subkey: "#MyAppName"; ValueData: "Program #MyAppName"; Flags: uninsdeletekey; ValueType: string; ValueName: ""
Root: HKCR; Subkey: "#MyAppName\DefaultIcon"; ValueData: "app\#MyAppExeName,0"; ValueType: string; ValueName: ""
Root: HKCR; Subkey: "#MyAppName\shell\open\command"; ValueData: """app\#MyAppExeName"" ""%1"""; ValueType: string; ValueName: ""
说明
Root: HKCR; Subkey: ".magi"; ValueData: "MyMAGIApplication"; ValueType: string; ValueName: ""; Flags: uninsdeletevalue
。该指令在注册表中添加“.magi”键,在 HKEY_CLASSES_ROOT (HKCR) 中更准确。在这条指令中,我们还有ValueName=""
,所以它在注册表中获得了默认值。
Root: HKCR; Subkey: "MyMAGIApplication"; ValueData: "Program MAGI"; ValueType: string; ValueName: ""; Flags: uninsdeletekey
为了在 HKCR 中添加键 MyMAGIApplication
,其值为“Program MAGI”。
Root: HKCR; Subkey: "MyMAGIApplication\DefaultIcon"; ValueData: "app\MAGI.EXE,0"; ValueType: string; ValueName: ""
为了关联一个图标包含在可执行文件中。 “0”表示它是可执行 MAGI.EXE 中出现的第一个图标。
Root: HKCR; Subkey: "MyMAGIApplication\shell\open\command"; ValueData: """app\MAGI.EXE"" ""%1"""; ValueType: string; ValueName: ""
为了添加子键 shell\open\command。使用此指令,当用户单击扩展名为“.magi”的文件时,Windows 能够启动应用程序 MAGI.EXE。
结果在注册表中:
【讨论】:
广告到shell\open\command
键描述,或具有此类扩展名的文件被某些 Shell API 函数打开(例如 ShellExecute
)。此主题还有一个FAQ entry
。 [+1]
谢谢,复制粘贴 Reg 选择并操作 horz 滚动在 Edge 中丢失选择。编辑答案和复制/意大利面和取消会阻碍它。【参考方案3】:
总结一下Windows文件关联 有 3 个主要的注册表设置需要处理:
-
HKCR MyMAGICApplication -> 应用程序的路径和图标
HKCR .magi -> '将 .magi 与 MyMAGICApplication 关联(系统默认)
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.magi\UserChoice ->'将 .magi 与 MyMAGICApplication(用户默认)
关于 1. 和 2. 这些在之前的答案中都有很好的介绍。 (除了 .magi 之前可能与 SomeOtherMAGICApplication 相关联。此设置将被覆盖,卸载时不会恢复。) 但是要让它在现实中充分发挥作用 3. 还必须考虑到。
好的,我们从 FileSample.iss 开始:
#define MyAppName "MovToAvi"
#define MyAppNameExt ".mov"
[Setup]
ChangesAssociations=yes
[Languages]
Name: "german"; MessagesFile: "compiler:Languages\German.isl"
[CustomMessages]
german.Assoc=Verknüpfung:
[Tasks]
Name: "desktopicon"; Description: "cm:CreateDesktopIcon"; GroupDescription: "cm:AdditionalIcons"
; Flags: unchecked
Name: fileassoc; Description: "cm:AssocFileExtension,#MyAppName,#MyAppNameExt"; GroupDescription: "cm:Assoc"
[Run]
Filename: "app\install FileAssoc\AssocBak.cmd"; Parameters: "#MyAppNameExt #MyAppName"; StatusMsg: "cm:AssocingFileExtension,#MyAppName,#MyAppNameExt"; Tasks: fileassoc
[UninstallRun]
Filename: "app\install FileAssoc\AssocBak.cmd"; Parameters: "UnAssoc"; RunOnceId: "RemoveAssoc"
[Registry]
;Handled by AssocBak.cmd
;Root: HKCR; Subkey: "#MyAppNameExt"; ValueData: "#MyAppName"; Flags: uninsdeletekeyifempty; ValueType: string; ValueName: "" ; Tasks: fileassoc
;Doesn't work like this - also handled by AssocBak.cmd
;Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\#MyAppNameExt\UserChoice"; ValueData: "#MyAppName"; ValueType: string; ValueName: "Progid" ; Tasks: fileassoc
Root: HKCR; Subkey: "#MyAppName"; ValueData: "Program #MyAppName"; ValueType: string; ValueName: "" ; Flags: uninsdeletekey;
Root: HKCR; Subkey: "#MyAppName\DefaultIcon"; ValueData: "app\Pipe_icon.ico"; ValueType: string; ValueName: "" ;
Root: HKCR; Subkey: "#MyAppName\shell\open\command"; ValueData: """app\#MyAppExeName"" ""%1"""; ValueType: string; ValueName: "" ;
所以在这里说什么。好吧,只有 1. 已经完成了。 2.(和 3.)的完成取决于 Task associate 是否已启用并且其工作是通过调用 AssocBak.cmd 来完成的
请原谅这里使用批处理文件而不是 Inno Pascal 代码/请随意实施。但是,只要它有效,我就会保留它。
@prompt -$G
@set BakFile=BeforeInstallAssoc.dat
@if "%1"=="" @goto :ShowHelp
@pushd %~dp0
@if %1==UnAssoc (
@call :Restore
) else (
@call :DoAndMakeBak %1 %2
)
@popd
@goto :eof
:DoAndMakeBak
@if not exist "%BakFile%" (
@assoc %1 >"%BakFile%"
@assoc %1 %2
@call :ResetUserFileExt %1
) else (
@echo Skipped - Backupfile already exist! Run '%~nx0 u' first or delete '%BakFile%'.
)
@goto :eof
:Restore
:: Attentions putting %BakFile% in quotes gives the Filename and not the File content
@FOR /f "delims== tokens=1,2" %%i IN (%BakFile%) DO @(
set Ext=%%i
set Verb=%%j
)
assoc %Ext%=%Verb%
@call :ResetUserFileExt %Ext%
::@del "%BakFile%"
@goto :eof
:ShowHelp
@echo Assoc with backup
@echo =================
@echo.
@echo Restore:
@echo %~nx0 UnAssoc
@echo.
@echo Set:
@echo %~nx0 ^<AssocExt^> ^<Assochandle^>
@echo Example %~nx0 .mov MovToAvi
@goto :eof
:ResetUserFileExt
::Workaround for
::REG DELETE "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\%1\UserChoice" /f /va
@REG ADD "HKCU\emptyKey" /f >nul
@REG SAVE "HKCU\emptyKey" empty.hiv /y >nul
@REG DELETE "HKCU\emptyKey" /f >nul
@REG RESTORE "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\%1" empty.hiv >nul
@del empty.hiv
@goto :eof
总结该脚本,它只是 assoc 命令添加的一种包装
-
在 BeforeInstallAssoc.dat 中保存/恢复之前的设置
通过 REG RESTORE 重置/删除 3. (Explorer\FileExts)
会好的
REG DELETE "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\%1\UserChoice" /f /va
会工作。只需删除当前用户设置,以便使用系统设置。但只是得到 ACCESS DENIED.。愚蠢的 Windows 版本越高,它就越卑鄙。所以你必须为自己的权利而战。
REG RESTORE 是解决此问题的一些解决方法。有关详细信息,请参阅脚本末尾的 :ResetUserFileExt 函数。
好的,就是这样:D
【讨论】:
【参考方案4】:之前在 SO 上已经回答了创建文件关联。但是核心文档引用了它:
http://www.jrsoftware.org/isfaq.php#assoc
创建文件关联
首先将
[Setup]
部分指令ChangesAssociations
设置为yes
。然后创建[Registry]
条目,如下所示。[Registry] Root: HKCR; Subkey: ".myp"; ValueType: string; ValueName: ""; ValueData: "MyProgramFile"; Flags: uninsdeletevalue
.myp
是我们关联的扩展名。MyProgramFile
是存储在注册表中的文件类型的内部名称。请确保为此使用唯一名称,以免无意中覆盖另一个应用程序的注册表项。Root: HKCR; Subkey: "MyProgramFile"; ValueType: string; ValueName: ""; ValueData: "My Program File"; Flags: uninsdeletekey
My Program File
以上是资源管理器中显示的文件类型的名称。Root: HKCR; Subkey: "MyProgramFile\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "app\MYPROG.EXE,0"
DefaultIcon
是注册表项,它指定包含要与文件类型关联的图标的文件名。,0
告诉 Explorer 使用来自MYPROG.EXE
的第一个图标。 (,1
表示第二个图标。)Root: HKCR; Subkey: "MyProgramFile\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """app\MYPROG.EXE"" ""%1"""
shell\open\command
是注册表项,指定在资源管理器中双击该类型的文件时要执行的程序。周围的引号在命令行中,因此它可以正确处理长文件名。
【讨论】:
太好了,除了 DefaultIcon 之外的一切都很好,改为空白图标以上是关于Inno Setup 中的文件关联的主要内容,如果未能解决你的问题,请参考以下文章
将我的 QT 应用程序与 Inno Setup 中的视频/图像文件相关联
程序打包(安装包制作,Inno setup打包教程,QT程序打包)
程序打包(安装包制作,Inno setup打包教程,QT程序打包)
程序打包(安装包制作,Inno setup打包教程,QT程序打包)
Inno Setup 5 安装包制作!reg2iss,Inno Setup 问题。Inno Setup 怎么批量导入reg文件,(像nsis