AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi [createprocess] cmd.exe liefert exitcode 1 ohne Debugger?!
Thema durchsuchen
Ansicht
Themen-Optionen

[createprocess] cmd.exe liefert exitcode 1 ohne Debugger?!

Ein Thema von alleinherrscher · begonnen am 12. Mär 2009 · letzter Beitrag vom 13. Mär 2009
Antwort Antwort
Benutzerbild von alleinherrscher
alleinherrscher

Registriert seit: 8. Jul 2004
Ort: Aachen
797 Beiträge
 
Delphi XE2 Professional
 
#1

[createprocess] cmd.exe liefert exitcode 1 ohne Debugger?!

  Alt 12. Mär 2009, 14:01
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)='EXITthen
    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.
„Software wird schneller langsamer als Hardware schneller wird. “ (Niklaus Wirth, 1995)

Mein Netzwerktool: Lan.FS
  Mit Zitat antworten Zitat
Benutzerbild von alleinherrscher
alleinherrscher

Registriert seit: 8. Jul 2004
Ort: Aachen
797 Beiträge
 
Delphi XE2 Professional
 
#2

Re: [createprocess] cmd.exe liefert exitcode 1 ohne Debugger

  Alt 13. Mär 2009, 12:10
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 !!! 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
Angehängte Dateien
Dateityp: rar redirectconsole_167.rar (176,2 KB, 47x aufgerufen)
„Software wird schneller langsamer als Hardware schneller wird. “ (Niklaus Wirth, 1995)

Mein Netzwerktool: Lan.FS
  Mit Zitat antworten Zitat
Antwort Antwort


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 01:58 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