Utilisation avancée de Inno Setup
Publié : jeu. 17/déc./2015 1:08
Bonjour,
Pour diffuser certains de mes programmes, j'utilise Inno Setup + Inno Script Studio
http://www.jrsoftware.org
Si lors de l'installation, un ou plusieurs fichiers faisant parti du package sont en cours d’exécution, la mise à jour ne se fait pas correctement.
J'ai essayé d'utiliser la dll psvince, mais cela ne fonctionne pas pour les process 64-bit.
J'ai donc écrit un petit programme pour pallier le problème.
La version 32-bit fonctionne aussi bien pour les versions 32-bit ou 64-bit de l'installeur.
L'installeur est aussi crypté, protégé par mot de passe et d'une durée d'installation limitée dans le temps.
Programme mypviewer.pbpProgramme mypviewer.pbVoici une partie du script inno setup que j'utilise
C'est la version 64-bit du setup. Remplacer 64 par 32 pour la version 32-bit du setup
Dans l'exemple, le programme s'appelle myprog64.exe et utilise en plus les programmes program1.exe a program5.exe dont l'installeur teste la présence en mémoire. Le programme myprogram64.exe est testé en mémoire via l'AppMutex
Si vous avez d'autres solutions, je suis preneur.
Pour diffuser certains de mes programmes, j'utilise Inno Setup + Inno Script Studio
http://www.jrsoftware.org
Si lors de l'installation, un ou plusieurs fichiers faisant parti du package sont en cours d’exécution, la mise à jour ne se fait pas correctement.
J'ai essayé d'utiliser la dll psvince, mais cela ne fonctionne pas pour les process 64-bit.
J'ai donc écrit un petit programme pour pallier le problème.
La version 32-bit fonctionne aussi bien pour les versions 32-bit ou 64-bit de l'installeur.
L'installeur est aussi crypté, protégé par mot de passe et d'une durée d'installation limitée dans le temps.
Programme mypviewer.pbp
Code : Tout sélectionner
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://www.purebasic.com/namespace" version="1.0" creator="PureBasic 5.40 LTS (Windows - x64)">
<section name="config">
<options closefiles="0" openmode="0" name="mypviewer (x86) Project"/>
</section>
<section name="data">
<explorer view="..\..\Program Files\PureBasic\Examples\" pattern="0"/>
<log show="1"/>
<lastopen date="2015-12-16 13:34" user="gg" host="EBCAGE"/>
</section>
<section name="files">
<file name="mypviewer.pb">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" panelstate="+"/>
<fingerprint md5="3cdd5a2133f1fbc3016d48657ab2de47"/>
</file>
</section>
<section name="targets">
<target name="Default Target" enabled="1" default="1">
<inputfile value="mypviewer.pb"/>
<outputfile value="mypviewer.exe"/>
<compiler version="PureBasic 5.40 LTS (Windows - x86)"/>
<executable value="mypviewer.exe"/>
<options unicode="1" debug="1"/>
<purifier enable="1"/>
<temporaryexe value="source"/>
<icon enable="0">yhpview.ico</icon>
<versioninfo enable="1">
<field0 value="15,12,0,17"/>
<field1 value="15,12,0,17"/>
<field2 value="CAGE"/>
<field3 value="mypviewer"/>
<field4 value="15.12.17"/>
<field5 value="15.12.17"/>
<field6 value="Process Viewer"/>
<field7 value="mypviewer.exe"/>
<field8 value="mypviewer.exe"/>
<field9 value="© CAGE"/>
<field10 value="This software is the property of the author : CAGE"/>
<field11 value="0"/>
<field12 value="0"/>
</versioninfo>
</target>
</section>
</project>
Code : Tout sélectionner
EnableExplicit
OnErrorGoto(?ErrorHandler)
Procedure getNamePID(ProcessName.s,*ptrPID)
; Retrieve the ProcessID according to exe name.
; Note: If many runing exe share the same name,
; Note: this would retrieve the first exe PID that had found,not all.
; Note: If found it, return 1 else 0, ps: .lbool = .l
Protected HSnap.l,Prec.processentry32,result.l=#False
HSnap=CreateToolhelp32Snapshot_(#TH32CS_SNAPPROCESS,0)
If HSnap=#INVALID_HANDLE_VALUE
ProcedureReturn result
EndIf
Prec\dwSize=SizeOf(prec)
If Not Process32First_(HSnap,Prec)
ProcedureReturn result
EndIf
Repeat
If LCase(GetFilePart(PeekS(@Prec\szexefile)))=LCase(ProcessName)
PokeL(*ptrPID,Prec\th32ProcessID)
result=#True
Break
EndIf
Until Not Process32Next_(HSnap,Prec)
CloseHandle_(HSnap)
ProcedureReturn result
EndProcedure
Define Count = CountProgramParameters()
Define Program$ = #Null$
Define rcode = #False
If Count
Program$ = ProgramParameter(0)
Define ptrPID = 0
Define ExeName$ = GetFilePart(Program$)
If getNamePID(ExeName$, @ptrPID)
rcode = #True
Else
rcode = #False
EndIf
Else
rcode = #False
EndIf
ErrorHandler:
End rcode
C'est la version 64-bit du setup. Remplacer 64 par 32 pour la version 32-bit du setup
Dans l'exemple, le programme s'appelle myprog64.exe et utilise en plus les programmes program1.exe a program5.exe dont l'installeur teste la présence en mémoire. Le programme myprogram64.exe est testé en mémoire via l'AppMutex
Code : Tout sélectionner
; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
#define MyAppName "MYPROG"
#define MyAppVersion "15.12.17"
#define MyAppPublisher "© 2014-2015 CAGE"
[Setup]
ArchitecturesAllowed=x64
; 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={{8B7E0591-E499-42C1-997B-2E5D22039A3B}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppPublisher={#MyAppPublisher}
DefaultDirName=D:\Public\{#MyAppName}
DefaultGroupName={#MyAppName}
AllowNoIcons=yes
LicenseFile=embedded\License.rtf
InfoAfterFile=embedded\InfoAfter.rtf
InfoBeforeFile=embedded\InfoBefore.rtf
OutputDir=.\binaires
OutputBaseFilename=myprog-full-setup-x64
Compression=lzma
SolidCompression=yes
PrivilegesRequired=lowest
Password=Private
Encryption=yes
AppMutex=myprog64
CloseApplications=yes
RestartApplications=no
CloseApplicationsFilter=*.*
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
Name: "french" ; MessagesFile: "compiler:Languages\French.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
[Types]
Name: Custom ; Description: "Select components to install" ; Flags:
Name: Compact; Description: "Install components" ; Flags: IsCustom
[Components]
[Files]
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
Source: "release\mypviewer.exe"; Flags: dontcopy
[Icons]
Name: "{group}\{#MyAppName}" ; Filename: "{app}\myprog64.exe" ;
Name: "{group}\{#MyAppName} Help" ; Filename: "{app}\myptog64.chm" ;
Name: "{group}\{#MyAppName} Uninstall"; Filename: "{uninstallexe}" ;
;
Name: "{commondesktop}\myprog64"; Filename: "{app}\myprog64.exe"; Tasks: desktopicon;
;
Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\{#MyAppName}"; Filename: "{app}\myprog64.exe"; Tasks: quicklaunchicon;
[Run]
Filename: "{app}\myprog64.exe" ; Description: "Launch MYPROG x64" ; Flags: nowait postinstall skipifsilent;
Filename: "{app}\myprog64.chm" ; Description: "Launch MYPROG Help" ; Flags: nowait postinstall skipifsilent shellexec;
[Code]
const EXPIRY_DATE = '2016.01.03'; //Date format: yyyy.mm.dd
function InitializeSetup(): Boolean;
begin
//If current date exceeds MY_EXPIRY_DATE_STR then return false and exit Installer.
Result := CompareStr(GetDateTimeString('yyyy.mm.dd', #0,#0), EXPIRY_DATE) <= 0;
if not Result then
begin
MsgBox('The install date '+EXPIRY_DATE+' has been exceeded.'+chr(13)+chr(13)+'The Program will not install.', mbError, MB_OK);
Exit;
end;
end;
function ProductRunning(MyProgram:String): Boolean;
var
ResultCode: Integer;
begin
if Exec(ExpandConstant('{tmp}\mypviewer.exe'), MyProgram, '', SW_HIDE, ewWaitUntilTerminated, ResultCode) then
begin
Result := ResultCode > 0;
Exit;
end;
MsgBox('Failed to check running process '+MyProgram, mbError, MB_OK);
end;
function PrepareToInstall(var NeedsRestart: Boolean): String;
var
ResultCode: Integer;
MyProgram: String;
MyPrograms: array[1..5] of String;
index: integer;
begin
Exec('taskkill.exe', '/f /im hh.exe', '', SW_HIDE, ewWaitUntilTerminated, ResultCode)
ExtractTemporaryFile('mypviewer.exe');
MyPrograms[1] := 'program1.exe'
MyPrograms[2] := 'program2.exe'
MyPrograms[3] := 'program3.exe'
MyPrograms[4] := 'program4.exe'
MyPrograms[5] := 'program5.exe'
for index := 1 to 5 do begin
MyProgram := MyPrograms[index]
//MsgBox(MyProgram, mbInformation, MB_OK);
while ProductRunning(MyProgram) do
begin
if MsgBox( MyProgram+' is running.'+chr(13)+chr(13)+'Click [Yes] to shut it down and continue installation, or'+chr(13)+'Click [No] to exit.', mbConfirmation, MB_YESNO ) = IDNO then
begin
Result := MyProgram+' is running.';
Exit;
end;
Exec('taskkill.exe', '/f /im '+MyProgram, '', SW_HIDE, ewWaitUntilTerminated, ResultCode)
end;
end;
end;