4

我一直在尝试使用 Inno Setup 为我的 vb.net 应用程序创建安装程序。

此应用程序具有对 MySQL ODBC 的先决条件依赖。所以,我在想是否可以检查系统是否存在 MySQL ODBC,如果不存在则安装。好吧,坦率地说,我是一个新手程序员,我对 debian 一无所知,debian 是 InnoSetup 的脚本语言。

一段时间以来,我一直在通过谷歌和其他东西寻求帮助,但除了一些示例之外找不到任何东西,并尝试自己编写脚本。

这是脚本:

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

[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={{ID goes here}
AppName=DCS
AppVersion=1.0
;AppVerName=DCS 1.0
AppPublisher=Syed
DefaultDirName={pf}\DCS
DisableDirPage=yes
DefaultGroupName=DCS
DisableProgramGroupPage=yes
OutputBaseFilename=setup
SetupIconFile=C:\logo.ico
Compression=lzma
SolidCompression=yes

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

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

[Files]
Source: "C:\VS12\Projects\DCS\bin\Debug\DCS.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "C:\VS12\Projects\DCS\bin\Debug\DCS.vshost.exe.config"; DestDir: "{app}"; Flags: ignoreversion
Source: "C:\VS12\Projects\DCS\bin\Debug\DCS.vshost.exe.manifest"; DestDir: "{app}"; Flags: ignoreversion
Source: "C:\VS12\Projects\DCS\bin\Debug\DCS.application"; DestDir: "{app}"; Flags: ignoreversion
Source: "C:\VS12\Projects\DCS\bin\Debug\DCS.exe.config"; DestDir: "{app}"; Flags: ignoreversion
Source: "C:\VS12\Projects\DCS\bin\Debug\DCS.exe.manifest"; DestDir: "{app}"; Flags: ignoreversion
Source: "C:\VS12\Projects\DCS\bin\Debug\DCS.pdb"; DestDir: "{app}"; Flags: ignoreversion
Source: "C:\VS12\Projects\DCS\bin\Debug\DCS.vshost.application"; DestDir: "{app}"; Flags: ignoreversion
Source: "C:\VS12\Projects\DCS\bin\Debug\DCS.vshost.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "C:\VS12\Projects\DCS\bin\Debug\DCS.xml"; DestDir: "{app}"; Flags: ignoreversion
Source: "C:\VS12\Projects\DCS\bin\Debug\mysql-connector-odbc-5.1.12-win32.msi"; DestDir: "{app}"; Flags: ignoreversion
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

[code]
function IsMySQLOdbcInstalled(): boolean;
begin
    If NOT RegKeyExists(HKEY_LOCAL_MACHINE, 'Software\ODBC\ODBCINST.INI\MySQL ODBC 5.1 Driver') then
    Result := True
    Else
    Result := False;
end;

[Icons]
Name: "{group}\DCS"; Filename: "{app}\DCS.exe"
Name: "{commondesktop}\DCS"; Filename: "{app}\DCS.exe"; Tasks: desktopicon

[Run]
Filename: {src}\mysql-connector-odbc-5.1.12-win32.msi; Check: IsMySQLOdbcInstalled()
Filename: "{app}\DCS.exe"; Description: "{cm:LaunchProgram,DCS}"; Flags: nowait postinstall skipifsilent

现在,编译顺利,并生成一个 setup.exe 可执行文件。运行时,应用程序 DCS 被安装,但 MySQL ODBC 没有并给出错误,

Unable to execute file:
'Output path'\mysql-connector-odbc-5.1.12-win32.msi
Create Process failed; code2.
The system cannot find the file specified. 

OK

我认为输出文件夹需要 mysql-connector-odbc msi 安装文件夹。只是为了检查,我手动复制它,重新编译并运行设置,只是为了得到相同的结果,但有一些变化:

Unable to execute file:
'Output path'\mysql-connector-odbc-5.1.12-win32.msi
Create Process failed; code193.
%1 is not a vaild Win32 application. 

OK

而且,我希望安装程序在进行任何安装之前检查 MySQL ODBC 驱动程序,但在这里,它是在主应用程序安装之后进行的。谁能帮我纠正这个脚本?

谢谢

4

1 回答 1

2

The problem lies in your [Run] section. You're going to execute that MySQL ODBC installer from the {src} path. Since you copy your mysql-connector-odbc-5.1.12-win32.msi installer file to the {app} folder, you must run it from the same. Fix your [Run] section of the script this way:

[Run]
; on the following line, run the executable from the {app} directory instead
; of {src}; the {src} folder is the folder in which the Setup files are located
; since it is not an *.exe file, you must also specify the shellexec flag
Filename: {app}\mysql-connector-odbc-5.1.12-win32.msi; Check: IsMySQLOdbcInstalled(); Flags: shellexec
Filename: "{app}\DCS.exe"; Description: "{cm:LaunchProgram,DCS}"; Flags: nowait postinstall skipifsilent

Update:

To meet your additional requirement, run the ODBC driver installer before the main installation process, I've made the following script example (there are kept only parts relevant to the ODBC driver setup).

Anyway, I guess it might be less annoying if you run the ODBC driver installer in some silent mode with some default setting, so it won't offer wizard to the user if there is some (but that's much wider topic for this question; there will be parameters to control the ODBC driver installer, and those you can pass to the second parameter of the Exec function maybe telling the show window flag to be SW_HIDE instead of SW_SHOWNORMAL, which will keep it hidden from user). Please note, this code is untested:

[Setup]
AppName=DCS
AppVersion=1.0
DefaultDirName={pf}\DCS

[Files]
; keep just the only one flag, "dontcopy"; it will tell the installer to not copy
; this file entry to the target machine, but will be part of the setup binary and
; available for manual extracting by using the ExtractTemporaryFile(s) function
Source: "C:\VS12\Projects\DCS\bin\Debug\mysql-connector-odbc-5.1.12-win32.msi"; Flags: dontcopy

[Run]
; remove the ODBC driver installer entry from [Run] section since the [Run] section
; is executed after the installation is succesfully finished and your requirement is
; to run it before the installation process
; Filename: {app}\mysql-connector-odbc-5.1.12-win32.msi; Check: IsMySQLOdbcInstalled()

[Code]
function IsMySQLODBC51Installed: Boolean;
begin
  // the result was inverted in the original code; the original function returned
  // True if the ODBC driver was not installed, False otherwise, and according to
  // the function name it should be vice-versa
  Result := RegKeyExists(HKEY_LOCAL_MACHINE, 'Software\ODBC\ODBCINST.INI\MySQL ODBC 5.1 Driver');
end;

procedure CurStepChanged(CurStep: TSetupStep);
var
  ResultCode: Integer;
begin
  // if we are right before the main installation starts and ODBC driver is not yet
  // installed, then...
  if (CurStep = ssInstall) and not IsMySQLODBC51Installed then
  begin
    // now extract the ODBC installaer to the Inno Setup's temporary folder
    ExtractTemporaryFile('mysql-connector-odbc-5.1.12-win32.msi');
    // and execute the ODBC driver installation (it is necessary to use ShellExec
    // since it is not an *.exe file); if the execution fails, then...
    if not ShellExec('', ExpandConstant('{tmp}\mysql-connector-odbc-5.1.12-win32.msi'), '', '', 
      SW_SHOWNORMAL, ewWaitUntilTerminated, ResultCode) then
    begin
      // show the error message with exit code
      MsgBox('MySQL ODBC Driver setup failed!' + #13#10 + 'Exit code: ' + IntToStr(ResultCode) +
        '; ' + SysErrorMessage(ResultCode), mbError, MB_OK);
      // here you can optionally call Abort to abort the upcoming installation process
      // so if you uncomment the following line, the main installation will not run if
      // the ODBC driver installer execution failed
      // Abort;
    end;
  end;
end;
于 2013-10-07T07:23:15.297 回答