Utilisation avancée de Inno Setup

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Avatar de l’utilisateur
cage
Messages : 604
Inscription : ven. 16/oct./2015 18:22
Localisation : France
Contact :

Utilisation avancée de Inno Setup

Message par cage »

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.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>
Programme mypviewer.pb

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
Voici 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

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;
Si vous avez d'autres solutions, je suis preneur.
■ Win10 Pro 64-bit (Intel Celeron CPU N2920 @ 1.86GHz, 4,0GB RAM, Intel HD Graphics) & PB 6.12 LTS
■ Vivre et laisser vivre.
■ PureBasic pour le fun
■ Gérard sur le forum Anglais
■ Mes sites: http://pbcage.free.fr - http://yh.toolbox.free.fr
Marc56
Messages : 2197
Inscription : sam. 08/févr./2014 15:19

Re: Utilisation avancée de Inno Setup

Message par Marc56 »

Merci pour ce partage :wink:

Personnellement je met dans le même package les versions 32 et 64 bits, Inno se charge d'installer la version adhoc en fonction de l'os.

Je met simplement dans la section [Files] un contrôle à la fin de chaque source

Source: ... (mon prog v 64 bits) ... Check: Is64BitInstallMode
Source: ... (mon prog v 32 bits) ... Check: not Is64BitInstallMode

Pour les autres fichiers (communs) rien de spécial.

D'après ce que j'ai compris, le setup lui-même n'est que du 32 bits, donc inutile de faire deux packages (à moins d'avoir un tas de fichiers différents d'une version à l'autre, mais dans mon cas, seul l'EXE est différent)
Avatar de l’utilisateur
cage
Messages : 604
Inscription : ven. 16/oct./2015 18:22
Localisation : France
Contact :

Re: Utilisation avancée de Inno Setup

Message par cage »

Effectivement, la possibilité d'utiliser Check: Is64BitInstallMode ou Check: not Is64BitInstallMode comme tu l'indique est intéressante.
L'installeur que je prend pour exemple fait environ 190Mo pour la version 64-bit et un peu moins pour la version 32-bit.
Il contient a ce jour plus de 1500 fichiers a installer (copier) sur le PC de l'utilisateur.
Je ne souhaite pas inclure les fichiers 32-bit et 64-bit dans un même installeur qui deviendrait trop important en taille.
Le but recherché dans l'exemple est de détecter lors de l'installation si des fichiers présents dans l'installateur sont actifs en mémoire pour les tuer afin qu'ils puissent êtres remplacés.
D’où ma tentative d'utilisation de la DLL Psvince qui s'est vouée par un échec.
Alors la question implicite est : as-tu (avez vous) testé/utilisé une solution personnelle ou pas d'ailleurs qui fasse la même chose (détecter/tuer les fichiers a remplacer) pour que l'installeur Inno Setup soit le plus performant possible.
Merci de vos retours d'expérience a ce sujet.
■ Win10 Pro 64-bit (Intel Celeron CPU N2920 @ 1.86GHz, 4,0GB RAM, Intel HD Graphics) & PB 6.12 LTS
■ Vivre et laisser vivre.
■ PureBasic pour le fun
■ Gérard sur le forum Anglais
■ Mes sites: http://pbcage.free.fr - http://yh.toolbox.free.fr
Marc56
Messages : 2197
Inscription : sam. 08/févr./2014 15:19

Re: Utilisation avancée de Inno Setup

Message par Marc56 »

Je n'en n'ai jamais eut l'occasion, mais effectivement, j'aurais fais comme toi et invoqué "taskkill".
Cependant, je ne sais pas à partir de quelle version de Windows cet utilitaire est présent ?
Répondre