Source: Using InnoSetup with the DotNet Framework (script)
Using Inno Setup with the .NET Framework
This article describes the script used to automatically download and install the Microsoft .NET Framework during the TimeSprite installation. Developers of .NET applications may find this information useful for their own applications.
The script is based heavily on the script Ted Ehrich posted to the Inno Setup newsgroup in this post: http://news.jrsoftware.org/news/innosetup.isx/msg06108.html
The script uses some of the third party add-ons to Innosetup, I think the QuickStart Pack includes what you need.
Requirements
Having the .NET Framework as a dependency makes the installation requirements somewhat complex.
The Script
The script that I ended up with performs the following processing:
I haven’t programmed in Pascal, and this was my first shot at an Inno Setup script, so there are probably plenty of opportunities for tidying things up. A lot of what I did was just copying and modifying stuff. However the end result does seem to handle the .NET installation nicely.
Here is the script: dotnet.iss
Notes:
HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\policy\v1.1
. This key is accessible to regular users.Unrelated but perhaps useful information
I also have a digital photo program, Picnam, which I converted to the same process. Picnam adds entries to the “Open With” menu in Explorer, so that people can easily open images using Picnam but existing file associations are not affected.
These are the registry entries I used:
[Registry] Root: HKCR; Subkey: “.jpg\OpenWithList\MyApp.exe”; Flags: uninsdeletekey noerror Root: HKCR; Subkey: “.jpeg\OpenWithList\MyApp.exe”; Flags: uninsdeletekey noerror Root: HKCR; Subkey: “applications\MyApp.exe\shell\open\command”; ValueType: string; ValueData: “”"{app}\MyApp.exe”" “”%1″”"; Flags: uninsdeletekey noerror Root: HKCU; Subkey: "Software\Classes\.jpg\OpenWithList\MyApp.exe"; Flags: uninsdeletekey Root: HKCU; Subkey: "Software\Classes\.jpeg\OpenWithList\MyApp.exe"; Flags: uninsdeletekey Root: HKCU; Subkey: "Software\Classes\applications\MyApp.exe\shell\open\command"; ValueType: string; ValueData: """{app}\MyApp.exe"" ""%1"""; Flags: uninsdeletekey
The HKCR values install the “Open With” option for all users, but fail if the user is not an administrator. The HKCU values install it for the current user, and work even if the user is not an administrator.
VMWare
I used VMWare Workstation for the first time in testing the setup process, and I have to say it is a huge productivity booster for this type of thing. Using snapshots I was able to run the installation process with minor changes in various configurations over and over again - probably about 20 times in a couple of hours. It was a huge productivity gain, and I join those who say that VMWare or an equivalent product is an essential tool for software development.
Script:
[_ISTool] EnableISX=true [Setup] AppName=MyApp AppVerName=MyApp 1.0.0 MinVersion=4.1,4.0 DefaultDirName={pf}\MyApp DefaultGroupName=MyApp UninstallDisplayIcon={app}\MyApp.exe Compression=lzma SolidCompression=true OutputBaseFilename=MyAppSetup [Files] Source: c:\ISSI\include\isxdl\isxdl.dll; Flags: dontcopy Source: Release\MyApp.exe; DestDir: {app} [Messages] WinVersionTooLowError=MyApp requires Windows NT4, Windows 98 or later. [Icons] Name: {group}\MyApp; Filename: {app}\MyApp.exe Name: {group}\Uninstall MyApp; Filename: {uninstallexe} [Code] var dotnetRedistPath: string; downloadNeeded: boolean; dotNetNeeded: boolean; memoDependenciesNeeded: string; procedure isxdl_AddFile(URL, Filename: PChar); external 'isxdl_AddFile@files:isxdl.dll stdcall'; function isxdl_DownloadFiles(hWnd: Integer): Integer; external 'isxdl_DownloadFiles@files:isxdl.dll stdcall'; function isxdl_SetOption(Option, Value: PChar): Integer; external 'isxdl_SetOption@files:isxdl.dll stdcall'; const dotnetRedistURL = 'http://download.microsoft.com/download/a/a/c/aac39226-8825-44ce-90e3-bf8203e74006/dotnetfx.exe'; // local system for testing... // dotnetRedistURL = 'http://192.168.1.1/dotnetfx.exe'; function InitializeSetup(): Boolean; begin Result := true; dotNetNeeded := false; // Check for required netfx installation if (not RegKeyExists(HKLM, 'Software\Microsoft\.NETFramework\policy\v1.1')) then begin dotNetNeeded := true; if (not IsAdminLoggedOn()) then begin MsgBox('MyApp needs the Microsoft .NET Framework to be installed by an Administrator', mbInformation, MB_OK); Result := false; end else begin memoDependenciesNeeded := memoDependenciesNeeded + ' .NET Framework' #13; dotnetRedistPath := ExpandConstant('{src}\dotnetfx.exe'); if not FileExists(dotnetRedistPath) then begin dotnetRedistPath := ExpandConstant('{tmp}\dotnetfx.exe'); if not FileExists(dotnetRedistPath) then begin isxdl_AddFile(dotnetRedistURL, dotnetRedistPath); downloadNeeded := true; end; end; SetIniString('install', 'dotnetRedist', dotnetRedistPath, ExpandConstant('{tmp}\dep.ini')); end; end; end; function NextButtonClick(CurPage: Integer): Boolean; var hWnd: Integer; ResultCode: Integer; begin Result := true; if CurPage = wpReady then begin hWnd := StrToInt(ExpandConstant('{wizardhwnd}')); // don't try to init isxdl if it's not needed because it will error on < ie 3 if downloadNeeded then begin isxdl_SetOption('label', 'Downloading Microsoft .NET Framework'); isxdl_SetOption('description', 'MyApp needs to install the Microsoft .NET Framework. '+ 'Please wait while Setup is downloading extra files to your computer.'); if isxdl_DownloadFiles(hWnd) = 0 then Result := false; end; if (Result = true) and (dotNetNeeded = true) then begin if Exec(ExpandConstant(dotnetRedistPath), '', '', SW_SHOW, ewWaitUntilTerminated, ResultCode) then begin // handle success if necessary; ResultCode contains the exit code if not (ResultCode = 0) then begin Result := false; end; end else begin // handle failure if necessary; ResultCode contains the error code Result := false; end; end; end; end; function UpdateReadyMemo(Space, NewLine, MemoUserInfoInfo, MemoDirInfo, MemoTypeInfo, MemoComponentsInfo, MemoGroupInfo, MemoTasksInfo: String): String; var s: string; begin if memoDependenciesNeeded <> '' then begin s := s + 'Dependencies to install:' + NewLine + memoDependenciesNeeded + NewLine; end; s := s + MemoDirInfo + NewLine + NewLine; Result := s end;
Source: http://www.vbforums.com/showthread.php?t=620221
[CustomMessages] dotnetmissing=This application requires Microsoft Framework 4.0 which is not yet installed on this computer. Would you like to download it now? . . . [Code] function InitializeSetup(): Boolean; var ErrorCode: Integer; netFrameWorkInstalled : Boolean; isInstalled: Cardinal; begin result := true; // Check for the .Net 4.0 framework isInstalled := 0; netFrameworkInstalled := RegQueryDWordValue(HKLM, 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\client', 'Install', isInstalled); if ((netFrameworkInstalled) and (isInstalled <> 1)) then begin netFrameworkInstalled := false; end; if netFrameworkInstalled = false then begin if (MsgBox(ExpandConstant('{cm:dotnetmissing}'), mbConfirmation, MB_YESNO) = idYes) then begin ShellExec('open', 'http://www.microsoft.com/downloads/details.aspx?familyid=9CFB2D51-5FF4-4491-B0E5-B386F32C0992&displaylang=en', '','',SW_SHOWNORMAL,ewNoWait,ErrorCode); end; result := false; end; end;
Source: http://www.vbforums.com/showthread.php?t=620221
This code checks, downloads and installs it if needed. Verify the file isxdl.dll
(InnoSetup third-party tool) is also deployed.
[CustomMessages] dotnetfx40_title=.NET Framework 4.0 dotnetfx40_size=48.1 MB . . . [Code] const dotnetfx40_url = 'http://download.microsoft.com/download/9/5/A/95A9616B-7A37-4AF6-BC36-D6EA96C8DAAE/dotNetFx40_Full_x86_x64.exe'; procedure dotnetfx40(); var version: cardinal; begin RegQueryDWordValue(HKLM, 'Software\Microsoft\NET Framework Setup\NDP\v4\Full', 'Install', version); if version <> 1 then begin AddProduct('dotNetFx40_Full_x86_x64.exe', '/q /norestart', CustomMessage('dotnetfx40_title'), CustomMessage('dotnetfx40_size'), dotnetfx40_url); end; end;
When an installer, after its installation, asks to restart the computer, you can avoid doing so removing the pertinent pending operations from the following Windows registry value:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations
Issue: A “Blue Screen of Death” shows up when trying to start the installer.
He starts the setup and a a random point it gets killed (not an normal stop)….
We have seen this, too. We work around it by having the customer use msconfig to disable services that are not Microsoft's, plus all Startup programs. Then run the installer, then use msconfig to go back to a Normal startup. Works every time.
When the installation is complete you must restore your computer from a clean boot.
Hello,
We use InnoSetup for a commercial programm.
With a customer we run in to the following problem.
He starts the setup and at a random point it gets killed (not an normal
stop)….
When I use the /LOG option, the log also just stops at a point and no
closing/stop info of inno setup is logged. Also the temporary created
folders are still there. This suggest that (probably some other process -
aka virusscanner) is killing the installer process…
Example:
#include <idp.iss> [Files] Source: "{tmp}\file1.xyz"; DestDir: "{app}"; Flags: external; ExternalSize: 1048576 Source: "{tmp}\file2.xyz"; DestDir: "{app}"; Flags: external; ExternalSize: 1048576 Source: "{tmp}\file3.xyz"; DestDir: "{app}"; Flags: external; ExternalSize: 1048576 [Icons] Name: "{group}\{cm:UninstallProgram,My Program}"; Filename: "{uninstallexe}" [Code] procedure InitializeWizard(); begin idpAddFileSize('http://127.0.0.1/file1.xyz', ExpandConstant('{tmp}\file1.xyz'), 1048576); idpAddFileSize('http://127.0.0.1/file2.xyz', ExpandConstant('{tmp}\file2.xyz'), 1048576); idpAddFileSize('http://127.0.0.1/file3.xyz', ExpandConstant('{tmp}\file3.xyz'), 1048576); idpDownloadAfter(wpReady); end.