Inno安装Microsoft Word模板子目录安装

时间:2012-11-23 20:21:12

标签: ms-word ms-office inno-setup

我是小企业管理局的程序员。 SBA为借款人和贷方创建并免费提供一些程序。下面的安装代码适用于最终用户机器的免费程序。

我搜索了一周的时间来解决我的问题然后决定我需要学习如何编程我需要的东西。我是Pascal和Inno Setup的新手。我窃取了代码并测试了本网站和其他网站中的所有示例。谢谢你的帮助。我一遍又一遍地修改和测试。以下是我的代码。

注意:我提供这个是希望它对其他人有用,但它并没有按计划完成。希望在其他人的帮助下发布一个工作版本。我提供了整个代码,以帮助其他人了解我努力学习的内容。 ; - )

问题 :安装完美无效,除了重复[代码]部分。它至少在 之前运行GetInstallDirectory 到达[Files]部分中的{code:GetInstallDirectory}调用。

它通过Word 14的If语句运行一次,然后运行一次[Files]部分。我的消息“MsgBox('1。Setup ...”出现两次。之前它出现了3到4次,但我做了一个我不记得的改变,现在只运行了两次。

任何人都可以帮我找到问题吗?也许是If,Then,Else语句。然后它可能是声明的顺序。提前谢谢。

; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
; Script written by Daniel H. Smith, Lead Programmer/Analyst, Base Technologies
;                   Washington, DC

#define MyAppName "IDAP mini-Wizard"
#define MyAppVersion "v 2013"
#define MyAppPublisher "Small Business Administration"
#define MyAppURL "http://www.sba.gov/"
#define MyAppExeName "IDAPv2013.exe"
#define MyAppCopyright "(c) 2013-2014"

[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={{459E8784-C110-4348-A294-229C58CB00D2}
AppName={#MyAppPublisher}'s {#MyAppName} {#MyAppVersion}
AppVersion={#MyAppVersion}
AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
AppCopyright={#MyAppCopyright}
DefaultDirName={app}
CreateAppDir=false
OutputDir=C:\Users\Dan\Documents\IDAP Development\Setup
OutputBaseFilename=IDAPv2013Setup
SetupIconFile=C:\Users\Dan\Documents\My Shapes\_private\folder.ico
Compression=lzma
SolidCompression=true
UsePreviousGroup=false
UsePreviousAppDir=false
InfoBeforeFile=C:\Users\Dan\Documents\IDAP Development\Setup\IDAPInfo.txt
WizardImageFile=compiler:WizModernImage-IS.bmp
WizardSmallImageFile=compiler:WizModernSmallImage-IS.bmp
InfoAfterFile=C:\Users\Dan\Documents\IDAP Development\Setup\IDAPWord.txt
AppContact=Auth-IDAP@sba.gov
PrivilegesRequired=none
RestartIfNeededByRun=False
VersionInfoVersion=1.0
VersionInfoCompany={#MyAppPublisher}
VersionInfoCopyright={#MyAppCopyright}

[Languages]
Name: english; MessagesFile: compiler:Default.isl

[Files]
Source: "C:\Users\Dan\Documents\IDAP Development\IDAP 2013 Boilerplate_V10.Clean.pdf"; DestDir: "{userdocs}\IDAP Documents"; Flags: ignoreversion
Source: "C:\Users\Dan\Documents\IDAP Development\IDAP Borrower Certification (9-25-12)(initials) final.docx"; DestDir: "{userdocs}\IDAP Documents"; Flags: ignoreversion
Source: "C:\Users\Dan\Documents\IDAP Development\IDAP Loan Note (Draft July 25).docx"; DestDir: "{userdocs}\IDAP Documents"; Flags: ignoreversion
Source: "C:\Users\Dan\AppData\Roaming\Microsoft\Templates\IDAPLoan2013.dotm"; DestDir: "{code:GetInstallDirectory}"; DestName: "IDAPWizard2013v111.dotm"; Flags: confirmoverwrite

[Messages]
// define wizard title and tray status msg
// both are normally defined in innosetup's default.isl (install folder)
SetupAppTitle = Install {#MyAppName} {#MyAppVersion}
SetupWindowTitle = Install {#MyAppName} {#MyAppVersion} -- {#MyAppPublisher}

[Run]
//Opens Word if User leaves checkbox checked on Finish
  Filename: "{code:GetWordDirectory}"; Flags: postinstall; Description: "Open Word after Finish"; StatusMsg: "Opening Word ..."

[Code]
function GetWordDirectory(S: string) : String;
Begin
  IF RegKeyExists(HKCU, 'Software\Microsoft\Office\14.0\Common\General') THEN BEGIN
    Result := ExpandConstant('{pf32}\Microsoft Office\Office14\winword.exe');
  end Else begin
    Result := ExpandConstant('{pf32}\Microsoft Office\Office12\winword.exe');
  end;
End;
//--------
function GetInstallDirectory(S: String) : String;
var installDirectory : String;
    Version: TWindowsVersion;
Begin
//Word 14 Start
IF RegKeyExists(HKCU, 'Software\Microsoft\Office\14.0\Common\General') THEN BEGIN
    GetWindowsVersionEx(Version);
    if RegQueryStringValue(HKCU, 'Software\Microsoft\Office\14.0\Common\General', 'UserTemplates', installDirectory) then begin
    //Successfully read the registry value
        If (Version.Major = 6) and (Version.Minor = 1) and (Version.ProductType = VER_NT_WORKSTATION) //Windows 7
          then begin
            MsgBox ('1. Setup is installing to Word User Templates directory for:      '+#10+#13+#10+#13+'---> Word 2010 and Windows 7 <---', mbInformation, MB_OK);
            Result := installDirectory
          end else begin //begin c2
        //FAILED READING USERTEMPLATES DIRECTORY
        //Windows <= 6.0 Not Windows 7 and above
        If (Version.Major = 6) and (Version.Minor = 0) and (Version.ProductType = VER_NT_WORKSTATION)  //Windows Vista or XP
          then begin
            MsgBox ('2. Setup is installing to Word default template directory for:      '+#10+#13+#10+#13+'---> Word 2010 and Windows 7 <---', mbInformation, MB_OK);
            Result := ExpandConstant('C:\Users\{username}\AppData\Roaming\Microsoft\Templates');
          end else
            MsgBox ('3. Setup is installing to Word default template directory for:      '+#10+#13+#10+#13+'---> Word 2010 and Windows Vista/XP <---', mbInformation, MB_OK);
            Result := ExpandConstant('C:\Documents and Settings\{username}\Application Data\Microsoft\Templates');
        end;
    end;
//End Word 14
//Start Word 12
END ELSE IF RegKeyExists(HKCU, 'Software\Microsoft\Office\12.0\Common\General') THEN     BEGIN
    GetWindowsVersionEx(Version);
    if RegQueryStringValue(HKCU, 'Software\Microsoft\Office\12.0\Common\General', 'UserTemplates', installDirectory) then begin  
//    Successfully read the value
      If (Version.Major = 6) and (Version.Minor = 0) and (Version.ProductType = VER_NT_WORKSTATION)  //Windows 7
      then begin //c3
        MsgBox ('4. Setup is installing to Word User Templates directory for:      '+#10+#13+#10+#13+'---> Word 2007 and Windows 7 <---', mbInformation, MB_OK);
        Result := installDirectory
      end else begin //begin c4
      //FAILED READING VALUE
      If (Version.Major = 6) and (Version.Minor = 0) and (Version.ProductType = VER_NT_WORKSTATION)  //Windows Vista/XP
      then begin
        MsgBox ('5. Setup is installing to Word User Templates directory for:      '+#10+#13+#10+#13+'---> Word 2007 and Windows 7 <---', mbInformation, MB_OK);
        Result := ExpandConstant('C:\Users\{username}\AppData\Roaming\Microsoft\Templates');
      end else
        MsgBox ('6. Setup is installing to Word default templates directory for:      '+#10+#13+#10+#13+'---> Word 2007 and Windows XP or Vista <---', mbInformation, MB_OK);
        Result := ExpandConstant('C:\Documents and Settings\{username}\Application Data\Microsoft\Templates');
      end;
    end;
END;
//End Word 12
end;  //Function GetInstallDirectory end
//End All
//------------------------------------------------------------------------------
//Following are reference notes
//How to code a if-elseif-else
//  if condition then begin
    // ...
//  end else if condition then begin
    // ...
//  end else begin
    // ...
//  end;
//+------------+------------+-------+-------+---------+
//| Version    | PlatformId | Major | Minor | Release |
//+------------+------------+-------+-------+---------+
//| Win32s     |      0     |   ?   |   ?   |         |
//| Win95      |      1     |   4   |   0   | 1995 08 |
//| Win98      |      1     |   4   |  10   | 1998 06 |
//| WinME      |      1     |   4   |  90   | 2000 09 |
//| WinNT351   |      2     |   3   |  51   | 1995 04 |
//| WinNT4     |      2     |   4   |   0   | 1996 07 |
//| Win2000    |      2     |   5   |   0   | 2000 02 |
//| WinXP      |      2     |   5   |   1   | 2001 10 |
//| Win2003    |      2     |   5   |   2   | 2003 04 |
//| WinXPx64   |      2     |   5   |   2   | 2003 03 |
//| WinCE      |      3     |   ?   |   ?   |         |
//| Vista      |      2     |   6   |   0   | 2007 01 |
//| Win2008    |      2     |   6   |   0   | 2008 02 |
//| Win2008R2  |      2     |   6   |   1   | 2009 10 |
//| Win7       |      2     |   6   |   1   | 2009 10 |
//+------------+------------+-------+-------+---------+
//Word Templates default subdirectory before Windows 7
//C:\Documents and Settings\"user name"\Application Data\Microsoft\Templates\  
//Word Templates default subdirectory after Windows 7
//C:\Users\"username"\AppData\Roaming\Microsoft\Templates\
//
//For MS Word WinWord.Exe location and registry entry
//HKEY_CURRENT_USER\Software\Microsoft\Office\14.0\Word\Options
//C:\Program Files (x86)\Microsoft Office\Office14\ -- For Word 14
//MS Word 14 UserTemplates registry
//HKCU, 'Software\Microsoft\Office\14.0\Common\General', 'UserTemplates'
//MS Word 12 UserTemplates registry
//HKCU, 'Software\Microsoft\Office\12.0\Common\General', 'UserTemplates'
//------------------------------------------------------------------------------

1 个答案:

答案 0 :(得分:0)

<强> 更新

你是对的,从DestDir参数调用的代码函数被调用两次。第一次安装时,第二次处理文件。我不知道原因(源代码中的内容很深),但实际上并不需要关心它。该参数函数曾用于获取目标目录,而不是用于任何类型的用户交互,因此您无需担心它被调用两次。

虽然我已对您的代码进行了审核。请注意,它是从下面列出的资源编写的未经测试。需要指出的一点:

  • 使用常量,更容易维护一个常量而不是脚本中的许多位置
  • 不要依赖于所有用户都将Office安装在默认的Program Files目录中
  • 默认模板目录位于用户的应用程序数据中,在InnoSetup中,您可以使用{userappdata}常量替换,在您的情况下可以安全使用,因为您使用PrivilegesRequired=none运行设置,因此强制管理员用户差异没有风险
  • 如果您的用户必须至少安装了一个Word版本,请在显示向导表单之前检查,请参阅下面的InitializeSetup事件功能

...

[Run]
; the Check parameter here use only when you remove the InitializeSetup event
; function (see below), otherwise it's useless because the setup won't even start 
; when there's not at least Word 2007 or 2010 version installed
Filename: "{code:GetLatestWordAppPath}"; Flags: postinstall; Description: "Open Word after Finish"; StatusMsg: "Opening Word ..."; Check: IsWordInstalled('12.0') or IsWordInstalled('14.0');

[Code]
// better for maintenance is to use constants
const  
  PathDefaultUserTemplates = '{userappdata}\Microsoft\Templates';
  RegKeyOfficeTemplatesPath = 'SOFTWARE\Microsoft\Office\%s\Common\General';
  RegKeyWordInstallRootPath = 'SOFTWARE\Microsoft\Office\%s\Word\InstallRoot';

// helper function for checking if the Word version specified by the input parameter
// is installed or not; inspired by https://stackoverflow.com/a/3267832/960757
function IsWordInstalled(const Version: string): Boolean;
begin
  Result := RegValueExists(HKEY_LOCAL_MACHINE, 
    Format(RegKeyWordInstallRootPath, [Version]), 'Path');
end;

// this is used for the application path for the check box from the [Run] section
// you shouldn't rely on that everyone installs Office to Program Files directory
function GetLatestWordAppPath(S: string): string;
begin
  Result := '';
  if not RegQueryStringValue(HKEY_LOCAL_MACHINE, 
    Format(RegKeyWordInstallRootPath, ['14.0']), 'Path', Result) 
  then
    RegQueryStringValue(HKEY_LOCAL_MACHINE, 
      Format(RegKeyWordInstallRootPath, ['12.0']), 'Path', Result);
end;

// helper function for getting the Office user templates path (if available)
function GetUserTemplatesPath(const Version: string; var Path: string): Boolean;
begin
  Result := RegQueryStringValue(HKEY_CURRENT_USER, 
    Format(RegKeyOfficeTemplatesPath, [Version]), 'UserTemplates', Path);
end;

// function returning target installation directory
function GetInstallDirectory(S: string): string;
var 
  InstallDirectory: string;
begin
  // initialize the Result first
  Result := '';
  // check if Word 2010 application is installed and if so, then...
  if IsWordInstalled('14.0') then
  begin
    // try to get the Office 2010 user templates location from registry, if succeed then...
    if GetUserTemplatesPath('14.0', InstallDirectory) then 
    begin
      Result := InstallDirectory;
      MsgBox('Office 2010 user templates directory was found in registry!' + #10#13 + #10#13 +
        Result, mbInformation, MB_OK);
    end
    else
    // the Office 2010 user templates location was not found in registry, so...
    begin
      // you're running your setup with PrivilegesRequired=none, so you can safely use {userappdata}
      // constant with no risk of getting different user path (forced administrator)
      Result := ExpandConstant(PathDefaultUserTemplates);
      MsgBox('Office 2010 user templates directory was not found in registry!' + #10#13 + #10#13 +
        Result, mbInformation, MB_OK);
    end;
  end
  else
  // Word 2010 was not found, check for Word 2007 and if it's found, then...
  if IsWordInstalled('12.0') then
  begin
    // try to get the Office 2007 user templates location from registry, if succeed then...
    if GetUserTemplatesPath('12.0', InstallDirectory) then 
    begin
      Result := InstallDirectory;
      MsgBox('Office 2007 user templates directory was found in registry!' + #10#13 + #10#13 +
        Result, mbInformation, MB_OK);
    end
    else
    // the Office 2007 user templates location was not found in registry, so...
    begin
      // you're running your setup with PrivilegesRequired=none, so you can safely use {userappdata}
      // constant with no risk of getting different user path (forced administrator)
      Result := ExpandConstant(PathDefaultUserTemplates);
      MsgBox('Office 2007 user templates directory was not found in registry!' + #10#13 + #10#13 +
        Result, mbInformation, MB_OK);
    end;
  end;
end;

// this event function is for the first check before the wizard form is shown if you 
// return False to this event function, the setup will exit, what is here conditioned 
// by presence of Word 2007 or Word 2010
function InitializeSetup: Boolean;
begin
  Result := IsWordInstalled('12.0') or IsWordInstalled('14.0');
  if not Result then
    MsgBox('You don''t have installed neither Word 2007 nor Word 2010.' + #10#13 +
      'Setup will now exit.', mbCriticalError, MB_OK);
end;