IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Delphi Discussion :

probleme avec PowerShell et Delphi 11 update 3


Sujet :

Delphi

  1. #1
    Membre averti

    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2024
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2024
    Messages : 26
    Par défaut probleme avec PowerShell et Delphi 11 update 3
    Bonjour,

    j'essaye d'executer une commande PowerShell par Delphi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Get-WmiObject Win32_SerialPort | ForEach-Object { "$($_.DeviceID) - $($_.Caption)" }
    qui fonctionne tres bien sur PowerShell mais quand je l'inclus dans un programme :
    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
     
    unit Unit1;
     
    interface
     
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
      Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
     
    type
      TForm1 = class(TForm)
        Button1: TButton;
        Memo: TMemo;
        procedure Button1Click(Sender: TObject);
      private
        { Déclarations privées }
        procedure RunPowerShellCommand(const Command: string; OutputLines: TStringList);
      public
        { Déclarations publiques }
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm1.RunPowerShellCommand(const Command: string; OutputLines: TStringList);
    var
      SecurityAttr: TSecurityAttributes;
      StartInfo: TStartupInfo;
      ProcessInfo: TProcessInformation;
      PipeRead, PipeWrite: THandle;
      Buffer: array[0..1023] of AnsiChar;
      BytesRead: DWORD;
    begin
      ZeroMemory(@SecurityAttr, SizeOf(SecurityAttr));
      SecurityAttr.nLength := SizeOf(SecurityAttr);
      SecurityAttr.bInheritHandle := True;
     
      if not CreatePipe(PipeRead, PipeWrite, @SecurityAttr, 0) then
        raise Exception.Create('Impossible de créer les pipes.');
     
      try
        ZeroMemory(@StartInfo, SizeOf(StartInfo));
        StartInfo.cb := SizeOf(StartInfo);
        StartInfo.hStdOutput := PipeWrite;
        StartInfo.hStdError := PipeWrite;
        StartInfo.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
        StartInfo.wShowWindow := SW_HIDE;
     
        ZeroMemory(@ProcessInfo, SizeOf(ProcessInfo));
     
        if not CreateProcess(nil, PChar('powershell -Command "' + Command + '"'),
          nil, nil, True, CREATE_NO_WINDOW, nil, nil, StartInfo, ProcessInfo) then
          raise Exception.Create('Échec de la création du processus PowerShell.');
     
        CloseHandle(PipeWrite);
     
        OutputLines.Clear;
        repeat
          if ReadFile(PipeRead, Buffer, SizeOf(Buffer) - 1, BytesRead, nil) and (BytesRead > 0) then
          begin
            Buffer[BytesRead] := #0;
            OutputLines.Text := OutputLines.Text + string(Buffer);
          end;
        until BytesRead = 0;
     
        WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
        CloseHandle(ProcessInfo.hThread);
        CloseHandle(ProcessInfo.hProcess);
      finally
        CloseHandle(PipeRead);
      end;
    end;
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
      Results: TStringList;
    begin
      Results := TStringList.Create;
      try
        RunPowerShellCommand(
          'Get-WmiObject Win32_SerialPort | ForEach-Object { "$($_.DeviceID) - $($_.Caption)" }',
          Results
        );
     
        if Results.Count > 0 then
          Memo.Lines.Assign(Results) // Affiche les résultats dans le Memo
        else
          ShowMessage('Aucune donnée n''a été récupérée.');
      finally
        Results.Free;
      end;
    end;
     
    end.
    le commande ne s'exécute pas correctement ou du moins je n'arrive pas a récupérer les données.

    Est ce que j'ai commis un erreur dans mon code ? j'ai essayé un grand nombre de solutions, même en essayant d'utiliser les API Windows avec ce que j'ai trouvé sur le Net.

    le but est d'avoir les port séries dans un tableau par exemple COM4, COM5, COM6, ... et la description du port. Pour faire au plus simple j'utilise un memo pour afficher mes résultats sans succès.

    par exemple dans mon cas, j'ai lorsque j'exécute dans PowerShell ma commande :

    COM3 - Arduino Mega 2560 (COM3)
    COM8 - Silicon Labs CP210x USB to UART Bridge (COM8)
    COM9 - Silicon Labs CP210x USB to UART Bridge (COM9)


    j'aimerais retrouver ces données dans un tableau à 2 dimensions.

    Merci pour votre aide précieuse

    Pascal

  2. #2
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 993
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 993
    Par défaut
    Je te recommande de revoir tes handles de Pipe, tu peux utiliser ce code si tu veux comprendre l'historique de comme bien associer les Pipe de Lecture et Ecriture sur les trois canaux, c'est dans ce sujet Redirection des entrées/sorties du process
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 569
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 569
    Billets dans le blog
    65
    Par défaut
    D'un autre côté, je me pose la question : pourquoi utiliser un appel à powershell quand on peut le faire directement dans le code ?

    WMI Delphi Code Creator est mon ami, en quelques sélections j'ai obtenu un code qu'il ma simplement fallu modifié en
    quelque chose comme ceci
    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
     
    var Tableau : array [20,2] of string;  // un tableau dynamique serait mieux
    ..... 
    procedure  GetWin32_SerialPortInfo;
    const
      WbemUser            ='';
      WbemPassword        ='';
      WbemComputer        ='localhost';
      wbemFlagForwardOnly = $00000020;
    var
      FSWbemLocator : OLEVariant;
      FWMIService   : OLEVariant;
      FWbemObjectSet: OLEVariant;
      FWbemObject   : OLEVariant;
      oEnum         : IEnumvariant;
      iValue        : LongWord;
      i : word;
    begin;
      FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
      FWMIService   := FSWbemLocator.ConnectServer(WbemComputer, 'root\CIMV2', WbemUser, WbemPassword);
      FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM Win32_SerialPort','WQL',wbemFlagForwardOnly);
      oEnum         := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
      i:=0;   
      while oEnum.Next(1, FWbemObject, iValue) = 0 do
      begin
        Tableau[i,0]:=String(FWbemObject.DeviceID);
        Tableau[i,1]:=String(FWbemObject.Caption);
        inc(i);
        FWbemObject:=Unassigned;
      end;
    end;
    Impossible à tester sur ma machine qui n'a aucun port série
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  4. #4
    Membre émérite Avatar de sergio_is_back
    Homme Profil pro
    Consultant informatique industrielle, développeur tout-terrain
    Inscrit en
    Juin 2004
    Messages
    1 180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Consultant informatique industrielle, développeur tout-terrain
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 180
    Par défaut
    Il est aussi possible aussi d'énumérer la liste des ports séries via la base de registre, la clé HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM contient la liste des périphériques RS232/RS422/TTL détectés sur la machine

  5. #5
    Membre averti

    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2024
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2024
    Messages : 26
    Par défaut
    Bonjour à tous,

    j'avais déjà essayé la base de registre, c'était simple. J'avais bien mes ports COM, mais pas de description du port dans la base de registre. Tu peux essayer si tu veux, moi ce qui m'intéresse c'est le port COM ET sa description.

    Je ne me suis pas penché plus en avant, je vais essayer de voir avec le PowerShell. J'avais écrit le programme et tout fonctionnait parfaitement, mais malheureusement en faisant des sauvegardes multiples, j'ai perdu la version finale que j'ai transformé en C++ Builder à l'exception près que j'utilise un fichier .lib et ca marche très bien en C++. Je ne sais pas comment ajouter ce fichier .lib à mon programme Delphi. Si vous avez une idée?

    Merci à tous pour votre aide

    Pascal

  6. #6
    Membre émérite Avatar de sergio_is_back
    Homme Profil pro
    Consultant informatique industrielle, développeur tout-terrain
    Inscrit en
    Juin 2004
    Messages
    1 180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Consultant informatique industrielle, développeur tout-terrain
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 180
    Par défaut
    Citation Envoyé par herrflick13 Voir le message
    Bonjour à tous,

    j'avais déjà essayé la base de registre, c'était simple. J'avais bien mes ports COM, mais pas de description du port dans la base de registre. Tu peux essayer si tu veux, moi ce qui m'intéresse c'est le port COM ET sa description.

    Je ne me suis pas penché plus en avant, je vais essayer de voir avec le PowerShell. J'avais écrit le programme et tout fonctionnait parfaitement, mais malheureusement en faisant des sauvegardes multiples, j'ai perdu la version finale que j'ai transformé en C++ Builder à l'exception près que j'utilise un fichier .lib et ca marche très bien en C++. Je ne sais pas comment ajouter ce fichier .lib à mon programme Delphi. Si vous avez une idée?

    Merci à tous pour votre aide

    Pascal
    Si tu veux le port et sa description, alors, c'est exactement le code qu'a donné SergioMaster plus haut la discussion !!!

  7. #7
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 569
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 569
    Billets dans le blog
    65
    Par défaut
    Et encore, la requête WSQL proposée peut être affinée (j'ai horreur des SELECT *)

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT DeviceID,Caption FROM Win32_SerialPort
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

Discussions similaires

  1. [Rave] Problème avec DataMemo sous Delphi 2006
    Par bhtechnologies dans le forum Composants VCL
    Réponses: 12
    Dernier message: 30/07/2009, 15h53
  2. [KUBUNTU] Problème avec la commande apt-get update
    Par benjamin1985 dans le forum Ubuntu
    Réponses: 2
    Dernier message: 04/11/2008, 22h55
  3. Problème avec TMediaPlayer de Delphi
    Par cincap dans le forum Composants VCL
    Réponses: 6
    Dernier message: 16/01/2008, 17h36
  4. [VB.net] Problème avec les paramètres d'un update
    Par dolyne.b dans le forum Accès aux données
    Réponses: 5
    Dernier message: 16/05/2007, 17h00
  5. Problème avec EInOutError sous delphi 2005
    Par Teb dans le forum Langage
    Réponses: 3
    Dernier message: 19/08/2005, 11h48

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