File association in Inno Setup

后端 未结 4 1248
挽巷
挽巷 2020-12-04 23:01

I am using Inno Setup and am trying to associate a program that is located in the Program Files (x86) in Windows 7. I have the following:

#defin         


        
相关标签:
4条回答
  • 2020-12-04 23:09

    Well to summarize Windows file association There are 3 major registry settings to deal with:

    1. HKCR MyMAGICApplication
      -> path & icon to app
    2. HKCR .magi
      -> 'associate .magi with MyMAGICApplication (System default)
    3. HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.magi\UserChoice
      ->'associate .magi with MyMAGICApplication (User default)

    Regarding 1. and 2. these were covered well in previous answers. (Except the point that .magi may have been associated to let's say SomeOtherMAGICApplication before. This setting will get overwritten and is not restored on uninstall.) However to make it fully work in real 3. must also taken into account.

    Okay here we got let's start with 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: "" ;
    

    So what to say here. Well only 1. is already done. 2.(and 3.) is done depending if the Task associate was enabled and its work is done by invoking AssocBak.cmd

    Please excuse the use of batch files instead of Inno Pascal code here / feel free to implement. However as long as it is working, I keep it.

    @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
    

    to summaries that script, its just a kind of wrapper for the assoc command adding

    1. save / restore previous setting in BeforeInstallAssoc.dat
    2. Resets / deletes 3. (Explorer\FileExts) via REG RESTORE Would be nice REG DELETE "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\%1\UserChoice" /f /va would work. Just delete the current user setting so the system one will be used. But instead just get ACCESS DENIED.. Stupid Windows the higher the version the more bitchier it gets. So You have to fight for your rights. REG RESTORE is some workaround to overcome this. See the :ResetUserFileExt function at the end of the script for details.

    Okay that's it enjoy :D

    0 讨论(0)
  • 2020-12-04 23:18

    This works:

        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""" 
    
    0 讨论(0)
  • 2020-12-04 23:32

    If you want to associate a program with an extension just add this instruction in your iss file :

    In the section

    [Setup]
    
    ChangesAssociations = yes
    

    ^-Setup will tell Explorer to refresh its file associations information at the end of the installation, and Uninstall will do the same at the end of uninstallation.

    And in the section

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

    Explanations

    Root: HKCR; Subkey: ".magi"; ValueData: "MyMAGIApplication"; ValueType: string; ValueName: ""; Flags: uninsdeletevalue. This instruction add ".magi" key in the registry, with more accurate in HKEY_CLASSES_ROOT (HKCR). In this instruction we also have ValueName="" so it get the default value in the registry.

    add extension in registry

    Root: HKCR; Subkey: "MyMAGIApplication"; ValueData: "Program MAGI"; ValueType: string; ValueName: ""; Flags: uninsdeletekey In order to add the key MyMAGIApplication in HKCR with the value "Program MAGI".

    Root: HKCR; Subkey: "MyMAGIApplication\DefaultIcon"; ValueData: "{app}\MAGI.EXE,0"; ValueType: string; ValueName: "" In order to associate an icon contains in the executable. "0" indicates that it's the first icon present in the executable MAGI.EXE.

    Root: HKCR; Subkey: "MyMAGIApplication\shell\open\command"; ValueData: """{app}\MAGI.EXE"" ""%1"""; ValueType: string; ValueName: "" In order to add the subkey shell\open\command. With this instruction, Windows is able to launch application MAGI.EXE when an user click on a file with extension ".magi".

    And the result in registry :

    Add entry in KHCR\MyMAGIApplication

    0 讨论(0)
  • 2020-12-04 23:32

    Creating file associations has been answered on SO before. But the core documentation refers to it:

    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.

    0 讨论(0)
提交回复
热议问题