1. #1
    Membre du Club
    Homme Profil pro
    Freelance
    Inscrit en
    novembre 2006
    Messages
    50
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Freelance

    Informations forums :
    Inscription : novembre 2006
    Messages : 50
    Points : 54
    Points
    54

    Par défaut ExtractFilename et paramètres de ses chaînes

    Bonjour à tous,

    J'ai un problème sur lequel je galère pas mal.
    Je dois découper des strings pour en récupérer d'un côté le nom de fichier exécutable et de l'autre les paramètres.
    Ceci afin de les utiliser dans un TAsyncProcess.

    Les strings sont récupérées dans la base de registre, donc je n'ai pas le choix de leur mise en forme.

    Exemples de strings :

    "C:\Windows\SysWOW64\RunDll32.EXE" "C:\Program Files\NVIDIA Corporation\Installer2\InstallerCore\NVI2.DLL",UninstallPackage Display.Update
    C:\Program Files (x86)\DYMO\DYMO Label Software\Uninstall DYMO Label.exe
    MsiExec.exe /X{908DB568-E5FA-40C7-A2AA-AB340190858B}
    RunDll32 C:\Program Files (x86)\COMMON~1\INSTAL~1\PROFES~1\RunTime\11\50\Intel32\ctor.dll,LaunchSetup "C:\Program Files (x86)\InstallShield Installation Information\{40989F6C-18D8-4EE1-9B79-3D6FD2893EE9}\setup.exe" -l0x40c UNINSTALL -removeonly
    c:\Program Files (x86)\Common Files\Adobe AIR\Versions\1.0\Resources\Adobe AIR Updater.exe -arp:uninstall

    J'ai fait exprès de choisir les exemples qui me posent des problèmes.
    J'aimerais récupérer l’exécutable en bleu
    et les paramètres en rouge.
    J'ai farfouillé un peu partout et je n'ai rien trouvé de très probant.
    J'ai bien évidemment essayé les ExtractFileName ExtractFileDir etc. sans succès.

    Quelqu'un a déjà eu affaire à ce problème ???

    Merci et joyeux Noël ;-)

  2. #2
    Membre éprouvé
    Profil pro
    Développeur informatique
    Inscrit en
    janvier 2010
    Messages
    446
    Détails du profil
    Informations personnelles :
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : janvier 2010
    Messages : 446
    Points : 1 021
    Points
    1 021

    Par défaut

    Bonjour

    Je pense que le plus simple est d'éclater chaque ligne de ton exemple dans une TStringList, puis récupérer le premier item et concaténer les autres.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    procedure TForm1.FormShow(Sender: TObject);
    var
      Liste: TStringList;
    begin
      Liste := TStringList.Create;
      try
        Liste.Delimiter:= ' ';
        Liste.DelimitedText:= '"C:\Windows\SysWOW64\RunDll32.EXE" "C:\Program Files\NVIDIA Corporation\Installer2\InstallerCore\NVI2.DLL",UninstallPackage Display.Update';
      Memo1.Clear;
      Memo1.Lines.AddStrings( Liste );
      finally
        Liste.Free;
      end ;
    end;
    Ce qui affichera
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    
    C:\Windows\SysWOW64\RunDll32.EXE
    C:\Program Files\NVIDIA Corporation\Installer2\InstallerCore\NVI2.DLL
    ,UninstallPackage
    Display.Update
    
    Cordialement,
    Tintinux

    Initiateur de Gestinux, une comptabilité gestion open-source, pour Linux, Windows et Mac OS.
    Une version stable et une autre en développement, avec Lazarus : vous pouvez aider à la tester, la traduire et à la développer.

  3. #3
    Membre du Club
    Homme Profil pro
    Freelance
    Inscrit en
    novembre 2006
    Messages
    50
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Freelance

    Informations forums :
    Inscription : novembre 2006
    Messages : 50
    Points : 54
    Points
    54

    Par défaut

    Oui c'est un peu ce que fait la procédure [CommandToList] du TProcess (unité C:\lazarus\fpc\3.0.4\source\packages\fcl-process\src\process.pp)
    Sauf que cela ne marche plus lorsqu'il y a des espaces dans le nom de fichier comme "c:\Program Files (x86)\Common Files\Adobe AIR\Versions\1.0\Resources\Adobe AIR Updater.exe -arp:uninstall" par exemple.
    Dans ce cas j'aurai :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    c:\Program 
    Files 
    (x86)\Common 
    Files\Adobe 
    AIR\Versions\1.0\Resources\Adobe 
    AIR 
    Updater.exe 
    -arp:uninstall
    C'est sûrement pour cette raison que la Property CommandLine du TProcess est deprecated;

    J'ai pensé faire un peu la méme chose mais en decoupant le TStringList par des '\', ce qui donnerait pour l'exemple ci dessus :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    c:
    Program Files (x86)
    Common Files
    Adobe AIR
    Versions
    1.0
    Resources
    Adobe AIR Updater.exe -arp:uninstall
    Dans ce cas on récupère le nom de l'exec+les params dans la dernière ligne.
    Et le path dans les lignes précédentes.

    La question c'est comment séparer le Nom de l'exe des paramètres en sachant qu'on peut avoir comme strings :
    • Uninstall DYMO Label.exe (Avec des espaces dans le nom de fichier)
    • MsiExec.exe /X{908DB568-E5FA-40C7-A2AA-AB340190858B}
    • msiexec /X{908DB568-E5FA-40C7-A2AA-AB340190858B} (Sans extension .exe)
    • Adobe AIR Updater.exe -arp:uninstall (avec des espaces et avec les parametres commencants par '-')


    Et là où ça devient de la folie, c'est quand il y a des '\' dans les paramètres comme :
    • RunDll32 C:\Program Files (x86)\COMMON~1\INSTAL~1\PROFES~1\RunTime\11\50\Intel32\ctor.dll,LaunchSetup "C:\Program Files (x86)\InstallShield Installation Information\{40989F6C-18D8-4EE1-9B79-3D6FD2893EE9}\setup.exe" -l0x40c UNINSTALL -removeonly

    Il n'y aurait pas une fonction Windows qui gérerait cette problématique ?

    Merci à ceux qui ont eu le courage de lire jusqu'ici...
    Et MERCI à ceux qui vont répondre ou apporter un début de réponse...

  4. #4
    Membre éprouvé
    Profil pro
    Développeur informatique
    Inscrit en
    janvier 2010
    Messages
    446
    Détails du profil
    Informations personnelles :
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : janvier 2010
    Messages : 446
    Points : 1 021
    Points
    1 021

    Par défaut

    Sauf que cela ne marche plus lorsque il y a des espaces dans le nom de fichier comme "c:\Program Files (x86)\Common Files\Adobe AIR\Versions\1.0\Resources\Adobe AIR Updater.exe -arp:uninstall" par exemple.
    Ce n'est pas un vrai nom de fichier qui est entre quotes, puisqu'il y a -arp:uninstall à l'intérieurdes quotes.

    Le mieux serait effectivement de trouver la fonction de l'API Windows qui fasse le travail, qu'on peut sûrement appeler avec Lazarus, ou sinon connaître les règles précises, qu'on peut certainement implémenter avec Lazarus.

    Dans les deux cas ce n'est pas une problématique Lazarus, et je te suggère d'aller voir ou de questionner sur des forums Windows.
    Cordialement,
    Tintinux

    Initiateur de Gestinux, une comptabilité gestion open-source, pour Linux, Windows et Mac OS.
    Une version stable et une autre en développement, avec Lazarus : vous pouvez aider à la tester, la traduire et à la développer.

  5. #5
    Membre du Club
    Homme Profil pro
    Freelance
    Inscrit en
    novembre 2006
    Messages
    50
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Freelance

    Informations forums :
    Inscription : novembre 2006
    Messages : 50
    Points : 54
    Points
    54

    Par défaut AnsiExtractQuotedStr, la solution pour les lignes commençant par "

    (Je fais un nouveau message pour pas alourdir le précédent)
    J'ai trouvé une solution pour les lignes commençant par un "

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    procedure _ExtractFileAndParamsFromQuotted(const ACmd: string; var AExe, AParams: string);
      var
        pCmd: PChar;
      begin
        pCmd := PChar(ACmd);  // Parce que AnsiExtractQuotedStr(PChar(ACmd), '"') ne fonctionne pas, car le premier paramètre de la procédure est un var
        AExe := AnsiExtractQuotedStr(pCmd, '"'); //function AnsiExtractQuotedStr(var Src: PChar; Quote: Char): string; dans SysUtils
        AParams := trim(pCmd);
      end;
    Avec ACmd := '"C:\Windows\SysWOW64\RunDll32.EXE" "C:\Program Files\NVIDIA Corporation\Installer2\InstallerCore\NVI2.DLL",UninstallPackage Display.Update'
    on récupère AExe = C:\Windows\SysWOW64\RunDll32.EXE (Extraction du contenu du premier QuotedStr de ACmd)
    et AParams = "C:\Program Files\NVIDIA Corporation\Installer2\InstallerCore\NVI2.DLL",UninstallPackage Display.Update (soit ACmd - l'extraction ci-dessus)

    Voilà, un des problèmes de résolu...

  6. #6
    Membre du Club
    Homme Profil pro
    Freelance
    Inscrit en
    novembre 2006
    Messages
    50
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Freelance

    Informations forums :
    Inscription : novembre 2006
    Messages : 50
    Points : 54
    Points
    54

    Par défaut

    Citation Envoyé par tintinux Voir le message
    Ce n'est pas un vrai nom de fichier qui est entre quotes, puisqu'il y a -arp:uninstall à l'intérieurdes quotes.
    Oui effectivement il n'y a pas de quotes autour de cette ligne de commande, je les ai mis pour que le texte soit plus lisible, cela peut porter a confusion, c'est de ma faute...

    La ligne de commande est bien : c:\Program Files (x86)\Common Files\Adobe AIR\Versions\1.0\Resources\Adobe AIR Updater.exe -arp:uninstall

  7. #7
    Membre éprouvé

    Homme Profil pro
    Retraité
    Inscrit en
    juin 2012
    Messages
    531
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Retraité
    Secteur : Biens de consommation

    Informations forums :
    Inscription : juin 2012
    Messages : 531
    Points : 955
    Points
    955

    Par défaut

    J'ai bricolé ça vite fait mais sous Linux:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    procedure TForm1.Button1Click(Sender: TObject);
    Var
      Full_Name, Dir_Name, File_Name, Ext_Name, Cmd_Name: String;
    begin
      Full_Name:='c:\Program Files (x86)\Common Files\Adobe AIR\Versions\1.0\Resources\Adobe AIR Updater.exe -arp:uninstall';
      Dir_Name:=ExtractFilePath(Full_Name);     //    ExtractFileDir(Full_Name) fonctionne aussi.
      File_Name:=ExtractFileName(Full_Name);    // Va récupérer le nom de fichier ET les paramètres.
      Ext_Name:=ExtractFileExt(Full_Name);      // Juste pour voir, ne sert à rien.
      Cmd_Name:=RightStr(Ext_Name,Length(Ext_Name)-4); // Récupérer les paramètres ( A modifier si plus de 3 caractères après le . )
      File_Name:=AnsiReplaceStr(File_Name,Cmd_Name,'');// Virer les paramètres du nom de fichier.
     
      ShowMessage('Chemin: '+Dir_Name+chr(10)+chr(10)+
                  'Fichier :'+File_Name+chr(10)+chr(10)+
                  'Extension & Cmd: '+Ext_Name+chr(10)+chr(10)+
                  'Commande: '+Cmd_Name);
    end;
    Le résultat est correct:
    Nom : file_name.jpg
Affichages : 84
Taille : 14,9 Ko
    Si vraiment la version windows de Lazarus ne digère pas les espaces il suffit de les remplacer par un caractère qu'on ne risque pas de trouver dans un nom de fichier ( < 32 ou 255 ) dans la chaîne originelle et de faire l'inverse une fois le traitement terminé.

    Note: Un truc bête et méchant: extractfilename renvoie bien le nom de fichier seul avec son extension mais extractfilenameonly le renvoie avec le chemin d'accès complet ce qui me semble un peu tartignole.

  8. #8
    Membre éprouvé

    Homme Profil pro
    Retraité
    Inscrit en
    juin 2012
    Messages
    531
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Retraité
    Secteur : Biens de consommation

    Informations forums :
    Inscription : juin 2012
    Messages : 531
    Points : 955
    Points
    955

    Par défaut

    J'ai trouvé une solution pour les lignes commençant par un "
    J'avais oublié ce détail, ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Full_Name:=AnsiReplaceStr(Full_Name,'"','');
    Serait peut-être plus simple.

  9. #9
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    décembre 2011
    Messages
    3 149
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Sénégal

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : décembre 2011
    Messages : 3 149
    Points : 11 640
    Points
    11 640
    Billets dans le blog
    5

    Par défaut

    Bonjour ! Intéressant casse-tête.

    Sur un autre forum, en réponse à une question similaire, quelqu'un conseillait d'utiliser la fonction CommandLineToArgvW, mais je n'ai pas réussi à faire un exemple qui fonctionne. Mon programme ne me renvoie que des points d'interrogation.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
     
    { https://stackoverflow.com/questions/44086865/delphi-extract-path-file-from-uninstallstring-registry-key }
     
    uses
      Windows, ShellAPI;
     
    function TryGetCommandLineFileName(const CommandLine: string; out FileName: string): boolean;
    type
      TPWideCharArray = array[0..0] of PWideChar;
    var
      Count: Integer;
      Arguments: PPWideChar;
    begin
      Arguments := CommandLineToArgvW(PWideChar(CommandLine), @Count);
      Result := Assigned(Arguments) and (Count > 0);
      if Result then
      begin
        FileName := TPWideCharArray(Arguments^)[0];
        LocalFree(THandle(Arguments));
      end;
    end;
     
    const
      EXEMPLES: array[1..10] of string = (
        '"C:\Windows\SysWOW64\RunDll32.EXE" "C:\Program Files\NVIDIA Corporation\Installer2\InstallerCore\NVI2.DLL",UninstallPackage Display.Update',
        'C:\Program Files (x86)\DYMO\DYMO Label Software\Uninstall DYMO Label.exe',
        'MsiExec.exe /X{908DB568-E5FA-40C7-A2AA-AB340190858B}',
        'RunDll32 C:\Program Files (x86)\COMMON~1\INSTAL~1\PROFES~1\RunTime\11\50\Intel32\ctor.dll,LaunchSetup "C:\Program Files (x86)\InstallShield Installation Information\{40989F6C-18D8-4EE1-9B79-3D6FD2893EE9}\setup.exe" -l0x40c UNINSTALL -removeonly',
        'c:\Program Files (x86)\Common Files\Adobe AIR\Versions\1.0\Resources\Adobe AIR Updater.exe -arp:uninstall',
        'Uninstall DYMO Label.exe',
        'MsiExec.exe /X{908DB568-E5FA-40C7-A2AA-AB340190858B}',
        'msiexec /X{908DB568-E5FA-40C7-A2AA-AB340190858B}',
        'Adobe AIR Updater.exe -arp:uninstall',
        'RunDll32 C:\Program Files (x86)\COMMON~1\INSTAL~1\PROFES~1\RunTime\11\50\Intel32\ctor.dll,LaunchSetup "C:\Program Files (x86)\InstallShield Installation Information\{40989F6C-18D8-4EE1-9B79-3D6FD2893EE9}\setup.exe" -l0x40c UNINSTALL -removeonly'
      );
     
    var
      vFileName: string;
      vIndex: integer;
     
    begin
      for vIndex := Low(EXEMPLES) to High(EXEMPLES) do
        if TryGetCommandLineFileName(EXEMPLES[vIndex], vFileName) then
          WriteLn(vIndex, ' ', vFileName);
    end.
    Autrement j'ai pensé à une autre approche. Le nœud du problème n'est-il pas de reconnaître le nom de l'exécutable, avec ou sans extension ? Parce que s'il y avait toujours l'extension, ce serait facile de séparer le nom de l'exécutable des paramètres, non ? Donc mon approche consiste à parcourir la chaîne, à m'arrêter à chaque espace et à chercher si la sous-chaîne qui précède cet espace ne se termine pas par ".exe" ou n'est pas le nom d'un exécutable se trouvant dans le PATH. Pour le moment, j'ai négligé le cas d'un nom d'exécutable entre guillemets.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
     
    uses
      SysUtils;
     
    function TryGetCommandLineFileName(const CommandLine: string; out FileName: string): boolean;
    var
      vPos: integer;
      vStr: string;
    begin
      result := FALSE;
      vPos := 1;
      while (vPos <= Length(CommandLine)) and not result do
      begin
        if Copy(CommandLine, vPos, 1) = ' ' then
        begin
          vStr := Copy(CommandLine, 1, Pred(vPos));
     
          if UpperCase(RightStr(vStr, 4)) = '.EXE' then
          begin
            result := TRUE;
            FileName := vStr;
          end else
          begin
            vStr := Concat(vStr, '.exe');
     
            vStr := ExeSearch(vStr, GetEnvironmentVariable('PATH'));
     
            if Length(vStr) > 0 then
            begin
              result := TRUE;
              FileName := vStr;
            end;
          end;
        end;
        Inc(vPos);
      end;
    end;
     
    const
      EXEMPLES: array[1..10] of string = (
        '"C:\Windows\SysWOW64\RunDll32.EXE" "C:\Program Files\NVIDIA Corporation\Installer2\InstallerCore\NVI2.DLL",UninstallPackage Display.Update',
        'C:\Program Files (x86)\DYMO\DYMO Label Software\Uninstall DYMO Label.exe',
        'MsiExec.exe /X{908DB568-E5FA-40C7-A2AA-AB340190858B}',
        'RunDll32 C:\Program Files (x86)\COMMON~1\INSTAL~1\PROFES~1\RunTime\11\50\Intel32\ctor.dll,LaunchSetup "C:\Program Files (x86)\InstallShield Installation Information\{40989F6C-18D8-4EE1-9B79-3D6FD2893EE9}\setup.exe" -l0x40c UNINSTALL -removeonly',
        'c:\Program Files (x86)\Common Files\Adobe AIR\Versions\1.0\Resources\Adobe AIR Updater.exe -arp:uninstall',
        'Uninstall DYMO Label.exe',
        'MsiExec.exe /X{908DB568-E5FA-40C7-A2AA-AB340190858B}',
        'msiexec /X{908DB568-E5FA-40C7-A2AA-AB340190858B}',
        'Adobe AIR Updater.exe -arp:uninstall',
        'RunDll32 C:\Program Files (x86)\COMMON~1\INSTAL~1\PROFES~1\RunTime\11\50\Intel32\ctor.dll,LaunchSetup "C:\Program Files (x86)\InstallShield Installation Information\{40989F6C-18D8-4EE1-9B79-3D6FD2893EE9}\setup.exe" -l0x40c UNINSTALL -removeonly'
      );
     
    var
      vFileName: string;
      vIndex: integer;
     
    begin
      for vIndex := Low(EXEMPLES) to High(EXEMPLES) do
        if TryGetCommandLineFileName(EXEMPLES[vIndex], vFileName) then
          WriteLn(vIndex, ' ', vFileName);
    end.

  10. #10
    Membre confirmé

    Homme Profil pro
    Autre
    Inscrit en
    novembre 2015
    Messages
    114
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : novembre 2015
    Messages : 114
    Points : 476
    Points
    476

    Par défaut

    Citation Envoyé par Roland Chastain Voir le message

    [...] mais je n'ai pas réussi à faire un exemple qui fonctionne. Mon programme ne me renvoie que des points d'interrogation. [...]
    Contrairement aux versions récentes de Delphi, Free Pascal n'utilise pas des chaînes de caractères Unicode "Wide" par défaut. Il faut donc faire la conversion avant l'appel à l'API Windows "Wide", ou bien forcer l'utilisation de ces chaînes de caractères Unicode "Wide". Par exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    {$modeswitch unicodestrings}
    ou bien

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     Arguments := CommandLineToArgvW(PWideChar(UnicodeString(CommandLine)), @Count);

  11. #11
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    décembre 2011
    Messages
    3 149
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Sénégal

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : décembre 2011
    Messages : 3 149
    Points : 11 640
    Points
    11 640
    Billets dans le blog
    5

    Par défaut

    @FChrisF
    Merci !

    Maintenant que l'exemple fonctionne, j'ai pu constater que la fonction CommandLineToArgvW ne fait pas notre affaire, c'est-à-dire ne gère pas le cas où le chemin de l'exécutable contient des espaces sans être entouré de guillemets.

  12. #12
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    décembre 2011
    Messages
    3 149
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Sénégal

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : décembre 2011
    Messages : 3 149
    Points : 11 640
    Points
    11 640
    Billets dans le blog
    5

    Par défaut

    Voici une proposition plus complète, pour ne pas dire parfaite.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
     
    uses
      SysUtils;
     
    function TryGetQuotedFileName(const aCommandLine: string; out aFileName, aParameter: string): boolean;
    var
      vQuotePos, vOtherQuotePos: integer;
    begin
      result := FALSE;
     
      vQuotePos := 1;
      while (vQuotePos <= Length(aCommandLine)) and (Copy(aCommandLine, vQuotePos, 1) <> '"') do
        Inc(vQuotePos);
      if vQuotePos > Length(aCommandLine) then
        exit;
     
      vOtherQuotePos := Succ(vQuotePos);
      while (vOtherQuotePos <= Length(aCommandLine)) and (Copy(aCommandLine, vOtherQuotePos, 1) <> '"') do
        Inc(vOtherQuotePos);
      if vOtherQuotePos > Length(aCommandLine) then
        exit;
     
      result := TRUE;
      aFileName := Copy(aCommandLine, vQuotePos, Succ(vOtherQuotePos - vQuotePos));
      aParameter := Copy(aCommandLine, vOtherQuotePos + 2);
    end;
     
    function TryGetCommandLineFileName(const aCommandLine: string; out aFileName, aParameter: string): boolean;
    var
      vFileName, vParameter: string;
      vSpacePos: integer;
    begin
      if UpperCase(RightStr(aCommandLine, 4)) = '.EXE' then
      begin
        result := TRUE;
        aFileName := aCommandLine;
        aParameter := '';
      end else
     
        if (Copy(aCommandLine, 1, 1) = '"') and TryGetQuotedFileName(aCommandLine, vFileName, vParameter) then
        begin
          result := TRUE;
          aFileName := vFileName;
          aParameter := vParameter;
        end else
          result := FALSE;
     
      vSpacePos := 1;
      while (vSpacePos <= Length(aCommandLine)) and not result do
      begin
        if Copy(aCommandLine, vSpacePos, 1) = ' ' then
        begin
          vFileName := Copy(aCommandLine, 1, Pred(vSpacePos));
     
          if UpperCase(RightStr(vFileName, 4)) = '.EXE' then
          begin
            result := TRUE;
            aFileName := vFileName;
            aParameter := Copy(aCommandLine, Succ(vSpacePos));
          end else
     
            if Length(ExeSearch(Concat(vFileName, '.exe'), GetEnvironmentVariable('PATH'))) > 0 then
            begin
              result := TRUE;
              aFileName := vFileName;
              aParameter := Copy(aCommandLine, Length(vFileName) + 2);
            end;
        end;
        Inc(vSpacePos);
      end;
    end;
     
    const
      EXEMPLES: array[1..10] of string = (
        '"C:\Windows\SysWOW64\RunDll32.EXE" "C:\Program Files\NVIDIA Corporation\Installer2\InstallerCore\NVI2.DLL",UninstallPackage Display.Update',
        'C:\Program Files (x86)\DYMO\DYMO Label Software\Uninstall DYMO Label.exe',
        'MsiExec.exe /X{908DB568-E5FA-40C7-A2AA-AB340190858B}',
        'RunDll32 C:\Program Files (x86)\COMMON~1\INSTAL~1\PROFES~1\RunTime\11\50\Intel32\ctor.dll,LaunchSetup "C:\Program Files (x86)\InstallShield Installation Information\{40989F6C-18D8-4EE1-9B79-3D6FD2893EE9}\setup.exe" -l0x40c UNINSTALL -removeonly',
        'c:\Program Files (x86)\Common Files\Adobe AIR\Versions\1.0\Resources\Adobe AIR Updater.exe -arp:uninstall',
        'Uninstall DYMO Label.exe',
        'MsiExec.exe /X{908DB568-E5FA-40C7-A2AA-AB340190858B}',
        'msiexec /X{908DB568-E5FA-40C7-A2AA-AB340190858B}',
        'Adobe AIR Updater.exe -arp:uninstall',
        'RunDll32 C:\Program Files (x86)\COMMON~1\INSTAL~1\PROFES~1\RunTime\11\50\Intel32\ctor.dll,LaunchSetup "C:\Program Files (x86)\InstallShield Installation Information\{40989F6C-18D8-4EE1-9B79-3D6FD2893EE9}\setup.exe" -l0x40c UNINSTALL -removeonly'
      );
     
    var
      vFileName, vParameter: string;
      vIndex: integer;
     
    begin
      for vIndex := Low(EXEMPLES) to High(EXEMPLES) do
        if TryGetCommandLineFileName(EXEMPLES[vIndex], vFileName, vParameter) then
          WriteLn(
            'Exemple : ', EXEMPLES[vIndex], #13#10,
            'Nom de fichier : ', vFileName, #13#10,
            'Paramètre : ', vParameter
          );
    end.
    Exemple : "C:\Windows\SysWOW64\RunDll32.EXE" "C:\Program Files\NVIDIA Corporation\Installer2\InstallerCore\NVI2.DLL",UninstallPackage Display.Update
    Nom de fichier : "C:\Windows\SysWOW64\RunDll32.EXE"
    Paramètre : "C:\Program Files\NVIDIA Corporation\Installer2\InstallerCore\NVI2.DLL",UninstallPackage Display.Update
    Exemple : C:\Program Files (x86)\DYMO\DYMO Label Software\Uninstall DYMO Label.exe
    Nom de fichier : C:\Program Files (x86)\DYMO\DYMO Label Software\Uninstall DYMO Label.exe
    Paramètre :
    Exemple : MsiExec.exe /X{908DB568-E5FA-40C7-A2AA-AB340190858B}
    Nom de fichier : MsiExec.exe
    Paramètre : /X{908DB568-E5FA-40C7-A2AA-AB340190858B}
    Exemple : RunDll32 C:\Program Files (x86)\COMMON~1\INSTAL~1\PROFES~1\RunTime\11\50\Intel32\ctor.dll,LaunchSetup "C:\Program Files (x86)\InstallShield Installation Information\{40989F6C-18D8-4EE1-9B79-3D6FD2893EE9}\setup.exe" -l0x40c UNINSTALL -removeonly
    Nom de fichier : RunDll32
    Paramètre : C:\Program Files (x86)\COMMON~1\INSTAL~1\PROFES~1\RunTime\11\50\Intel32\ctor.dll,LaunchSetup "C:\Program Files (x86)\InstallShield Installation Information\{40989F6C-18D8-4EE1-9B79-3D6FD2893EE9}\setup.exe" -l0x40c UNINSTALL -removeonly
    Exemple : c:\Program Files (x86)\Common Files\Adobe AIR\Versions\1.0\Resources\Adobe AIR Updater.exe -arp:uninstall
    Nom de fichier : c:\Program Files (x86)\Common Files\Adobe AIR\Versions\1.0\Resources\Adobe AIR Updater.exe
    Paramètre : -arp:uninstall
    Exemple : Uninstall DYMO Label.exe
    Nom de fichier : Uninstall DYMO Label.exe
    Paramètre :
    Exemple : MsiExec.exe /X{908DB568-E5FA-40C7-A2AA-AB340190858B}
    Nom de fichier : MsiExec.exe
    Paramètre : /X{908DB568-E5FA-40C7-A2AA-AB340190858B}
    Exemple : msiexec /X{908DB568-E5FA-40C7-A2AA-AB340190858B}
    Nom de fichier : msiexec
    Paramètre : /X{908DB568-E5FA-40C7-A2AA-AB340190858B}
    Exemple : Adobe AIR Updater.exe -arp:uninstall
    Nom de fichier : Adobe AIR Updater.exe
    Paramètre : -arp:uninstall
    Exemple : RunDll32 C:\Program Files (x86)\COMMON~1\INSTAL~1\PROFES~1\RunTime\11\50\Intel32\ctor.dll,LaunchSetup "C:\Program Files (x86)\InstallShield Installation Information\{40989F6C-18D8-4EE1-9B79-3D6FD2893EE9}\setup.exe" -l0x40c UNINSTALL -removeonly
    Nom de fichier : RunDll32
    Paramètre : C:\Program Files (x86)\COMMON~1\INSTAL~1\PROFES~1\RunTime\11\50\Intel32\ctor.dll,LaunchSetup "C:\Program Files (x86)\InstallShield Installation Information\{40989F6C-18D8-4EE1-9B79-3D6FD2893EE9}\setup.exe" -l0x40c UNINSTALL -removeonly

  13. #13
    Rédacteur/Modérateur
    Avatar de Andnotor
    Profil pro
    Inscrit en
    septembre 2008
    Messages
    4 535
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : septembre 2008
    Messages : 4 535
    Points : 9 403
    Points
    9 403

    Par défaut

    Elles viennent d'où ces clés de registres, un truc "maison" ?

    Parce que franchement, ce serait très surprenant que Adobe ne sache pas qu'un chemin avec espace s'écrit entre guillemets...

    Et là, RunDll32 C:\Program Files (x86)\COMMON~1\INSTAL~1\PROFES~1\RunTime\11\50\Intel32\ctor.dll,..., une partie en nom long et l'autre en court
    Je ne suis même pas certain que RunDLL32 supporte maintenant les noms longs (même entre guillemets). Ce que je retrouve dans mes vieux codes est toujours converti en 8.3...

    1. ... For best results, use the short file name instead of the long file name to ensure that no illegal characters will appear. Note in particular that this means a DLL in the "C:\Program Files" folder should be converted to its short name.
    2. The <dllname> may not contain any spaces or commas or quotation marks. This is a limitation in the Rundll command line parser.

Discussions similaires

  1. echec de la conversion de paramètre d'un string en int32
    Par sycoulibaly dans le forum VB.NET
    Réponses: 21
    Dernier message: 18/02/2009, 00h19
  2. DLL avec paramètres CString et String en .net
    Par basnifo dans le forum C++/CLI
    Réponses: 3
    Dernier message: 25/09/2008, 19h45
  3. Réponses: 7
    Dernier message: 29/10/2007, 14h03
  4. Réponses: 4
    Dernier message: 18/06/2007, 13h54
  5. Réponses: 3
    Dernier message: 04/06/2007, 09h31

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo