Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Salida de msdos en delhpi 2010 (https://www.clubdelphi.com/foros/showthread.php?t=66224)

xerkan 08-02-2010 17:16:32

Salida de msdos en delhpi 2010
 
Me gustaria saber si alguien me podria contestar como trasladar una funcion que tengo para delphi 2007 al nuevo delphi 2010, al funcion devuelve la salida de un comando ejecutado en ms-dos en delphi 2007 devuelve bien el resultado pero al ejecutarlo en delphi 2010 me devuelve basura, la funcion es esta:

Código:

function ejecutarComando (comando : string) : string;
var
  Buffer: array[0..4096] of Char;
  si: STARTUPINFO;
  sa: SECURITY_ATTRIBUTES;
  sd: SECURITY_DESCRIPTOR;
  pi: PROCESS_INFORMATION;
  newstdin, newstdout, read_stdout, write_stdin: THandle;
  exitcod, bread, avail: Cardinal;
begin
  Result:= '';
  if Win32Platform = VER_PLATFORM_WIN32_NT then
  begin
        InitializeSecurityDescriptor(@sd, SECURITY_DESCRIPTOR_REVISION);
        SetSecurityDescriptorDacl(@sd, true, nil, false);
        sa.lpSecurityDescriptor := @sd;
  end
  else sa.lpSecurityDescriptor := nil;
  sa.nLength := sizeof(SECURITY_ATTRIBUTES);
  sa.bInheritHandle := TRUE;
  if CreatePipe(newstdin, write_stdin, @sa, 0) then
  begin
        if CreatePipe(read_stdout, newstdout, @sa, 0) then
        begin
                GetStartupInfo(si);
                with si do
                begin
                  dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
                  wShowWindow := SW_HIDE;
                  hStdOutput := newstdout;
                  hStdError := newstdout;
                  hStdInput := newstdin;
                end;
                Fillchar(Buffer, SizeOf(Buffer), 0);
                GetEnvironmentVariable('COMSPEC', @Buffer, SizeOf(Buffer) - 1);
                StrCat(@Buffer,PChar(' /c ' + comando));
                if CreateProcess(nil, @Buffer, nil, nil, TRUE, CREATE_NEW_CONSOLE, nil, nil, si, pi) then
                begin
                  repeat
                        PeekNamedPipe(read_stdout, @Buffer, SizeOf(Buffer) - 1, @bread, @avail, nil);
                        if bread > 0 then
                        begin
                                Fillchar(Buffer, SizeOf(Buffer), 0);
                                ReadFile(read_stdout, Buffer, bread, bread, nil);
                                Result:= Result + String(PChar(@Buffer));
                        end;
                        Application.ProcessMessages;
                        GetExitCodeProcess(pi.hProcess, exitcod);
                  until (exitcod <> STILL_ACTIVE) and (bread = 0);
                end;
                CloseHandle(read_stdout);
                CloseHandle(newstdout);
        end;
        CloseHandle(newstdin);
        CloseHandle(write_stdin);
  end;
end;


Lord Delfos 08-02-2010 17:35:24

Bueno, no tengo D2010, pero se me ocurre que el problema está en el buffer, que es un arreglo de Char. El tipo Char en Delphi 2010 es un WideChar de antes, es decir Unicode. Yo probaría poniendo un AnsiChar.

Lo mismo haría con cualquier string, pchar o similar.

Espero te sirva. Saludongos.

yapt 08-02-2010 19:54:32

Bueno, lo ideal sería convertir todas las llamadas a WideChar, pero me ha sido más fácil hacer lo contrario, convertirlas a AnsiChar.

Pruebalo bien, solo está muy ligeramente probado.

Un saludo.

Código Delphi [-]
function TForm1.ejecutarComando (comando : AnsiString) : AnsiString;
var
  Buffer: array[0..4096] of AnsiChar;
  si: STARTUPINFOA;
  sa: SECURITY_ATTRIBUTES;
  sd: SECURITY_DESCRIPTOR;
  pi: PROCESS_INFORMATION;
  newstdin, newstdout, read_stdout, write_stdin: THandle;
  exitcod, bread, avail: Cardinal;
begin
  Result:= '';

  if Win32Platform = VER_PLATFORM_WIN32_NT then
  begin
     InitializeSecurityDescriptor(@sd, SECURITY_DESCRIPTOR_REVISION);
     SetSecurityDescriptorDacl(@sd, true, nil, false);
     sa.lpSecurityDescriptor := @sd;
  end
  else
    sa.lpSecurityDescriptor := nil;

  sa.nLength := sizeof(SECURITY_ATTRIBUTES);
  sa.bInheritHandle := TRUE;
  if CreatePipe(newstdin, write_stdin, @sa, 0) then
  begin
     if CreatePipe(read_stdout, newstdout, @sa, 0) then
     begin
        GetStartupInfoA(si);
        with si do
        begin
          dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
          wShowWindow := SW_HIDE;
          hStdOutput := newstdout;
          hStdError  := newstdout;
          hStdInput  := newstdin;
        end;
        Fillchar(Buffer, SizeOf(Buffer), #0);
        GetEnvironmentVariableA(AnsiString('COMSPEC'), @Buffer, SizeOf(Buffer) - 1);
        StrCat(@Buffer,PAnsiChar(' /c ' + comando));
        if CreateProcessA(nil, @Buffer, nil, nil, TRUE, CREATE_NEW_CONSOLE, nil, nil, si, pi) then
        begin
          repeat
             PeekNamedPipe(read_stdout, @Buffer, SizeOf(Buffer) - 1, @bread, @avail, nil);
             if bread > 0 then
             begin
                FillChar(Buffer, SizeOf(Buffer), 0);
                ReadFile(read_stdout, Buffer, bread, bread, nil);
                Result:= Result + AnsiString(PAnsiChar(@Buffer));
             end;
             Application.ProcessMessages;
             GetExitCodeProcess(pi.hProcess, exitcod);
          until (exitcod <> STILL_ACTIVE) and (bread = 0);
        end;
        CloseHandle(read_stdout);
        CloseHandle(newstdout);
     end;
     CloseHandle(newstdin);
     CloseHandle(write_stdin);
  end;
end;


La franja horaria es GMT +2. Ahora son las 10:35:31.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi