简体   繁体   中英

How to take the Office's install directory from registry for an Inno Setup installer

I'm creating an installer for Microsoft Office, specifically for 2007 - 2013 versions. It just copy some files inside two Office's directories. My Windows is 64bit but I want to create a installer for both x64 and x86 architectures.

So I wrote the following code that tries to take from the Windows registry the Office's installation path. And, for each version of Office (2007 - 2013), it takes the installation's path and append the rest of the path I need. That's the result I want.

[Code]
function GetHKLM() : Integer;

begin
 if IsWin64 then
  begin
    Result := HKLM64;
  end
  else
  begin
    Result := HKEY_LOCAL_MACHINE;
  end;
end;

function officeInstallDir(Param: string): string;
// This function takes the type of desired directory,
// verify the version of Office and returns the correct
// directory for style or bibform.

var
    styleFolder, bibformFolder : string;

begin
    // It verifies the Office version through the registry's subkey and it sets the correct Office's path.
    if RegKeyExists(GetHKLM(), '\SOFTWARE\Microsoft\Office\15.0') then begin
        styleFolder     := '{userappdata}\Roaming\Microsoft\Bibliography\Style';
        RegQueryStringValue(GetHKLM(), '\SOFTWARE\Microsoft\Office\15.0\Common', 'InstallRoot', bibformFolder);
        bibformFolder   := bibformFolder + '\1046\Bibliography';
    end else begin
        if RegKeyExists(GetHKLM(), '\SOFTWARE\Microsoft\Office\14.0') then begin
          RegQueryStringValue(GetHKLM(), '\SOFTWARE\Microsoft\Office\14.0\Common', 'InstallRoot', styleFolder);
          styleFolder       := styleFolder + 'Bibliography\Style';
          bibformFolder := styleFolder + '1046\Bibliography';
        end else begin
          if RegKeyExists(GetHKLM(), '\SOFTWARE\Microsoft\Office\12.0') then begin
            RegQueryStringValue(GetHKLM(), '\SOFTWARE\Microsoft\Office\12.0\Common', 'InstallRoot', styleFolder);
            styleFolder     := styleFolder + 'Bibliography\Style';
            bibformFolder   := styleFolder + '1046\Bibliography';
          end
        end;
    end;

    // Set the result according Param passed (the first or second type of path).
    if Param = 'style' then begin
        result := styleFolder;
    end else begin
        result := bibformFolder;
    end;

end;

With one of the paths, I tried to set the file's installation path (DestDir) in Inno Setup like this:

[Files]
Source: "E:\Google Drive\Informática\Bibword\Bibword Estilos\*"; DestDir: "{code:officeInstallDir|style}"; Flags: ignoreversion
Source: "E:\Google Drive\Informática\Bibword\Bibword file\BIBFORM.xml"; DestDir: "{code:officeInstallDir|bibform}"; Flags: ignoreversion

But if I pass the parameters style or bibform, the function officeInstallDir should help me set the correct path for each line. But RegKeyExists or RegQueryStringValue doesn't find the registry's subkeys. I even tried using the GetHKLM() function because the 64bit node problem but no go.

Would anyone help me?

When running 32 bit setup on 64 bit system, Inno will automatically expand HKLM as HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node what means you don't have to manipulate here unless there is 64 bit office installed which may hold his Registry info in 64 bit registry branch. But then you can do additional check for HKLM64 if IsWin64 = true . Although you have to pass it as String but not Integer as you do in your code.

I would call it this way (but I don't quite understand the final part of your code thus I have just pasted it):

[Code]
function officeInstallDir(Param: string): string;
var
    styleFolder, bibformFolder : string;

begin
    if RegKeyExists(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Office\15.0\Common\InstallRoot') then 
    begin
        RegQueryStringValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Office\15.0\Common\InstallRoot', 'Path', bibformFolder);
        styleFolder := ExpandConstant('{userappdata}') + '\Roaming\Microsoft\Bibliography\Style';
        bibformFolder := bibformFolder + '\1046\Bibliography';
    end 
    else begin
        if RegKeyExists(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Office\14.0\Common\InstallRoot') then 
        begin
          RegQueryStringValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Office\14.0\Common\InstallRoot', 'Path', styleFolder);
          styleFolder := styleFolder + 'Bibliography\Style';
          bibformFolder := styleFolder + '1046\Bibliography';
        end 
        else begin
          if RegKeyExists(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Office\12.0\Common\InstallRoot') then 
          begin
            RegQueryStringValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Office\12.0\Common\InstallRoot', 'Path', styleFolder);
            styleFolder := styleFolder + 'Bibliography\Style';
            bibformFolder := styleFolder + '1046\Bibliography';
          end;
        end;
    end;


    // I quite don't get this part here:
    if Param = 'style' then 
    begin
        result := styleFolder;
    end 
    else begin
        result := bibformFolder;
    end;

end;

With your help, this is my final solution to the problem. I noted that I missed the final double quote in line 64 (DestDir parameter).

; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!

#define MyAppName "Bibword para Office em português"
#define MyAppVersion "1.0"
#define MyAppPublisher "Yves e Lehnemann"
#define MyAppURL "https://bibword.codeplex.com/"
#define MyAppExeName "BibWordExtender2.exe"

[Setup]
; NOTE: The value of AppId uniquely identifies this application.
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{757B986A-1757-4DEC-9B7B-B2027ADD1147}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName={#MyAppName}
OutputDir=r:\Software
OutputBaseFilename=Bibword para Office em português
SetupIconFile=R:\Software\applications_office.ico
Compression=lzma
SolidCompression=yes

[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
Name: "brazilianportuguese"; MessagesFile: "compiler:Languages\BrazilianPortuguese.isl"
Name: "catalan"; MessagesFile: "compiler:Languages\Catalan.isl"
Name: "corsican"; MessagesFile: "compiler:Languages\Corsican.isl"
Name: "czech"; MessagesFile: "compiler:Languages\Czech.isl"
Name: "danish"; MessagesFile: "compiler:Languages\Danish.isl"
Name: "dutch"; MessagesFile: "compiler:Languages\Dutch.isl"
Name: "finnish"; MessagesFile: "compiler:Languages\Finnish.isl"
Name: "french"; MessagesFile: "compiler:Languages\French.isl"
Name: "german"; MessagesFile: "compiler:Languages\German.isl"
Name: "greek"; MessagesFile: "compiler:Languages\Greek.isl"
Name: "hebrew"; MessagesFile: "compiler:Languages\Hebrew.isl"
Name: "hungarian"; MessagesFile: "compiler:Languages\Hungarian.isl"
Name: "italian"; MessagesFile: "compiler:Languages\Italian.isl"
Name: "japanese"; MessagesFile: "compiler:Languages\Japanese.isl"
Name: "nepali"; MessagesFile: "compiler:Languages\Nepali.islu"
Name: "norwegian"; MessagesFile: "compiler:Languages\Norwegian.isl"
Name: "polish"; MessagesFile: "compiler:Languages\Polish.isl"
Name: "portuguese"; MessagesFile: "compiler:Languages\Portuguese.isl"
Name: "russian"; MessagesFile: "compiler:Languages\Russian.isl"
Name: "scottishgaelic"; MessagesFile: "compiler:Languages\ScottishGaelic.isl"
Name: "serbiancyrillic"; MessagesFile: "compiler:Languages\SerbianCyrillic.isl"
Name: "serbianlatin"; MessagesFile: "compiler:Languages\SerbianLatin.isl"
Name: "slovenian"; MessagesFile: "compiler:Languages\Slovenian.isl"
Name: "spanish"; MessagesFile: "compiler:Languages\Spanish.isl"
Name: "turkish"; MessagesFile: "compiler:Languages\Turkish.isl"
Name: "ukrainian"; MessagesFile: "compiler:Languages\Ukrainian.isl"

[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked

[Files]
Source: "R:\Software\BibWordExtender2.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "R:\Software\Bibword Estilos\*"; DestDir: "{code:officeInstallDir|style}"; Flags: ignoreversion
Source: "R:\Software\Bibword file\BIBFORM.xml"; DestDir: "{code:officeInstallDir|bibform}"; Flags: ignoreversion
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon

[Code]
// This function verifies the system's architecture (x32 ou x64).
// It returns the registry's root key according to the system architecture.
function GetHKLM() : Integer;

begin
 if IsWin64 then
  begin
    Result := HKLM64;
  end
  else
  begin
    Result := HKEY_LOCAL_MACHINE;
  end;
end;


// This function takes the type of desired directory (the directory for installation of styles or
// the general form of Bibliographic Sources), verify the version of Office with
// the installation directory (RegQueryStringValue() function that saves the directory
// bibformFolder or styleFolder and returns 1 if there is a key, which is the second parameter)
// and returns the correct directory for styles or bibform file.
// It has a parameter that need the Param name (see help for {code: |}) and be
// of type string.
function officeInstallDir(Param: string): string;


var
    // rootKey receives the result of GetHKLM() function, that is, the root key according to
    // the system architecture.
    // styleFolder, bibformFolder keep the addresses (folder's path) for the installation
    // of styles and form of Bibliographic Sources (bibform.xml).
    rootKey : Integer;
    styleFolder, bibformFolder : String;

begin
    // rootKey receives the value of function below according to
    // the system architecture.
    rootKey := GetHKLM();

    // Checks the version of Office (looking for the existence of the value of 'Path' in
    // Windows registry) and configures the necessary directories.

    // I had problems with this function because it did not recognize the subkey
    // '\SOFTWARE\Microsoft\Office\15.0\Common\InstallRoot', since the correct form is written below.

    // It did not work the use of function RegKeyExists(ROOTKEY, "SOFTWARE\Microsoft\Office\15.0'), for example,
    // because other Offices could already have been installed before, which kept the subkey in the system.

    // I had to use the ExpandConstant() function because the address does not translate the constant {userappdata}
    // (and it already comes with the Roaming directory).

    // And in the last two ifs, I had to change the order of the position of the styleFolder's and bibformFolder's variables
    // because I need the pure installation directory to generate the bibformFolder's directory, and only after
    // I can upgrade it to generate the styleFolder's.
    if RegQueryStringValue(rootKey, 'SOFTWARE\Microsoft\Office\15.0\Common\InstallRoot', 'Path', bibformFolder) then begin
        styleFolder     := ExpandConstant('{userappdata}\Microsoft\Bibliography\Style');
        bibformFolder   := bibformFolder + '1046\Bibliography';
    end else begin
        if RegQueryStringValue(rootKey, 'SOFTWARE\Microsoft\Office\14.0\Common\InstallRoot', 'Path', styleFolder) then begin
          bibformFolder := styleFolder + '1046\Bibliography';
          styleFolder       := styleFolder + 'Bibliography\Style';         
        end else begin
          if RegQueryStringValue(rootKey, 'SOFTWARE\Microsoft\Office\12.0\Common\InstallRoot', 'Path', styleFolder) then begin
            bibformFolder   := styleFolder + '1046\Bibliography';
            styleFolder     := styleFolder + 'Bibliography\Style';

          end
        end;
    end;

    // Adjusts the result according to the type of desired directory.
    if Param = 'style' then begin
        result := styleFolder;
    end else begin
        result := bibformFolder;
    end;

end;

Thanks for all, folks!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM