Solved

Use Inno Setup to detect and install Windows Installer 4.5

Posted on 2011-09-15
19
3,350 Views
Last Modified: 2013-11-14
I'm installing SQL Server Express 2008 as part of my installation using Inno Setup.  On my Windows XP, SP 3 virtual test machine, the installation fails because Windows Installer 4.5 is not installed.  How do I detect that this version of Windows Installer is missing?  Once the script detects it is missing, how to I get it to install the correct version?
0
Comment
Question by:cerebrumconsulting
  • 7
  • 5
  • 2
  • +1
19 Comments
 
LVL 22

Accepted Solution

by:
Ferruccio Accalai earned 200 total points
ID: 36547782
First of all check the version of MSI.dll to get the version of MS windows Installer
It's usually locate in windows/system32

To do this into innosetup you could create some code into the script.
Take a look at the CodeAutomation.iss example in InnoSetup
0
 
LVL 7

Assisted Solution

by:CSI-Windows
CSI-Windows earned 300 total points
ID: 36548450
Another way to get the version is through the com object (vbs example):

oMSI = createobject("windowsinstaller.installer")
MSIVersion = oMSI.version

Since MSI 4.5 was an interim release - you can download the EXE installer here: http://www.microsoft.com/download/en/details.aspx?id=8483

The challenge is that the MSI 4.5 update installer will most likely require a reboot.

For MSI 2.0 microsoft had a special installer and special procedure to allow you to upgrade MSI, then use the new version without rebooting (though one would be required for the entire machine to start using the new version).

You can test whether the old /delayreboot switch from the MSI 2.0 upgrade will work with the 4.5 installer.  

Here is the documentation on delaying a reboot of an upgrade to the MSI Engine itself: http://msdn.microsoft.com/en-us/library/aa369548(v=VS.85).aspx

You also have to load the msi.dll manually as per the instructions at the bottom of the article.
0
 
LVL 40

Expert Comment

by:Vadim Rapp
ID: 36548687
I think the easiest is if you launch it anyways. If it's already there, it will do nothing. Command line switch /quiet will make it quiet, /norestart will prohibit restart. From all times I was running it, it always wanted restart and never actually needed it, installer 4.5 always worked ok right after the installation.
0
 
LVL 7

Assisted Solution

by:CSI-Windows
CSI-Windows earned 300 total points
ID: 36548939
To follow up on vadimrapp1's comment:
*) Don't forget to request a restart at the end of your package if you did have to upgrade MSI
*) If you are sending this to Large Corporate customers, many will prefer that software packages DO NOT update MSI - but that they do it separately beforehand.  You might want to allow for this by at least documenting that an administrator should upgrade to MSI 4.5 ahead of time if they do not want your package to do it.
0
 

Author Comment

by:cerebrumconsulting
ID: 36553051
These suggestions were well intentioned and helpful to a degree, but none really gave me what I was looking for.  However, I was able to work it out for myself and I post it here in case this may be helpful to someone else in my situation.
function InitializeSetup(): Boolean;
var
  ErrorMsg :String;
  ErrorCode :Integer;
  MS, LS :Cardinal;
  MajorVerNo, MinorVerNo :Word; 
  NetSPVer :DWord;
  InstallMSI :Boolean;
  WindowsVersion: TWindowsVersion;

begin
  Result := True;
  If not IsWin64 then
  begin
    MsgBox('This computer is running a 64-bit version of Windows.  This installation is intended for a 32-bit Windows operating system only.  ' +
           'Please use the 32-bit version for this computer available from www.dgcontrol.com', mbConfirmation, MB_OK);
    Result := False;
  end;

  if Result then
  begin
    GetVersionNumbers(ExpandConstant('{sys}\msi.dll'), MS, LS);
    DecodeVersion(MS, MajorVerNo, MinorVerNo);
    InstallMSI := (MajorVerNo < 4) or ((MajorVerNo = 4) and (MinorVerNo < 5));
    if InstallMSI then
    begin
      Result := False;
      if MsgBox('DGControl requires that Windows Installer version 4.5 or higher be installed.  ' +
                'This installation can be downloaded now from the internet and installed on this computer, ' +
                'or you can do it yourself manually at a later time from a certified Microsoft download site. ' + 
                'Would you like to update Windows Installer now?' + #13#10#13#10 +
                '(After completing this step, you will have to rerun the DGControl setup program.)', mbConfirmation, MB_YESNO) = IDYES then
      begin 
        MsgBox('Once Windows Installer 4.5 has been installed, you will have to restart this computer, then rerun the DGControl Setup program.', mbConfirmation, MB_OK);
        ErrorMsg := 'Unable to install the Microsoft Installer 4.5 for the following reason: ' + #13#10#13#10;
        GetWindowsVersionEx(WindowsVersion);
        // Windows XP 
        if WindowsVersion.NTPlatform and 
          (WindowsVersion.Major = 5) and
          (WindowsVersion.Minor = 1) then
        begin
          if WindowsVersion.ServicePackMajor < 2 then
            MsgBox('Windows XP Service Pack 2 must be installed before the Windows Installer 4.5 can be installed.  ' +
                   'Please install the latest service pack for this computer, then rerun DGControl to again attempt to install Windows Installer 4.5.', mbConfirmation, MB_OK)
          else 
            if not ShellExec('open',	'http://www.dgcsoftware.com/userftp/WindowsXP-KB942288-v3-x86.exe',	'','',SW_SHOWNORMAL,ewNoWait,ErrorCode) then
              MsgBox(ErrorMsg + SysErrorMessage(ErrorCode), mbConfirmation, MB_OK);
        end else // Windows Server 2003
        if WindowsVersion.NTPlatform and 
          (WindowsVersion.Major = 5) and
          (WindowsVersion.Minor = 2) then
        begin
          if not ShellExec('open',	'http://www.dgcsoftware.com/userftp/WindowsServer2003-KB942288-v4-x86.exe',	'','',SW_SHOWNORMAL,ewNoWait,ErrorCode) then
            MsgBox(ErrorMsg + SysErrorMessage(ErrorCode), mbConfirmation, MB_OK);
        end else // Windows Vista 
        if WindowsVersion.NTPlatform and 
          (WindowsVersion.Major = 6) then
        begin
          if not ShellExec('open',	'http://www.dgcsoftware.com/userftp/Windows6.0-KB942288-v2-x86.exe',	'','',SW_SHOWNORMAL,ewNoWait,ErrorCode) then
            MsgBox(ErrorMsg + SysErrorMessage(ErrorCode), mbConfirmation, MB_OK);
        end; 
      end;
    end;
  end;

  if Result then
  begin
    Result := RegKeyExists(HKLM, 'Software\Microsoft\NET Framework Setup\NDP\v2.0.50727');
    if Result then
    begin
      Result := False;
      if RegValueExists(HKLM, 'Software\Microsoft\NET Framework Setup\NDP\v2.0.50727', 'SP') then
      begin
        RegQueryDWordValue(HKLM, 'Software\Microsoft\NET Framework Setup\NDP\v2.0.50727', 'SP', NetSPVer);
        Result := (NetSPVer = 2);
      end;
    end;

    if not Result then
    begin
      if (MsgBox('This installation requires the Windows .NET Framework 2.0 SP 2 to be installed.  ' + 
                 'DGControl can download and install this framework for you, or you can do so yourself at a later time from a Microsoft download site. ' + #13#10#13#10 +
                 'Would like to install the .NET Framework now.' + #13#10#13#10 +
                 '(After the .NET Framework in installed, you will have to rerun the DGControl setup program.)', mbConfirmation, MB_YESNO) = idYes) then
      begin
        if not ShellExec('open',	'http://www.dgcsoftware.com/userftp/NetFx20SP2_x86.exe',	'','',SW_SHOWNORMAL,ewNoWait,ErrorCode) then
        begin
          ErrorMsg := 'Unable to install the Microsoft .NET Framework for the following reason: ' + #13#10#13#10 + SysErrorMessage(ErrorCode);
          MsgBox(ErrorMsg, mbConfirmation, MB_OK);
        end;
      end;
    end;
  end;
end;

Open in new window

0
 

Author Comment

by:cerebrumconsulting
ID: 36553072
I've requested that this question be closed as follows:

Accepted answer: 500 points for CSI-Windows's comment http:/Q_27311365.html#36548450
Assisted answer: 0 points for cerebrumconsulting's comment http:/Q_27311365.html#36553051

for the following reason:

My own comment was the solution
0
 
LVL 40

Expert Comment

by:Vadim Rapp
ID: 36553071
If I correctly understand this code, its part related to Installer 4.5 is in fact implementation of the comment http:#36547782. If this is what worked, then that comment should be accepted.
0
 
LVL 40

Expert Comment

by:Vadim Rapp
ID: 36553073
(forgot to click "object" in the previous comment)
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 40

Expert Comment

by:Vadim Rapp
ID: 36553079
...sorry for multiple comments and maybe unnecessary Objection - I somehow missed author's last comment and looked only at the Reason.

If "my own comment was the solution", and "none really gave me what I was looking for",  then why another comment is accepted? and as I said, the code that appears to have been the solution in fact implements the very first comment from Ferruccio68 (contrary to the above quote).
0
 

Author Comment

by:cerebrumconsulting
ID: 36553984
I appreciate Ferruccio68 efforts, but my question Indicates I already knew what to do.  I wanted to know how to do it.  I knew I had to check the current version of windows installer and then upgrade if necessary to 4.5.  What I was asking for was "how" to do that.  That is why I posted the code sample, so some future individual in my boat, could see how it could be done.

However, I felt that it would be unfair to all that had participated to not aware any points.  You'd all made an effort to help and I wanted to show my appreciation.  I'm still fairly new to this.  In the future, should this situation reoccur, I'll take into consideration the "Accept Mutliple Solutions" feature and distributte the points around more fairly.


0
 
LVL 22

Expert Comment

by:Ferruccio Accalai
ID: 36554099
You asked exactly "How do I detect that this version of Windows Installer is missing?..."

So you really didn't know how to check the version (by reading the MSI.dll version, I mean)

Anyway I've suggested to take a look at the Inno Setup demo script CodeAutomation.iss that explains better than a long post here how to implement some code into Inno Setup.

Finally, for these reasons, I agree with the vadimrapp1 objection
0
 

Author Comment

by:cerebrumconsulting
ID: 36555308
That is correct.  I really didn't know how to check the version of msi.dll programmatically?  That was why I posted ths question on experts-exchange.com.  I was hoping for some specific code samples to show me how to do it.  I shall try to be even more specific in the future.  

The CodeAutomation.iss didn't prove as helpful to me as you think it should have.  My last post was intended to specifically answer the question of how to detect the current version of Windows Installer and upgrade it if needed to version 4.5.  I posted it in a hurry, and realize that it is missing some code, so this exchange has been advantageous in drawing that to my attention. I'm posting the corrected code here.

Again, it was not my intention to cause offense.  
; If you are using Inno Setup to install SQL Server Express 2008, you will
; need to ensure that its prerequisites are also installed.
; This code example serves to illustrate one way that can be accomplished.

#define MyAppName "My Program"
#define MyAppVersion "1.5"
#define MyAppPublisher "My Company, Inc."
#define MyAppURL "http://www.example.com/"
#define MyAppExeName "MyProg.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={{0B417C92-8359-4905-8CA6-AEB7D5E7FBEC}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\{#MyAppName}
DisableDirPage=yes
DefaultGroupName={#MyAppName}
DisableProgramGroupPage=yes
OutputDir=C:\Tmp
OutputBaseFilename=setup
Compression=lzma
SolidCompression=yes

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

[Files]
Source: "C:\Program Files (x86)\Inno Setup 5\Examples\MyProg.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "C:\Program Files (x86)\Inno Setup 5\Examples\MyProgDatabase_Data.MDF"; DestDir: "{app}\{#CommonFiles}"; Flags: ignoreversion; Permissions: everyone-full users-full
Source: "C:\Program Files (x86)\Inno Setup 5\Examples\MyProgDatabase_Log.LDF"; DestDir: "{app}\{#CommonFiles}"; Flags: ignoreversion; Permissions: everyone-full users-full
Source: "C:\Program Files (x86)\Inno Setup 5\Examples\SQLEXPR32_X86_ENU.exe"; DestDir: "{app}\Temp"; Flags: ignoreversion deleteafterinstall; Permissions: everyone-full users-full
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"

[Run]
; Install SQL Server in unattended mode with progress indicators for user to view to know that the process is running
Filename: "{app}\Temp\SQLEXPR32_X86_ENU.exe"; Parameters: "/qs /ACTION=Install /FEATURES=SQLEngine /INSTANCENAME=MY_SQL_INSTANCE /ERRORREPORTING=1 /INDICATEPROGRESS /IAcceptSQLServerLicenseTerms /SECURITYMODE=SQL /SAPWD=MySQLPassword "; WorkingDir: "{app}\Temp"; StatusMsg: SQL Server 2008 Express Setup
; Attach MyProgDatabase to the new named instance of SQL Server Express
Filename: "sqlcmd"; Parameters: "-S {computername}\MY_SQL_INSTANCE -d master -U sa -P MySQLPassword -Q ""exec sp_attach_db @dbname = N'MyProgDatabase', @filename1 = N'{app}\{#CommonFiles}\MyProgDatabase_Data.mdf', @filename2 = N'{app}\{#CommonFiles}\MyProgDatabase_Log.ldf'"" "

[Code]
procedure DecodeVersion(const Version: cardinal; var MajorVerNo, MinorVerNo :word);
begin
  MajorVerNo := word(Version shr 16);
  MinorVerNo := word(Version and not $ffff0000);
end;

// Check for SQL Server Express prerequisites and stop installation if they are not present, while prompting user to install them. 
function InitializeSetup(): Boolean;
var
  ErrorMsg :String;
  ErrorCode :Integer;
  MS, LS :Cardinal;
  MajorVerNo, MinorVerNo :Word; 
  NetSPVer :DWord;
  InstallMSI :Boolean;
  WindowsVersion: TWindowsVersion;

begin
  Result := True;
  If IsWin64 then
  begin
    MsgBox('This computer is running a 64-bit version of Windows.  This installation is intended for a 32-bit Windows operating system only.  ' +
           'Please use the 32-bit version for this computer available from www.dgcontrol.com', mbConfirmation, MB_OK);
    Result := False;
  end;

  if Result then
  begin
    // SQLExpress 2008 requires Windows Installer 4.5.  Check the current version.
    GetVersionNumbers(ExpandConstant('{sys}\msi.dll'), MS, LS);
    DecodeVersion(MS, MajorVerNo, MinorVerNo);
    InstallMSI := (MajorVerNo < 4) or ((MajorVerNo = 4) and (MinorVerNo < 5));
    if InstallMSI then
    begin
      Result := False;
      if MsgBox('This setup program requires that Windows Installer version 4.5 or higher be installed.  ' + #13#10#13#10 +
                'Would you like to update Windows Installer now?', mbConfirmation, MB_YESNO) = IDYES then
      begin 
        MsgBox('Once Windows Installer 4.5 has been installed, you will have to restart this computer, then rerun the DGControl Setup program.', mbConfirmation, MB_OK);
        ErrorMsg := 'Unable to install the Microsoft Installer 4.5 for the following reason: ' + #13#10#13#10;
        GetWindowsVersionEx(WindowsVersion);
        // Windows XP 
        if WindowsVersion.NTPlatform and 
          (WindowsVersion.Major = 5) and
          (WindowsVersion.Minor = 1) then
        begin
          if WindowsVersion.ServicePackMajor < 2 then
            MsgBox('Windows XP Service Pack 2 must be installed before the Windows Installer 4.5 can be installed.  ' +
                   'Please install the latest service pack for this computer, then rerun this setup program to again attempt to install Windows Installer 4.5.', mbConfirmation, MB_OK)
          else 
            if not ShellExec('open',	'http://www.example.com/WindowsXP-KB942288-v3-x86.exe',	'','',SW_SHOWNORMAL,ewNoWait,ErrorCode) then
              MsgBox(ErrorMsg + SysErrorMessage(ErrorCode), mbConfirmation, MB_OK);
        end else // Windows Server 2003
        if WindowsVersion.NTPlatform and 
          (WindowsVersion.Major = 5) and
          (WindowsVersion.Minor = 2) then
        begin
          if not ShellExec('open',	'http://www.example.com/WindowsServer2003-KB942288-v4-x86.exe',	'','',SW_SHOWNORMAL,ewNoWait,ErrorCode) then
            MsgBox(ErrorMsg + SysErrorMessage(ErrorCode), mbConfirmation, MB_OK);
        end else // Windows Vista 
        if WindowsVersion.NTPlatform and 
          (WindowsVersion.Major = 6) then
        begin
          if not ShellExec('open',	'http://www.example.com/Windows6.0-KB942288-v2-x86.exe',	'','',SW_SHOWNORMAL,ewNoWait,ErrorCode) then
            MsgBox(ErrorMsg + SysErrorMessage(ErrorCode), mbConfirmation, MB_OK);
        end; 
      end;
    end;
  end;

  if Result then
  begin
    Result := RegKeyExists(HKLM, 'Software\Microsoft\NET Framework Setup\NDP\v2.0.50727');
    if Result then
    begin
      Result := False;
      if RegValueExists(HKLM, 'Software\Microsoft\NET Framework Setup\NDP\v2.0.50727', 'SP') then
      begin
        RegQueryDWordValue(HKLM, 'Software\Microsoft\NET Framework Setup\NDP\v2.0.50727', 'SP', NetSPVer);
        Result := (NetSPVer = 2);
      end;
    end;

    if not Result then
    begin
      if (MsgBox('This setup program requires the Windows .NET Framework 2.0 SP 2 to be installed.  ' + 
                 'Would like to install the .NET Framework now.' + #13#10#13#10 +
                 '(After the .NET Framework in installed, you will have to rerun the DGControl setup program.)', mbConfirmation, MB_YESNO) = idYes) then
      begin
        if not ShellExec('open',	'http://www.example.com/NetFx20SP2_x86.exe',	'','',SW_SHOWNORMAL,ewNoWait,ErrorCode) then
        begin
          ErrorMsg := 'Unable to install the Microsoft .NET Framework for the following reason: ' + #13#10#13#10 + SysErrorMessage(ErrorCode);
          MsgBox(ErrorMsg, mbConfirmation, MB_OK);
        end;
      end;
    end;
  end;
end;

Open in new window

0
 

Author Comment

by:cerebrumconsulting
ID: 36578297
I thought I had already closed it.
0
 

Author Closing Comment

by:cerebrumconsulting
ID: 36578341
The reason for the Average grade--no offence intended--is simply that I was looking for a solution that showed me how to do what I asked about.  I did learn from the answers what to do, which gave me the starting point to figure out how to do it.
0
 
LVL 40

Expert Comment

by:Vadim Rapp
ID: 36579868
> I did learn from the answers what to do, which gave me the starting point to figure out how to do it.

Which is exactly what you should expect from this website, and qualifies for A. The very name of this website implies that you have the expertise sufficient to implement the how-to advise given by the experts; if something still appears unclear, all you have to do is to ask. Still, http:#36548450 gives a sample of the code how to detect the version of the dll.
0
 

Author Comment

by:cerebrumconsulting
ID: 36592898
I'll leave it up to you.
0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

Suggested Solutions

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now