Всем доброго времени,
столкнулся с рядом проблем при создании инсталлятора .net-приложения. Задача до невероятности типична (а потому должна иметь множество готовых решений): есть приложение, написанное на .net, необходимо обеспечить его работоспособность на максимуме систем. В том числе на Windows XP, по причине чего пришло использовать минимально возможную версию .net, а именно 3.5. Как я понимаю, ClickOnce сам написан на .net, поэтому пришлось использовать InnoSetup. Проверяю, установлен ли .net, если нет - ставлю. Вроде бы все просто. Но есть проблемы:
1. В Windows XP приходится тащить еще и WindowsInstaller. Проблема в том, что это я выяснил эмпирически, и возможно существуют другие вещи, которые нужно тащить, о которых я не знаю. Например непонятно, будет ли все это дело работать на Windows XP SP2. Будет ли на Windows XP работать MS SQL + EF.
2. Почему-то при запуске установленной программы на Windows 8 она ругается, что нужен .net 3.5, тогда как он идет встроенным.
У кого есть успешный опыт? Вот текущий скрипт:
#define MyAppName "SomeApp"
#define MyAppVersion "1.0"
#define MyAppPublisher "SomeCompany"
#define MyAppURL "SomeURL"
#define MyAppExeName "SomeFile.exe"
#define ThirdParty "libs\"
#define MSIFile "WindowsInstaller-KB893803-v2-x86.exe"
#define DotNetFile "DotNetFx35Client.exe"
[Setup]
AppId={{5E032C5B-4AAC-4F96-8C88-F662F09BCD48}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\SomeSoft {#MyAppVersion}
DefaultGroupName=SomeSoft {#MyAppVersion}
OutputDir=Output
OutputBaseFilename=SomeSoft {#MyAppVersion}
Compression=lzma
SolidCompression=yes
UsePreviousAppDir=yes
WizardImageFile=wizard.bmp
[Languages]
Name: "russian"; MessagesFile: "compiler:Languages\Russian.isl"
[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 0,6.1
[Files]
Source: "{#ThirdParty}\{#MSIFile}"; DestDir: {tmp}; Flags: deleteafterinstall; Check: MSI3IsNotInstalled; AfterInstall: InstallPackage('{tmp}\{#MSIFile}')
Source: "{#ThirdParty}\{#DotNetFile}"; DestDir: {tmp}; Flags: deleteafterinstall; Check: Framework35IsNotInstalled; AfterInstall: InstallPackage('{tmp}\{#DotNetFile}')
Source: "..\bin\Release\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: quicklaunchicon
[Run]
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
[Code]
const
// The minimum MSI version is 3.1.0.0
MinMSIVersionMS = (3 shl 16) or 1;
MinMSIVersionLS = (0 shl 16) or 0;
function MSI3IsNotInstalled : Boolean;
var
MSIVersionMS: Cardinal;
MSIVersionLS: Cardinal;
begin
Result := True;
if GetVersionNumbers(ExpandConstant('{sys}\msi.dll'), MSIVersionMS, MSIVersionLS) then
if MSIVersionMS >= MinMSIVersionMS then
Result := False;
end;
function Framework35IsNotInstalled(): Boolean;
var
bSuccess: Boolean;
flag: Cardinal;
begin
Result := True;
bSuccess := RegQueryDWordValue(HKLM, 'Software\Microsoft\NET Framework Setup\NDP\v3.5', 'Install', flag);
if (True = bSuccess) and (flag = 1) then
begin
Result := False;
end;
end;
procedure InstallPackage(FileName: String);
var
ResultCode: Integer;
StatusText: string;
begin
StatusText := WizardForm.StatusLabel.Caption;
WizardForm.StatusLabel.Caption := 'Install libs...';
WizardForm.ProgressGauge.Style := npbstMarquee;
try
if not Exec(ExpandConstant(FileName), '/q', '', SW_SHOW, ewWaitUntilTerminated, ResultCode) then
begin
MsgBox('Error: ' + IntToStr(ResultCode) + '.', mbError, MB_OK);
end;
finally
WizardForm.StatusLabel.Caption := StatusText;
WizardForm.ProgressGauge.Style := npbstNormal;
end;
end;
end.