当前位置: 首页 > 知识库问答 >
问题:

如何从注册表中获取 Office 的安装目录以进行 Inno 安装程序

萧成文
2023-03-14

我正在为Microsoft Office创建一个安装程序,专门用于2007 - 2013版本。它只是复制了两个Office目录中的一些文件。我的Windows是64位的,但是我想为x64和x86体系结构创建一个安装程序。

因此,我编写了以下代码,试图从Windows注册表中获取Office的安装路径。而且,对于每个版本的Office(2007-2013),它都采用安装路径并附加我所需的其余路径。这是我想要的结果。

[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;

对于其中一个路径,我尝试在Inno Setup中设置文件的安装路径(DestDir ),如下所示:

[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

但是如果我传递参数的样式或bibform,函数officeInstallDir应该可以帮助我为每一行设置正确的路径。但是RegKeyExist或RegQueryStringValue找不到注册表的子项。我甚至尝试使用GetHKLM()函数,因为64位节点有问题,但没有成功。

有人会帮助我吗?

共有2个答案

魏风华
2023-03-14

在你的帮助下,这是我解决问题的最终方案。我注意到我在第64行(DestDir参数)中漏掉了最后一个双引号。

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

谢谢大家,伙计们!

澹台俊达
2023-03-14

当在64位系统上运行32位安装程序时,Inno会自动将< code>HKLM扩展为< code > HKEY _ LOCAL _ MACHINE \ SOFTWARE \ wow 6432 node ,这意味着您不必在此操作,除非安装了64位office,它可能会在64位注册表分支中保存他的注册表信息。但是,如果< code>IsWin64 = true,您可以对< code>HKLM64进行额外的检查。尽管您必须将它作为< code>String而不是< code>Integer来传递,就像您在代码中所做的那样。

我会这样称呼它(但我不太明白您的代码的最后一部分,因此我刚刚粘贴了它):

[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;
 类似资料:
  • 问题内容: 我正在尝试通过Inno Setup(以及另一个应用程序)安装最新的平台(x64或x86)合适的Java Runtime Environment。我找到了一些脚本示例,这些脚本示例说明了如何检测版本并在正确的情况下进行安装并使其适应我的需要,但我一直遇到以下问题: 无法打开文件“ path \ to \ JREInstall.exe”: CreateProcess失败:代码5: 拒绝访问

  • 问题内容: 我将为我的Java应用程序创建一个安装程序。它使用mysql数据库,因此程序的安装必须包括mysql服务器5.5的安装,服务器的配置和数据库的加载。我使用Inno设置来执行此操作,但发现了一些问题。我找到了此代码,但它有点旧了 当我调试时,它会在第一条语句后生成错误。在第二条指令中找不到指定的程序。我尝试使用mysqld代替mysqld-nt,但没有任何变化 有人能帮我吗?? 问题答案

  • 我试图用自定义脚本设置安装程序变量,但随后注意到媒体向导中的“目录名”和“自定义基本目录”字段不接受安装程序变量。 我还尝试在媒体向导中不使用“自定义基本目录”选项,并在“安装位置”屏幕前使用自定义脚本设置变量,但该屏幕似乎根据媒体向导设置计算安装目录。 上下文:我们构建一个产品和一个测试安装程序。prod版本应该建议在中安装。测试安装程序不请求特权,应该建议在用户主页中安装。 定义了一个编译器变

  • 场景是我们编写了一个控制台应用程序,我们希望在Inno设置期间调用该应用程序并读取其输出。与此问题相反,当其他程序仍在运行时,必须从Inno设置读取此输出。输出将包含runnig应用程序的进度信息(double或int值),我们希望用ProgressGauge在Inno中显示这些信息。该应用程序是一个用C#编写的简单可执行程序,可以运行几秒钟到几分钟。 这可能吗?如果可能,是否可以在不冻结Inno

  • 第一步:在“MUI 现代界面定义结束”后面读取注册表中关于安装路径的键值,如果没有,就使用默认路径。 InstallDirRegKey HKCU "Software\eBook Workshop" "" 第二步:在主区段中把安装路径写入注册表。 WriteRegStr HKCU "Software\eBook Workshop" "" $INSTDIR 第三步:在卸载区段删除注册表中安装路径的

  • 根据文档,Inno Setup使用AppName或AppId允许您创建一个更新程序,该程序将自动将其文件放在用户安装初始应用程序的同一路径中。 我需要能够根据AppId确定Inno Setup将文件安装到哪里,但不是从Inno Setup中。例如,我需要能够从Python脚本中确定这一点。 一个用例:修补安装程序位置中的文件。打包整个安装程序只是为了有条件地添加或编辑文本文件中的一行是矫枉过正的。