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;