CreateProcess wirft Kernelbase Error
Wenn ich CreateProcess ohne UniqueString aufrufe wirft es einen Kernelbase Error.
Rufe ich es mit auf sind die Strings nicht lesbar.
Delphi-Quellcode:
Warum?
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; |
AW: CreateProcess wirft Kernelbase Error
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; |
AW: CreateProcess wirft Kernelbase Error
Zitat:
Ich glaube das die Rückgabe mit Utf8ToString übergeben werden muß. PWideChar scheint kein "writable string" zu sein. werde das mal testen. |
AW: CreateProcess wirft Kernelbase Error
Jo.
Zitat:
Doch kann es, falls Konstante rein kommt. (nur bei Commands[1]=' ' wird es immer eine Variable) Tipp:
Delphi-Quellcode:
als erste Zeile einfügen.
UniqueString(Commands);
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? |
AW: CreateProcess wirft Kernelbase Error
Zitat:
Ich habe es jetzt mal so gemacht aber leider schmiert die Anwendung wieder ab mit EAccessViolation Obwohl der Text jetzt korrekt zu lesen ist.
Delphi-Quellcode:
Callback( ReadPipe(StdIO), Input, Terminate, PI, UserData);
Delphi-Quellcode:
TIOPipe = record hRead, hWrite: DWORD; end; TStdIO = record stdIn, stdOut, stdError: TIOPipe; end;
Delphi-Quellcode:
so läuft es durch aber der Text ist dann nicht zu lesen.
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;
Delphi-Quellcode:
Finde den Fehler nicht warum es mit einem Array of AnsiString abschmiert.
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; Zitat:
|
AW: CreateProcess wirft Kernelbase Error
Ich hatte oben noch bissl was geändert. :opps:
Vorallem siehe "Tipp" |
AW: CreateProcess wirft Kernelbase Error
Zitat:
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; |
AW: CreateProcess wirft Kernelbase Error
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. |
AW: CreateProcess wirft Kernelbase Error
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. |
AW: CreateProcess wirft Kernelbase Error
Zitat:
Danke für das reinschauen. Ich habe das Array auf 255 gesetzt. |
AW: CreateProcess wirft Kernelbase Error
So geht's.. (Aber lahm, selbe Problem mit der Batch Datei)
@KodeZwerg Kannst ja mit der alten vergleichen wenn du bock drauf hast :) Nebenbei man kann auch auf UniqueString(CommandLine); verzichten wenn man pchar(CommandLine) so definiert. pchar(WideString(CommandLine)) Interessant wäre hier eine Art Progressbar (Man sieht nicht wirklich das sich etwas tut) aber ich sehe nicht wo man hier ansetzen kann. Kenne die max. Durchläufe nicht. Thema erledigt |
AW: CreateProcess wirft Kernelbase Error
Hier noch eine kleine Animation damit man überhaupt etwas sieht das sich was tut.
Function einfach ersetzen.
Delphi-Quellcode:
Ok gut mit den Spielereien war nur ein Test Projekt für meinen Video Player.
Function ReadPipe(StdIo: TStdIO): AnsiString;
var bAvailable: DWORD; Buffer: PAnsiChar; begin if StdIo.stdOut.hRead <> INVALID_HANDLE_VALUE then begin bAvailable := 0; // First, check the size of the current pipe buffer PeekNamedPipe(StdIo.stdOut.hRead, nil, 0, nil, @bAvailable, nil); // if there is data waiting, fetch it if bAvailable > 0 then begin // set the new length of the result and initialize it Buffer := PAnsiChar(StrAlloc(bAvailable + 1)); try ZeroMemory(Buffer, bAvailable + 1); // Read all data from the pipe ReadFile(StdIo.stdOut.hRead, Buffer^, bAvailable, bAvailable, nil); SetLength(result, bAvailable); CopyMemory(PAnsiChar(result), Buffer, bAvailable); finally StrDispose(Buffer); end; end else begin result := result + '.'; // <<<<<<<< Animation sleep(200); if length(Result) > 63 then Result := ''; end; end else result := ''; end; Eine perfekte Fortschrittanzeige läßt sich leider nicht realisieren. |
AW: CreateProcess wirft Kernelbase Error
Zitat:
Ich habe mir gerade mal diese youtube-dl.exe geladen, die hat ja reichlich parameter. Mann-o-mann. Kannst Du mir bitte anhand eines Kommandozeilen Befehls zeigen was du dann übergibst um alles in Gang zu bringen? Damit es keine Mißverständisse gibt, sowas meine ich
Delphi-Quellcode:
usw.
c:\youtube\youtube-dl.exe argument1 argument2
Danke und vorab Frohe Ostern! |
AW: CreateProcess wirft Kernelbase Error
Pfad wo sich die exe befindet.
Delphi-Quellcode:
folderyoutube := ExtractFilePath(ParamStr(0)) + 'youtube-dl.exe';
Argument.
Delphi-Quellcode:
folderyoutube + ' -U'
aktualisiert das Exe File Zitat:
Zitat:
Habe da noch ein Problem
Delphi-Quellcode:
Das Handle PI.dwProcessId sollte eigentlich in Ordnung sein wirft aber einen Fehler 'Das Handle ist ungültig'
if not GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, Stophandle{PI.dwProcessId}) then
begin Aber ist ein anderes Thema. |
AW: CreateProcess wirft Kernelbase Error
Zitat:
Zitat:
Delphi-Quellcode:
probiert?
GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, 0)
Wenn die Sterne gut stehen habe ich morgen auch ein paar Demos startklar. |
AW: CreateProcess wirft Kernelbase Error
Zitat:
|
AW: CreateProcess wirft Kernelbase Error
Zitat:
Öffne cmd.exe mit Adminrechten und Paste das da rein. Zitat:
Das geht flott aber die Aktualisierung der EXE selber leider nicht. Zitat:
Fortschrittanzeige kannst du so verwirklichen. Aber wie ich schon sagte ich benötige es nicht.
Delphi-Quellcode:
function ExtractTextBetween(const Input, Delim1, Delim2: string): string;
var aPos, bPos: Integer; begin result := ''; aPos := Pos(Delim1, Input); if aPos > 0 then begin bPos := PosEx(Delim2, Input, aPos + Length(Delim1)); if bPos > 0 then result := Copy(Input, aPos + Length(Delim1), bPos - (aPos + Length(Delim1))); end; end;
Delphi-Quellcode:
function GetPercentofVideo(str: String; lastpercent: integer): Integer;
var temp:String; itemp:integer; test:integer; begin temp := ExtractTextBetween(str,'[download]','% of'); try temp := trim(temp); Val(temp,itemp,test); Result := round(itemp); except Result := lastpercent; end; end;
Delphi-Quellcode:
Du kannst mein Projekt damit aktualisieren zum testen.
aForm.RichEdit1.Text := Output + aForm.RichEdit1.Text;
tmpPercent := GetPercentofVideo(aForm.RichEdit1.Text, percent); percent := tmpPercent; aForm.ProgressBar1.Position := percent; |
AW: CreateProcess wirft Kernelbase Error
Zitat:
Danke für Deine Erklärung wie man es aufruft um was zu erhalten, hatte ich eigentlich nur für Dich benötigt, hat sich ja von selbst erledigt. (auf cmd ebene nutz ich was für mich besseres, yaydl (hier findet man eine .exe davon), das hat zwar hier und da ein paar macken, aber läuft ordentlich) auf browser ebene macht es ein plugin, auf Programm ebene nutze ich einen download manager.) Mein Gedanke war halt, weil Du was von einer progress anzeige meintest, das Du tatsächlich was laden wolltest. So krass vertan hab ich mich ja schon lange nicht mehr. Coole Methode ExtractTextBetween(), ich hätte wahrscheinlich den Ansipuffer von der Konsole verwendet um da per Laufzeit was zu regeln, wieder dazu gelernt! Die Zeit den Update zu beschleunigen, da fällt mir nichts ein, ich habe es zwar schon minimal beschleunigt da ich die Python Skripte direkt nutze, nicht die .exe, aber Python reinladen und das ausführen zu lassen dauert seine Zeit. (Die Update Prozedur schlingelt sich leider durch fast alle Skripte durch) Für mich war halt die Herausforderung sehr Interessant mal wieder was Sinnvolles mit Pipes anzustellen. Wenn es nur ums Update geht würde ich gar nichts darstellen lassen, ein freundliches label "background update in progress" und den im Hintergrund-Thread machen lassen, ob es eine Sekunde oder Stunde dauert kann Dir doch dann egal sein, es liegt ja nicht an Dir. (Man kann ja eine Kopie starten falls während des updates noch ein Aufruf erfolgt.) Aber da Du nicht ich bist, hast Du ja eh vollkommen andere Pläne, die ich respektiere. Nächste Woche lese ich mir alles nochmal durch, update alles so wie Du beschrieben hast. Danke für die mehr-Arbeit mit der progress anzeige. 2 1/2 verschiedene Wege mit Pipes zu arbeiten habe ich bereits erarbeitet, leider nichts was mehr speed beim ausführen bringt, nur verschiedene Wege um ans Ziel zu kommen. |
AW: CreateProcess wirft Kernelbase Error
Zitat:
Wie Ich schon sagte da hilft auch keine Batch ohne Code. Warum man da keine Fortschrittanzeige implementiert hat beim OutPut ist mir auch ein Rätzel. Aber solange die Animation läuft sehe ich wenigstens das sich überhaupt was tut. Zitat:
|
AW: CreateProcess wirft Kernelbase Error
Hier ist ein Update mit oben genannten Änderungen.
Url kopieren mit linker Maustaste ins Edit klicken der Rest erklärt sich von selbst. Sorry mehr mache ich nicht. In meinen Player übernimmt das der Wrapper für Youtube 3DYDYoutube von daher benötige ich es nicht. |
AW: CreateProcess wirft Kernelbase Error
Geiles Ding das Du das komplette Projekt nochmal bereit stellst *sag brav danke dafür* :cheer::thumb:
Aber ich frage mich ob da was falsch lief, der Inhalt vom letzten Archiv entspricht dem vom vorletzten (gleicher archivname)? (mein fehler, downloader hat datei mehrmals geladen...) Beim nochmal drüber nachdenken, Geschwindigkeit der Ausführung von youzube-dl.exe, vielleicht gibt es da doch was. Ich wage mich jetzt auf extrem dünnes Eis da ich das Produkt nicht kenne, nur nebenbei mal was von gehört habe. Es gibt ein Projekt was sich "PythonForPascal" oder "Phyton4Pascal" oder ähnlich nennt. Wenn das Projekt Python-Skripte ausführen kann, könntest du vielleicht doch noch bisschen zeit einkaufen indem du beim start schonmal python im Hintergrund hochfährst. Das ist es was bei der youtube-dl.exe Datei am längsten dauert, interpreter bereitstellen. Wenn das Projekt wiederum eher ein Konverter ist (python <-> pascal) dann denk ich mal vergiss diese Zeilen ganz schnell wieder. (Idee ab in Keller, Schloss zu, Schlüssel putt machen) Ich habe gerade leider keinen Link dazu parat, sonst hätte ich schonmal selbst was gelesen. |
AW: CreateProcess wirft Kernelbase Error
Zitat:
Inklusive Progressbar und Download Möglichkeit. Zitat:
Würde ich es so machen wie du denkst müßte ich Python auf meinem System installieren. |
AW: CreateProcess wirft Kernelbase Error
Zitat:
Zitat:
So, nun habe ich Dich genug belästigt und werde mich dem Sonntag zuwenden ;-) |
AW: CreateProcess wirft Kernelbase Error
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:35 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