![]() |
[createprocess] cmd.exe liefert exitcode 1 ohne Debugger?!
Hi@all!
Ich benutze den unten angehängten Code, um cmd-eingaben in mein programm umzuleiten. Der Code stammt ausm Internet, allerdings hab ich ihn dahingehend umgeschrieben, alsdass beim beenden der cmd.exe alle childprocesses mitgeschlossen werden.) Wenn ich mein Programm mit Delphi 2005 starte (mit Debugger) läuft es ohne Probleme, der Prozess cmd.exe wird erstellt und die ausgabe in mein programm umgeleitet. Zum Schluss (z.B. bei eingabe von "exit") terminiert die cmd.exe mit exitcode 0. Also alles perfekt. Wenn ich dann jedoch das Programm ohne den Debugger aus windows starte, erzeugt createprocess wie gewünscht die cmd.exe, diese beendet sich aber dann sofort mit Exitcode 1. MSDN sagt dazu: "Partial success; this means at least something, or possibly everything, failed to succeed." Jemand den Hauch einer Ahnung, woran das liegen kann???
Delphi-Quellcode:
/////////////////////////////////////////////////////
// // // UNiT REDiRECT CONSOLE by SONiC // // // // Console input/output redirection with pipes // // Last revision: 02/SEPT/02 // // // // Bugs/comments to: [email]Sonic1980@msn.com[/email] // // Home page: [url]http://sonic.rulestheweb.com[/url] // // // // Freeware // // // ///////////////////////////////////////////////////// unit RedirectConsole; interface uses Windows, Messages, SysUtils, StdCtrls,Forms,TlHelp32,Dialogs; const CRLF=#13#10; var RC_SendBuf: string; RC_End: Boolean; RC_ExitCode: Cardinal; ExeName:string; procedure RC_Run(Command: string); procedure RC_LineIn(s: string); var RC_LineOut: procedure(s: string)of object; implementation //uses Windows, Forms; function KillChildProcesses(ProcessID:Cardinal;NameFilter:string): boolean; var p: TProcessEntry32; h: THandle; begin Result := false; p.dwSize := SizeOf(p); h := CreateToolHelp32Snapshot(TH32CS_SnapProcess, 0); try if Process32First(h, p) then repeat if p.th32ParentProcessID=ProcessID then begin if (NameFilter='') or (AnsiLowerCase(p.szExeFile) = AnsiLowerCase(trim(NameFilter))) then begin KillChildProcesses(p.th32ProcessID,''); Result := TerminateProcess(OpenProcess(Process_Terminate,false,p.th32ProcessID),0); end; end; until (not Process32Next(h, p)); finally CloseHandle(h); end; end; procedure RC_LineIn(s: string); begin if uppercase(s)='EXIT' then killchildprocesses(GetCurrentProcessId,ExeName) else RC_SendBuf:=RC_SendBuf+s+CRLF; end; // RC_LineIn; function IsWinNT: Boolean; var osv: tOSVERSIONINFO; begin osv.dwOSVersionInfoSize:=sizeof(osv); GetVersionEx(osv); result:=osv.dwPlatformID=VER_PLATFORM_WIN32_NT; end; // IsWinNT procedure SplitLines(s: string); var t: string; begin while pos(CRLF, s)<>0 do begin t:=copy(s, 1, pos(CRLF, s)-1); RC_LineOut(t); delete(s, 1, pos(CRLF, s)+1); end; if length(s)>0 then RC_LineOut(s); end; // SplitLines procedure RC_Run(Command: string); const bufsize=1024; // 1KByte buffer var buf: array [0..bufsize-1] of char; si: tSTARTUPINFO; sa: tSECURITYATTRIBUTES; sd: tSECURITYDESCRIPTOR; pi: tPROCESSINFORMATION; newstdin, newstdout, read_stdout, write_stdin: tHandle; bread, avail: dword; begin // Configuraciones de seguridad para WinNT if IsWinNT then begin InitializeSecurityDescriptor(@sd, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(@sd, true, nil, false); sa.lpSecurityDescriptor:=@sd; end else sa.lpSecurityDescriptor:=nil; // Creamos Pipe A if not CreatePipe(newstdin, write_stdin, @sa, 0) then begin RC_LineOut('Error creating Pipe A'); exit; end; // Creamos Pipe B if not CreatePipe(read_stdout, newstdout, @sa, 0) then begin RC_LineOut('Error creating Pipe B'); CloseHandle(newstdin); CloseHandle(write_stdin); exit; end; // Configuramos si GetStartupInfo(si); si.dwFlags:= STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW; si.wShowWindow:=SW_HIDE; si.hStdOutput:=newstdout; si.hStdError:=newstdout; si.hStdInput:=newstdin; // Creamos proceso ExeName:=extractfilename(command); application.processmessages; if not CreateProcess(pchar(command), nil,nil, nil, true, CREATE_NEW_CONSOLE, nil, nil, si, pi) then begin RC_LineOut('Error creating process: '+command); CloseHandle(newstdin); CloseHandle(newstdout); CloseHandle(read_stdout); CloseHandle(write_stdin); exit; end; // Loop principal fillchar(buf, sizeof(buf), 0); RC_End:=false; RC_SendBuf:=''; repeat application.ProcessMessages; sleep(50); // Application.HandleMessage; GetExitCodeProcess(pi.hProcess, RC_ExitCode); if (RC_ExitCode<>STILL_ACTIVE) then RC_End:=True; PeekNamedPipe(read_stdout, @buf, bufsize, @bread, @avail, nil); // Comprobamos texto de salida if (bread<>0) then begin fillchar(buf, bufsize, 0); if (avail>bufsize) then while (bread>=bufsize) do begin ReadFile(read_stdout, buf, bufsize, bread, nil); SplitLines(buf); fillchar(buf, bufsize, 0); end else begin ReadFile(read_stdout, buf, bufsize, bread, nil); SplitLines(buf); end; end; // Comprobamos texto de entrada while (Length(RC_SendBuf)>0) do begin WriteFile(write_stdin, RC_SendBuf[1], 1, bread, nil); Delete(RC_SendBuf, 1, 1); end; until RC_End; // Cerramos las cosas Showmessage(inttostr(RC_ExitCode)); CloseHandle(pi.hThread); CloseHandle(pi.hProcess); CloseHandle(newstdin); CloseHandle(newstdout); CloseHandle(read_stdout); CloseHandle(write_stdin); end; // RC_Run end. |
Re: [createprocess] cmd.exe liefert exitcode 1 ohne Debugger
Liste der Anhänge anzeigen (Anzahl: 1)
Ich hab inzwischen mal eine kleine Testapplikation geschrieben. Interessanter Weise funktioniert diese SOWOHL in der IDE, als auch hinterher in Windows. (Der Quellcode ist Identisch zu dem anderen Programm, bei dem es nicht funktioniert). Also ich versteh das nicht :wall: !!! Warum funktioniert es in meinem anderen Programm nicht? Kann es sein, dass es etwas damit zu tun hat, dass mein Programm die cmd.exe erstellen will, nachdem es über eine TCP/IP Verbindung eine Aufforderung dazu bekommen hat, und dass M$ da irgendwas gefummelt hat, damit das untersagt wird (zwecks Trojaner o.Ä.)???
Grüße, Michael |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:35 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz