Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   cmd output in memo - Bug (https://www.delphipraxis.net/205064-cmd-output-memo-bug.html)

wschrabi 28. Jul 2020 17:42

cmd output in memo - Bug
 
Hallo Leute,
also in https://delphi.fandom.com/wiki/Captu...altime_To_Memo ist ein super Ansatz,

Delphi-Quellcode:
procedure Tform1.CaptureConsoleOutput(const ACommand, AParameters: String; AMemo: TMemo);
 const
   CReadBuffer = 2400;
 var
   saSecurity: TSecurityAttributes;
   hRead: THandle;
   hWrite: THandle;
   suiStartup: TStartupInfo;
   piProcess: TProcessInformation;
   pBuffer: array[0..CReadBuffer] of Char;
   dRead: DWord;
   dRunning: DWord;
 begin
   saSecurity.nLength := SizeOf(TSecurityAttributes);
   saSecurity.bInheritHandle := True;
   saSecurity.lpSecurityDescriptor := nil;
 
   if CreatePipe(hRead, hWrite, @saSecurity, 0) then
   begin  
     FillChar(suiStartup, SizeOf(TStartupInfo), #0);
     suiStartup.cb := SizeOf(TStartupInfo);
     suiStartup.hStdInput := hRead;
     suiStartup.hStdOutput := hWrite;
     suiStartup.hStdError := hWrite;
     suiStartup.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;  
     suiStartup.wShowWindow := SW_HIDE;
 
     if CreateProcess(nil, PChar(ACommand + ' ' + AParameters), @saSecurity,
       @saSecurity, True, NORMAL_PRIORITY_CLASS, nil, nil, suiStartup, piProcess)
       then
     begin
       repeat
         dRunning := WaitForSingleObject(piProcess.hProcess, 100);      
         Application.ProcessMessages();
         repeat
           dRead := 0;
           ReadFile(hRead, pBuffer[0], CReadBuffer, dRead, nil);        
           pBuffer[dRead] := #0;
 
           OemToAnsi(pBuffer, pBuffer);
           AMemo.Lines.Add(String(pBuffer));
         until (dRead < CReadBuffer);    
       until (dRunning <> WAIT_TIMEOUT);
       CloseHandle(piProcess.hProcess);
       CloseHandle(piProcess.hThread);  
     end;
 
     CloseHandle(hRead);
     CloseHandle(hWrite);
   end;
end;



doch leider bekomme ich in zeile
Delphi-Quellcode:
   if CreatePipe(hRead, hWrite, @saSecurity, 0) then
Diesen Error:
Delphi-Quellcode:
[dcc64 Fehler] BUnit1.pas(1313): E2010 Inkompatible Typen: 'PAnsiChar' und 'array[0..2400] of Char'
Ich kenne mich nicht ganz aus, es sit pBuffer ja ein array of Char, und das CretePipe braucht PChar.

Wie kann man den Fehler beheben? Ich habe Delphi Berlin.

DANKE

hoika 28. Jul 2020 17:44

AW: cmd output in memo - Bug
 
Hallo,

alt
pBuffer: array[0..CReadBuffer] of Char;

neu
pBuffer: array[0..CReadBuffer] of AnsiChar;


Oh, ich glaube, falsch gelesen.

wschrabi 28. Jul 2020 18:10

AW: cmd output in memo - Bug
 
Danke, ja der Fehler ist damit gelöst,
doch ich bekomm noch einen neuen jetzt:

Delphi-Quellcode:
[dcc32 Fehler] BUnit1.pas(1298): E2033 Die Typen der tatsächlichen und formalen Var-Parameter müssen übereinstimmen
bei der Zeile:
Delphi-Quellcode:
 if CreatePipe(hRead, hWrite, @saSecurity, 0) then
Ich habe Windows 10 und Berlin.
ist CreatePipe auch verändert worden?

DANKE

himitsu 28. Jul 2020 18:24

AW: cmd output in memo - Bug
 
Seit 2009 ist Delphi standardmäßig auf Unicode

string = UnicodeString (vorher AnsiString)
Char = WideChar (vorher AnsiChar)
PChar = PWideChar (vorher PAnsiChar)

CreatePipe zeigt nun eben auf CreatePipeW, wo es früher CreatePipeA war,
so wie fast alle WinAPI, sowie die RTL, VCL usw., die in Delphi mitgeliefert werden.

Jeder Code, der in damaligen Compilern fahrlässig mit compilierabhängigen Typen geschrieben wurde
und vor allem wo auch noch dynamische mit statischen Typen gemischt werden,
ist nun fehlerhaft, weil sich eben diese Typen geändert haben.



Man kann nun als Bugfix erstmal alles wieder auf ANSI zurückbringen
oder man schaut, wo es Unicode gibt und bringt es in einen aktuelleren Zustand.
So oder so, man muß es eben "zusamenhängend" mit den zusammenpassenden Typen und APIs entweder fix auf ANSI oder Unicode bringen.

wschrabi 28. Jul 2020 18:49

AW: cmd output in memo - Bug
 
Ja DANKE, so hab ich es mir auch gedacht.
Aber CreatePipeA findet er überhaupt nicht.
muss ich da eine Unit einbinden?
DANKE HERZLICHST:

hier sind aber alle paramter da laut IDE Unterstuützung bei CreatePipe.

Vielleicht hilf das, aber ich kenne mich nicht aus: https://stackoverflow.com/questions/...command-prompt


mfg
w

himitsu 28. Jul 2020 19:03

AW: cmd output in memo - Bug
 
Ups, falsch geguckt. Dachte im TSecurityAttributes gibt es auch ein paar "Char".
Wenn die API keine Chars als Parameter oder in Records hat, dann braucht man sie natürlich nicht doppelt. :oops:

Microsoft kam auf die geile IDE seine Webseite umzubauen, so funktionieren viele Links nicht mehr. :wall:
https://docs.microsoft.com/en-us/win...api-createpipe
https://docs.microsoft.com/en-us/pre...79560(v=vs.85) = toter Link
https://docs.microsoft.com/en-us/pre...79560(v=vs.85) = richtig

anderes Beispiel, was dich aber betrifft (CreateProcessA)
https://docs.microsoft.com/en-us/win...createprocessa
wobei hier nun "alles" mit W, weil ja jetzt unicode, aber da dein ACommand und AParameters Strings und keine UnicodeStrings sind, hier natürlich "alles" dynamisch und ohne A oder W.
Und natürlich muß auch OemToAnsi unbedingt als ANSI implementiert werden, A) weil ANSI ankommt und B) weil man bei der Unicode-Version mit den Parametern aufpassen muß, denn dort ist es verboten inplace übersetzen zu lassen, also niemals mit dem selben Ein- und Ausgabepuffer.

Alles was pBuffer betrifft muß ANSI sein, vor der Übersetung OEM to ANSI (ich weiß, aber OEM ist auch eine ANSI-Codepage und mit "ToANSI" ist hier die lokale ANSI-Codepage gemeint)
Aber ich würde statt MSDN-Library durchsuchenOemToAnsi empfehlen TMBCSEncoding.Create(437, 0, 0) oder TEncoding.GetEncoding(437) zu verwenden.
https://docs.microsoft.com/en-us/win...ntl/code-pages


Allerdings kommt es auch drauf an, was für eine ANSI-Codepage wirklich aus dem Programm kommt,
denn das kann OEM, ANSI, UTF-8 oder sonstwas sein,
somit wäre es bestimmt intelligent die CP_OEM (437) nicht direkt zu übergeben, sondern als Parameter. :zwinker:

Dalai 28. Jul 2020 19:06

AW: cmd output in memo - Bug
 
Zitat:

Zitat von wschrabi (Beitrag 1470611)
doch leider bekomme ich in zeile
Delphi-Quellcode:
   if CreatePipe(hRead, hWrite, @saSecurity, 0) then
Diesen Error:
Delphi-Quellcode:
[dcc64 Fehler] BUnit1.pas(1313): E2010 Inkompatible Typen: 'PAnsiChar' und 'array[0..2400] of Char'

Da passt etwas nicht, denn in der Zeile mit CreatePipe ist nichts in Richtung P(Ansi)Char oder array of Char zu finden, weil diese Funktion gar keinen Stringtypen als Parameter hat. Vermutlich meinst du die Zeile mit ReadFile oder OemToAnsi, halt irgendetwas wo PChar oder array of Char verwendet wird. Bitte genaue Beschreibungen posten, sonst sucht man an der völlig falschen Stelle und vergeudet dabei Zeit, deine und die der Helfer.

Grüße
Dalai


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:34 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz