AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein CreateProcess wirft Kernelbase Error
Thema durchsuchen
Ansicht
Themen-Optionen

CreateProcess wirft Kernelbase Error

Ein Thema von venice2 · begonnen am 2. Apr 2021 · letzter Beitrag vom 4. Apr 2021
Antwort Antwort
Seite 1 von 3  1 23      
venice2
(Gast)

n/a Beiträge
 
#1

CreateProcess wirft Kernelbase Error

  Alt 2. Apr 2021, 13:46
Wenn ich CreateProcess ohne UniqueString aufrufe wirft es einen Kernelbase Error.
Rufe ich es mit auf sind die Strings nicht lesbar.

Delphi-Quellcode:
function PipeExec(CommandLine, Path: String; EnvironementStrings: PChar; var StdIO: TStdIO; UserToken: THandle; ShowWindow: DWORD = SW_HIDE): TProcessInformation;

  UniqueString(CommandLine);

  if UserToken = 0 then
  begin
    if not CreateProcess( nil, // must be NIL for win16 apps under NT, including DOS progs
                   pchar(CommandLine),
                   nil, // Process security attibutes. Sue same as current
                   nil, // Thread security attibutes. Sue same as current
                   true, // Inherite handles. Must be true for IO redirection
                   ProcessCreationFlags, // creation flags
                   EnvironementStrings, // If using with a CGI aplication, you MUST pass the HTTP headers as env. strings in this variable
                   PathPChar, // Directory of the new process
                   SI, // SISTEMINFO Structure used to initialize the new process
                   result) // PROCESINFORMATION structure used to control the newly created process
    then
      RaiseLastOSError;
Warum?
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: CreateProcess wirft Kernelbase Error

  Alt 2. Apr 2021, 14:14
Ich weiß nicht direkt worin das problem besteht aber ich nutze es auch eher wie es hier beschrieben wird.
Also schon das erste Argument zu füllen.
Falls es hilft, so nutze ich es beispielsweise:
Delphi-Quellcode:
function ExecuteExe(const Executable: String; Commands: String; const ShowConsole, DoWait: Boolean): Cardinal;
  procedure WaitFor(processHandle: THandle);
  var
    Msg: TMsg;
    ret: DWORD;
  begin
    repeat
      ret := MsgWaitForMultipleObjects(1, { 1 handle to wait on }
              processHandle, { the handle }
              False, { wake on any event }
              INFINITE, { wait without timeout }
              QS_PAINT or { wake on paint messages }
              QS_SENDMESSAGE { or messages from other threads }
             );
      if ret = WAIT_FAILED then Exit; { can do little here }
      if ret = (WAIT_OBJECT_0 + 1) then
      begin
      while PeekMessage(Msg, 0, WM_PAINT, WM_PAINT, PM_REMOVE) do
          DispatchMessage(Msg);
      end;
    until ret = WAIT_OBJECT_0;
  end; { Waitfor }
var
  Security : TSecurityAttributes;
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
begin
 Result := Cardinal($FFFFFFFF);
 if ((Length(Commands) > 1) and (Commands[1]<>' ')) then
   Commands := ' ' + Commands;
 with Security do begin
   nLength := SizeOf(TSecurityAttributes);
   lpSecurityDescriptor := nil;
   bInheritHandle := False;
 end;
  FillChar(StartupInfo, SizeOf(StartupInfo), #0);
  StartupInfo.cb := SizeOf(StartupInfo);
  StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK;
  if ShowConsole then StartupInfo.wShowWindow := SW_SHOWNORMAL else StartupInfo.wShowWindow := SW_HIDE;
  if CreateProcess(PChar(Executable), PChar(Commands), @Security, @Security, False, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, PChar(ExtractFilePath(Executable)), StartupInfo, ProcessInfo) then
  begin
   if DoWait then WaitFor(ProcessInfo.hProcess);
   if not GetExitCodeProcess(ProcessInfo.hProcess, Result) then Result := Cardinal($FFFFFFFF);
    CloseHandle(ProcessInfo.hThread);
    CloseHandle(ProcessInfo.hProcess);
  end
  else
    Result := GetLastError;
end;
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
venice2
(Gast)

n/a Beiträge
 
#3

AW: CreateProcess wirft Kernelbase Error

  Alt 2. Apr 2021, 14:20
Zitat:
Before calling CreateProcess you have to guarantee that "FileName" is a
writable string. That can be done with the System function
UniqueString().
Ich verwende Pipe und sende mit UniqueString einen AnsiString obwohl CommandLine als PWideChar übergeben wird.
Ich glaube das die Rückgabe mit Utf8ToString übergeben werden muß.

PWideChar scheint kein "writable string" zu sein.


werde das mal testen.

Geändert von venice2 ( 2. Apr 2021 um 14:49 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.071 Beiträge
 
Delphi 12 Athens
 
#4

AW: CreateProcess wirft Kernelbase Error

  Alt 2. Apr 2021, 16:21
Jo.

Zitat:
lpCommangLine

...
The Unicode version of this function, CreateProcessW, can modify the contents of this string. Therefore, this parameter cannot be a pointer to read-only memory (such as a const variable or a literal string). If this parameter is a constant string, the function may cause an access violation.
ReadOnly ist er zwar nicht, da Variable, aber vielleicht zu klein?
Doch kann es, falls Konstante rein kommt. (nur bei Commands[1]=' ' wird es immer eine Variable)
Tipp: UniqueString(Commands); als erste Zeile einfügen.

PChar/PWideChar/PAnsiChar aus einem String/WideString/UnicodeString/AnsiString
is bei '' immer nicht "writeable" und auch nicht wenn es er aus einer Constante gibt. (OK, Stringkonstanten sind zwar nur "schreibgeschützte" Variablen, aber dennoch)


Warum leere "Security" anstatt NIL an die Funktion?
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu ( 2. Apr 2021 um 16:32 Uhr)
  Mit Zitat antworten Zitat
venice2
(Gast)

n/a Beiträge
 
#5

AW: CreateProcess wirft Kernelbase Error

  Alt 2. Apr 2021, 16:31
Jo.

Zitat:
lpCommangLine

...
The Unicode version of this function, CreateProcessW, can modify the contents of this string. Therefore, this parameter cannot be a pointer to read-only memory (such as a const variable or a literal string). If this parameter is a constant string, the function may cause an access violation.
ReadOnly ist er zwar nicht, da Variable, aber vielleicht zu klein?

PChar/PWideChar/PAnsiChar aus einem String/WideString/UnicodeString/AnsiString
is bei '' immer nicht "writeable" und auch nicht wenn es er aus einer Constante gibt. (OK, Stringkonstanten sind zwar nur "schreibgeschützte" Variablen, aber dennoch)
Zu klein nein BufferSize ist 38


Ich habe es jetzt mal so gemacht aber leider schmiert die Anwendung wieder ab mit EAccessViolation
Obwohl der Text jetzt korrekt zu lesen ist.
Callback( ReadPipe(StdIO), Input, Terminate, PI, UserData);
Delphi-Quellcode:
 
  TIOPipe = record
    hRead,
    hWrite: DWORD;
  end;
 
  TStdIO = record
    stdIn,
    stdOut,
    stdError: TIOPipe;
  end;
Delphi-Quellcode:
Function ReadPipe(StdIo: TStdIO): string;
var
  BufferSize: DWORD;
  Buffer: array [0..255] of AnsiChar;

begin
  if StdIO.stdOut.hRead <> INVALID_HANDLE_VALUE then
  begin
    BufferSize := 0;
    // First, check the size of the current pipe buffer
    PeekNamedPipe( StdIO.stdOut.hRead,
                   nil,
                   0,
                   nil,
                   @BufferSize,
                   nil);
    // if there is data waiting, fetch it
    if BufferSize > 0 then
    begin
      try
        ZeroMemory(@Buffer, BufferSize + 1);
        // Read all data from the pipe
        ReadFile(StdIO.stdOut.hRead, Buffer, BufferSize, BufferSize, nil);
        SetLength(Result, BufferSize);
        CopyMemory(@Result, @Buffer, BufferSize);
      finally
        StrDispose(Buffer);
      end;
    end
    else
      Result := '';
  end
  else
    Result := '';
end;
so läuft es durch aber der Text ist dann nicht zu lesen.
Delphi-Quellcode:
Function ReadPipe(StdIo: TStdIO): string;
var
  BufferSize: DWORD;
  Buffer: PChar;
begin
  if StdIO.stdOut.hRead <> INVALID_HANDLE_VALUE then
  begin
    BufferSize := 0;
    // First, check the size of the current pipe buffer
    PeekNamedPipe( StdIO.stdOut.hRead,
                   nil,
                   0,
                   nil,
                   @BufferSize,
                   nil);
    // if there is data waiting, fetch it
    if BufferSize > 0 then
    begin
      // set the new length of the result and initialize it
      Buffer := StrAlloc(BufferSize + 1);
      try
        ZeroMemory(Buffer, BufferSize + 1);
        // Read all data from the pipe
        ReadFile(StdIO.stdOut.hRead, Buffer^, BufferSize, BufferSize, nil);
        SetLength(Result, BufferSize);
        CopyMemory(PChar(Result), Buffer, BufferSize);
      finally
        StrDispose(Buffer);
      end;
    end
    else
      Result := '';
  end
  else
    Result := '';
end;
Finde den Fehler nicht warum es mit einem Array of AnsiString abschmiert.

Zitat:
Warum leere "Security" anstatt NIL an die Funktion?
Ist nicht von mir.

Geändert von venice2 ( 2. Apr 2021 um 16:38 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.071 Beiträge
 
Delphi 12 Athens
 
#6

AW: CreateProcess wirft Kernelbase Error

  Alt 2. Apr 2021, 16:33
Ich hatte oben noch bissl was geändert. pps:

Vorallem siehe "Tipp"
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
venice2
(Gast)

n/a Beiträge
 
#7

AW: CreateProcess wirft Kernelbase Error

  Alt 2. Apr 2021, 16:40
Ich hatte oben noch bissl was geändert. pps:

Vorallem siehe "Tipp"
Habe ich

Delphi-Quellcode:
function PipeExec(CommandLine, Path: String; EnvironementStrings: PChar; var StdIO: TStdIO; UserToken: THandle; ShowWindow: DWORD = SW_HIDE): TProcessInformation;
const
  ProcessCreationFlags: DWord = NORMAL_PRIORITY_CLASS;
var
  SI : TStartupInfo;
  PathPChar : PChar;
begin
  // initialize the structure we are going to use
  Zeromemory(@SI, SizeOf(SI));
  Zeromemory(@result, SizeOf(result));
  // Fill the necessary fields
  SI.cb := sizeof(SI); // Size of the structure. The OS uses that to validat it
  SI.dwFlags := STARTF_USESHOWWINDOW   or // Use the wShowWindow field
                 STARTF_USESTDHANDLES; // use the handles we created for the std IO pipes
  SI.wShowWindow := ShowWindow; // Show the console or not...
  SI.hStdError := StdIO.stdError.hWrite; // Write errors to the error pipe
  SI.hStdInput := StdIO.stdIn.hRead; // read input from input pipe
  SI.hStdOutput := StdIO.stdOut.hWrite; // Write Ouput to output pipe

  if length(path) > 0 then
     PathPChar := PChar(Path)
  else
      PathPChar := nil;

  UniqueString(CommandLine); //<<<<<<< Hier!

  if UserToken = 0 then
  begin
    if not CreateProcess( nil, // must be NIL for win16 apps under NT, including DOS progs
                   pchar(CommandLine),
                   nil, // Process security attibutes. Sue same as current
                   nil, // Thread security attibutes. Sue same as current
                   true, // Inherite handles. Must be true for IO redirection
                   ProcessCreationFlags, // creation flags
                   EnvironementStrings, // If using with a CGI aplication, you MUST pass the HTTP headers as env. strings in this variable
                   PathPChar, // Directory of the new process
                   SI, // SISTEMINFO Structure used to initialize the new process
                   result) // PROCESINFORMATION structure used to control the newly created process
    then
      RaiseLastOSError;
  end
  else
  begin
    if not CreateProcessAsUser( UserToken, // UserToken of desired user. That token must be retreived with LogonUser or DuplicatteToken from a Impersonation token
                         nil, // must be NIL for win16 apps under NT, including DOS progs
                         pchar(CommandLine),
                         nil, // Process security attibutes. Sue same as current
                         nil, // Thread security attibutes. Sue same as current
                         true, // Inherite handles. Must be true for IO redirection
                         ProcessCreationFlags, // creation flags
                         EnvironementStrings, // If using with a CGI aplication, you MUST pass the HTTP headers as env. strings in this variable
                         PathPChar, // Directory of the new process
                         SI, // SISTEMINFO Structure used to initialize the new process
                         result) // PROCESINFORMATION structure used to control the newly created process
    then
      RaiseLastOSError;
  end;
end;
  Mit Zitat antworten Zitat
venice2
(Gast)

n/a Beiträge
 
#8

AW: CreateProcess wirft Kernelbase Error

  Alt 2. Apr 2021, 17:43
Hänge das Projekt mal an falls jemand reinschauen möchte.
Es soll nichts anderes machen als die youtube-dl.exe über "Pipe" zu aktualisieren.

Achtung diese Datei ist nicht im Archiv.

Die Auskommentierte "Function ReadPipe" funktioniert ist aber nicht lesbar (Bild Auskommentierte Funktion)
Die Aktivierte Funktion läßt die Anwendung abstürzen.

Das Update zu erhalten dauert einige zeit warum das so langsam ist keine Ahnung! (gleiche mit der *.bat)
Ist nichts besonderes nur ein Test Projekt.

Wenn alle Stricke reißen mache ich es einfach über eine Batch Datei.

Geändert von venice2 ( 4. Apr 2021 um 16:46 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: CreateProcess wirft Kernelbase Error

  Alt 2. Apr 2021, 18:12
Ich schau mal rein (code), mein erster Gedanke ist, der Puffer ist viel zu klein. Als ich eine Cmd.exe über Pipes umlenkte, brauchte ich schlapp 35kb an puffer.
Mal sehen ob ich richtig nachvollziehen kann was Du da vorhast und eventuell sogar hilfreich sein kann.
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
venice2
(Gast)

n/a Beiträge
 
#10

AW: CreateProcess wirft Kernelbase Error

  Alt 2. Apr 2021, 18:14
Ich schau mal rein (code), mein erster Gedanke ist, der Puffer ist viel zu klein. Als ich eine Cmd.exe über Pipes umlenkte, brauchte ich schlapp 35kb an puffer.
Mal sehen ob ich richtig nachvollziehen kann was Du da vorhast und eventuell sogar hilfreich sein kann.
Der Buffer wird gesetzt an Hand vom BufferSize und der ist 38!
Danke für das reinschauen.

Ich habe das Array auf 255 gesetzt.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:36 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