Inno Setup中的文件关联

时间:2014-10-23 19:37:35

标签: inno-setup file-extension

我正在使用Inno安装程序,并尝试关联位于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 个答案:

答案 0 :(得分:26)

如果要将程序与扩展名关联,只需在iss文件中添加以下指令:

部分
[Setup]

ChangesAssociations = yes

^ - 安装程序将告诉Explorer在安装结束时刷新其文件关联信息,卸载将在卸载结束时执行相同的操作。

部分
[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,其值为" 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。

结果在注册表中:

Add entry in KHCR\MyMAGIApplication

答案 1 :(得分: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告诉资源管理器使用MYPROG.EXE中的第一个图标。 (,1表示第二个图标。)

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

shell\open\command是注册表项,指定在资源管理器中双击该类型的文件时要执行的程序。周围的引号位于命令行中,因此它可以正确处理长文件名。

答案 2 :(得分:2)

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

  1. HKCR MyMAGICApplication
    - >路径&图标到应用
  2. HKCR .magi
    - > 'strong .magi MyMAGICApplication (系统默认值)
  3. HKCU \ Software \ Microsoft \ Windows \ CurrentVersion \ 资源管理器\ FileExts \ .magi \ UserChoice
    - >'将 .magi 关联MyMAGICApplication (用户默认)
  4. 关于1.和2.这些在以前的答案中得到了很好的阐述。 (除非 .magi 可能与之前的 SomeOtherMAGICApplication 相关联。此设置将被覆盖,并且在卸载时不会恢复。) 然而,要使其在真实中完全发挥作用,也必须考虑到这一点。

    好的,我们开始使用 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关联,并且通过调用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. 中的先前设置
    3. 通过REG RESTORE重置/删除 3。(Explorer \ FileExts) 会好的 REG删除“HKCU \ Software \ Microsoft \ Windows \ CurrentVersion \ Explorer \ FileExts \%1 \ UserChoice”/ f / va 会工作。只需删除当前用户设置,即可使用系统设置。但是只需要拒绝访问。。愚蠢的Windows版本越高,它就越惹人讨厌。所以你必须争取自己的权利。 REG RESTORE 是解决此问题的一些解决方法。有关详细信息,请参阅脚本末尾的:ResetUserFileExt 函数。
    4. 好的,它很享受:D

答案 3 :(得分:0)

这有效:

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