WinXP - cmd.exe

0

Cześć.
Mam taki interesujący problem.
Poprzez mój program chcę odczytywać dane z programu cmd.exe.
Czy istnieje możliwość skopiowania danych, np. do kontrolki TMemo z programu cmd.exe?
W jaki sposób wywołać z poziomu mojej aplikacji(shellexecute?) program cmd.exe z parametrem np. net share(zasoby udostepnione) kopiując rezultat do TMemo, czy jest to w ogóle możliwe?
Ogólnie, chodzi o wydobycie ciekawych informacji z programów Windows, poprzez konsolę cmd.
Pozdrawiam
Pepe

0

http://4programmers.net/Forum/viewtopic.php?id=50371

Tak, dzieki, skorzystalem z kodu programu "guipex"
http://www.blueorbsoft.com/guipex/
Wykorzystałem następującą funkcję:

function TForm1.DosExecAndWait32(const FileName: string; var Output: string): DWORD;
{ func to execute a DOS app and pipe output to a string variable }
var
  zAppName: array[0..512] of char;
  StartupInfo: TStartupInfo;
  SecurityAttrib: TSecurityAttributes;
  ProcessInfo: TProcessInformation;
  StdOutPipeWrite, StdOutPipeRead: THandle;
  bResult: boolean;
  Buffer: array[0..255] of Char;
  BytesRead: 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
          { Woke on a message, process paint messages only. Calling
            PeekMessage gets messages send from other threads processed. }
          while PeekMessage(msg, 0, WM_PAINT, WM_PAINT, PM_REMOVE) do
            DispatchMessage(msg);
        end;
    until ret = WAIT_OBJECT_0;
  end;

begin
  with SecurityAttrib do
    begin
      nLength := SizeOf(SecurityAttrib);
      bInheritHandle := True;
      lpSecurityDescriptor := nil;
    end;
  // create pipe for standard output redirection
  CreatePipe(StdOutPipeRead, // read handle
    StdOutPipeWrite, // write handle
    @SecurityAttrib, // security attributes
    0 // number of bytes reserved for pipe - 0default
    );

  FillChar(zAppName, Sizeof(zAppName), #0);
  StrPCopy(zAppName, FileName);
  FillChar(StartupInfo, Sizeof(StartupInfo), #0);
  with StartupInfo do
    begin
      cb := Sizeof(StartupInfo);
      dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
      wShowWindow := SW_HIDE;
      hStdInput := GetStdHandle(STD_INPUT_HANDLE); // don't redirect stdinput
      hStdOutput := StdOutPipeWrite;
      hStdError := StdOutPipeWrite;
    end;

  if not CreateProcess(nil,
    zAppName, { pointer to command line string }
    nil, { pointer to process security attributes }
    nil, { pointer to thread security attributes }
    True, { handle inheritance flag }
    CREATE_NEW_CONSOLE or { creation flags }
    HIGH_PRIORITY_CLASS,
    nil, { pointer to new environment block }
    nil, { pointer to current directory name }
    StartupInfo, { pointer to STARTUPINFO }
    ProcessInfo) { pointer to PROCESS_INF } then
    Result := DWORD(-1) { failed, GetLastError has error code }
  else
    begin
      CloseHandle(StdOutPipeWrite);
      // get all output until dos app finishes
      repeat
        // read block of characters (might contain carriage returns and line feeds)
        bResult := ReadFile(StdOutPipeRead, Buffer, 255, BytesRead, nil);
        // has anything been read?
        if BytesRead > 0 then
          begin
            // finish buffer to PChar
            Buffer[BytesRead] := #0;
            // combine the buffer with the rest of the last run
            Output := Output + Buffer;
          end;
      until not(bResult) or (BytesRead = 0);
      Waitfor(ProcessInfo.hProcess);
      GetExitCodeProcess(ProcessInfo.hProcess, Result);
      CloseHandle(ProcessInfo.hProcess);
      CloseHandle(ProcessInfo.hThread);
      CloseHandle(StdOutPipeRead);
    end;
end;

Niestety, w TMemo, do którego dane wczytuje nie mam polskich znaków!!! Dlaczego? Jak je uzyskać?
Wywołuje dane w ten sposób:

procedure TForm1.SpeedButton2Click(Sender: TObject);
var
  Output: string;
  CommandParams:string;
  podprogram : string;
begin
  CommandParams:=parametry.text;
  podprogram:=programwyw.Text;

memo1.Clear;

DosExecAndWait32(podprogram + ' ' + CommandParams , Output);

memo1.Lines.Add('********************************************************************************');
memo1.Lines.Add(podprogram);
memo1.Lines.Add('Time: ' + timetostr(now) + ',  Date: ' + Datetostr(now));
memo1.Lines.Add('');
memo1.Lines.Add('');
memo1.Lines.Add(output);
memo1.Lines.Add('********************************************************************************');
end;

Pozdr, pepe

0

Witam!
Sorry wielkie za odkopywanie tak starego tematu, ale przydał mi się właśnie bardzo z tym że potrzebuję się nieco dopytać.
Mianowicie wykorzystałem sobie kodzik z postu wyżej do odpalania pewnej aplikacji która działa tylko z wiersza poleceń. Wszystko działa miodnie, program się odpala, robi co mu kazałem i uzyskuję od niego odpowiedź. Problem w tym że po uzyskaniu odpowiedzi potrzebuję wysłać do niego kolejne polecenie i znów uzyskać odpowiedź, tak kilka razy. Przy czym program nie może zostać zamykany i uruchamiany ponownie pomiędzy komendami, są one ze sobą powiązane i dają wspólny efekt.
Dodam że bawiłem się komponentem TUnitedCMD oraz TDosCommand, nie pasują mi one bardzo ze względu na mechanizm działania (timer). Próbowałem wygrzebać coś z ich kodu, ale wychodzi na to że jestem zbyt zielony, nie potrafię tego zmusić do działania.
Proszę o pomoc!

Pozdrawiam!

0

musisz wgryźć się trochę w ten kod, jak widzisz komunikacja odbywa się poprzez ReadFile(StdOutPipeRead,...), oraz, czego nie widać, WriteFile(StdOutPipeWrite,...).
Poczytaj o "named pipes".
Opisany wyżej problem z polskimi literami wynika z różnej strony kodowej w oknie konsoli (CP852) i w reszcie systemu (CP1250).

0

Sęk w tym że próbowałem i za cholerę mi to nie działa :/
Robiłem takie coś:
// do buffera jest wrzucana komenda
// bwrite dalem typu dword - ale nawet nie wiem po co mi ta zmienna :/
WriteFile(StdOutPipeWrite, Buffer, Length(command), BWrite, nil);

1 użytkowników online, w tym zalogowanych: 0, gości: 1