【问题标题】:File association in Inno SetupInno 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

标签: inno-setup file-association


【解决方案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 个主要的注册表设置需要处理:

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

    所以在这里说什么。好吧,只有 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 命令添加的一种包装

    1. 在 BeforeInstallAssoc.dat 中保存/恢复之前的设置
    2. 通过 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 之外的一切都很好,改为空白图标
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多