Inno Setup中的文件关联

23

我正在使用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""" 
任何关于为什么该关联不起作用的建议?
4个回答

40
如果您想将一个程序与一个扩展名关联起来,只需在您的iss文件中添加以下指令:
在该部分中。
[Setup]

ChangesAssociations = yes

在安装结束时,设置将告诉资源管理器刷新其文件关联信息,而卸载将在卸载结束时执行相同操作。

并且在该部分中

[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="",这样它就会获取注册表中的默认值。

add extension in registry

Root: HKCR; Subkey: "MyMAGIApplication"; ValueData: "Program MAGI"; ValueType: string; ValueName: ""; Flags: uninsdeletekey。为了在HKCR中添加键MyMAGIApplication,其值为"程序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。使用这个指令,Windows可以在用户单击扩展名为".magi"的文件时启动应用程序MAGI.EXE。

注册表中的结果如下:

Add entry in KHCR\MyMAGIApplication


将描述添加到 shell\open\command 键中,或者通过某些 Shell API 函数(例如 ShellExecute)打开具有该扩展名的文件。此主题还有一个 FAQ 条目。[+1] - TLama
谢谢,复制粘贴Reg选择,水平滚动会在Edge中失去选择。编辑答案和复制/粘贴以及取消操作都会捕获它。 - Laurie Stearn

9

在SO上已经回答了如何创建文件关联的问题。但是核心文档提到了它:

http://www.jrsoftware.org/isfaq.php#assoc

Creating File Associations

First set the [Setup] section directive ChangesAssociations to yes. Then create [Registry] entries as shown below.

[Registry]
Root: HKCR; Subkey: ".myp"; ValueType: string; ValueName: ""; ValueData: "MyProgramFile"; Flags: uninsdeletevalue

.myp is the extension we're associating. MyProgramFile is the internal name for the file type as stored in the registry. Make sure you use a unique name for this so you don't inadvertently overwrite another application's registry key.

Root: HKCR; Subkey: "MyProgramFile"; ValueType: string; ValueName: ""; ValueData: "My Program File"; Flags: uninsdeletekey

My Program File above is the name for the file type as shown in Explorer.

Root: HKCR; Subkey: "MyProgramFile\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\MYPROG.EXE,0"

DefaultIcon is the registry key that specifies the filename containing the icon to associate with the file type. ,0 tells Explorer to use the first icon from MYPROG.EXE. (,1 would mean the second icon.)

Root: HKCR; Subkey: "MyProgramFile\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\MYPROG.EXE"" ""%1"""

shell\open\command is the registry key that specifies the program to execute when a file of the type is double-clicked in Explorer. The surrounding quotes are in the command line so it handles long filenames correctly.


很好,除了默认图标外,已更改为空白图标。 - Alaa Sadik

3

总结一下Windows文件关联的内容,需要处理3个主要的注册表设置:

  1. HKCR MyMAGICApplication
    -> 应用程序路径和图标
  2. HKCR .magi
    -> '将.magiMyMAGICApplication关联(系统默认)
  3. HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.magi\UserChoice
    ->'将.magiMyMAGICApplication关联(用户默认)

关于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: "" ;

那么在这里要说什么呢?第一步已经完成了。第二步(和第三步)取决于任务关联是否启用,并且通过调用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命令。

  1. 在BeforeInstallAssoc.dat中保存/还原以前的设置
  2. 通过REG RESTORE重置/删除3.(Explorer\FileExts) 希望 REG DELETE "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\%1\UserChoice" /f /va 可以工作。只需删除当前用户设置,系统设置将被使用。但实际上却遇到访问被拒绝的问题。愚蠢的 Windows 版本越高就越难缠。所以你必须为自己的权利而战。 REG RESTORE 是一些解决方法,用于克服这个问题。有关详细信息,请参见脚本末尾的:ResetUserFileExt函数。

好了,享受吧 :D


2

这是有效的:

    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""" 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接