Domanda

I have been trying to create an installer using Inno Setup for my vb.net application.

This application has a prerequisite dependency on MySQL ODBC. So, I was thinking if I could check the system if MySQL ODBC is present, and install if not. Well, to be frank, I am a newbie programmer, and I know no hell about debian, which is the script language for InnoSetup.

I was looking for help since some time, through google and stuff, but couldn't find anything other than some examples, and tried coding the script myself.

Here's the script:

; 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

Now, the compile goes fine, and generates a setup.exe executable. When run, the app DCS gets installed, but the MySQL ODBC doesn't and gives an error,

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

I thought the output folder needs the mysql-connector-odbc msi installation folder. Just to check, I copied it manually, recompiled and ran setup, only to get the same, but with some change:

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

And also, I wanted the installer to check for the MySQL ODBC driver before any installation proceeds, but here, it does so after the main application install. Can anyone please help me correct this script?

Thanks

È stato utile?

Soluzione

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;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top