Program konsolowy - wysylanie i pobieranie danych

0

Mam program, który odpala się w konsoli. Potrzebuje co jakiś czas przesyłać do niego dane i odbierać.
Google nie chce mi poóc ;(
Jak to zrobić ?

0

a to wredne google... Popatrz mi natomiast na samej górze zwróciło https://www.google.pl/search?q=delphi+cmd+output o ale w sumie ja nie wpisywałem w google zapytania typu jak szydełkować...

0
function RunIt(const Exe,Param,Dir:String):Boolean;
var SA:TSecurityAttributes;
var SI:TStartupInfo;
var PI:TProcessInformation;
var Res:Cardinal;
var InH,OutH,ErrH,MyInH,MyOutH,MyErrH:THandle;
var L:DWord;
var F:Boolean;
var S:String;
var MSG:PChar;
const PipeSize=16000;
begin
  SA.nLength:=sizeof(SA);
  SA.bInheritHandle:=true;
  SA.lpSecurityDescriptor:=nil;
  CreatePipe(InH,MyInH,@SA,PipeSize);
  CreatePipe(MyOutH,OutH,@SA,PipeSize);
  CreatePipe(MyErrH,ErrH,@SA,PipeSize);
  try
    FillChar(SI,SizeOf(SI),0);
    FillChar(PI,SizeOf(PI),0);
    SI.cb:=SizeOf(SI);
    SI.wShowWindow:=SW_HIDE;
    SI.hStdInput:=InH;
    SI.hStdOutput:=OutH;
    SI.hStdError:=ErrH;
    SI.dwFlags:=STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
    F:=CreateProcess
    (
      nil,
      PChar(Exe+' '+Param),
      nil,
      nil,
      true,
      NORMAL_PRIORITY_CLASS,
      nil,
      PChar(Dir),
      SI,
      PI
    );
    if F then
    begin
      // Write to InH pipe
      WaitforSingleObject(PI.hProcess,INFINITE);
      GetExitCodeProcess(PI.hProcess,Res);
      Result:=(Res=0);
      if Result then
      begin
        SetLength(S,PipeSize);
        L:=0;
        ReadFile(MyOutH,S[1],PipeSize,L,nil);
        SetLength(S,L);
        // S - result 
      end;
      Exit;
    end;
    Res:=GetLastError;
    // Some message there
    Result:=false;
  finally
    CloseHandle(InH);
    CloseHandle(OutH);
    CloseHandle(ErrH);
    CloseHandle(MyInH);
    CloseHandle(MyOutH);
    CloseHandle(MyErrH);
  end;
0

Bardzo dziękuję. Jeszcze nie testowałem. Ale to chyba nie poleci. Problem jest taki, że program w konsoli odpalam 1x i dopiero po pewnym czasie mogę przesłać parametry. Program musi znaleźć interface na USB. Dopiero po tym czasie mogę wysłać parametry.

zaraz osiwieje.
Dlaczego CreateProcess nie odpala mi programu, a ShellExecute to robi ?

RunIt('moj.exe','',ExtractFilePath(Application.ExeName));

ShellExecute(Handle, 'open', 'moj.exe', nil, pchar(ExtractFilePath(Application.ExeName)), SW_SHOWNORMAL);

dodanie znaczników <code class="delphi"> i ``- fp

0

Wiem ze nie pisze sie postow pod postami, ale moze tak ktos mi podpowie.
Nie jestem programista z wykształcenia ale z potrzeby. Programow nie potrafie pisac tak jak Wy, ale "bazgroły" wystarcza na moje potrzeby.

Zmieniłem to:

SI.wShowWindow:=SW_NORMAL;

i teraz juz sie okienko z programem pokazuje ale program sie wiesza.

......" System dodaje znak 0 do linii poleceń, aby oddzielić nazwę plików od argumentów jego wywołania. "

Chyba dlatego

dodanie znacznika <code class="delphi"> - fp

0

Jezeli zrobie cos takiego

RunIt('cmd.exe','help',ExtractFilePath(Application.ExeName));

To pojawia mi sie tylko czarne okienko z migajacym kursorem ( cmd mam skopiowany tam gdzie kod wynikowy mojego programu ) i w niebieskim pasku ( na gorze ramki ) sciezka dostepu do cmd.exe
I tyle , zamiast zgloszenia sie programu ( napis microsoft .....) .
Nie mam pojecia jak i gdzie co wpisac.
Czytalem rozne fora ( nawet zagraniczne ) i cos mi dalej to nie robi.

Czytalem ze shellexecute nie ma uchwytu do okna czyli z tego co rozumiem nie nadaje sie to do mojego celu.
jest/bylo shellexecuteEX ale tego juz chyba nie ma.

Jak w pierwszym kroku otworzyc tylko cmd bez parametrow ?
jak w drugim kroku i kolejnych ( petli ) wysylac znaki ( ciagi ) do cmd ?

dodanie znacznika <code class="delphi"> - fp

0

Nikt nie pomoże ?

0

Przecież napisałem w komentarzu "Musisz coś wpisać do pipe InH." - którego słowa nie rozumiesz?

0

To ze mam wpisac to wiem. Tylko nie wiem jak sie cos wpisuje do pipe InH.

Chyba szybciej i prosciej jak znajde jakiegos studenta.

0

Gdybym nie probowal nie zawracal bym glowy.

s:='';   
   WriteFile(inH,S[1],PipeSize,L,nil);
  WriteFile(inH,'',0,L,nil);

To nie dziala.

Jezeli ta linie wyremuje ( tzn wstawie przed // ) to program odpala.

 SI.dwFlags:=STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;

Złośliwcom bardzo dziekuje za pomoc ( TBrain ) i proponuje brac 2x dziennie sapientia. ( pytac w aptece )

Z tego co doczytalem to jezeli te flagi nie sa wlaczone to nie bede mogl pobierac/wysylac danych z konsoli i kolo sie zamyka.

0

Biedaczysko nigdy nie słyszało o google :/
http://lmgtfy.com/?q=WriteFile+msdn

0

Widze ze trafilem na zle forum.
Zapytam gdzie indziej. Moze tam beda bardziej wyrozumiali.

0

@tatanka: nie ma wyrozumiałości dla braku TBrain i niechęci do googlowania. Nie śledziłem dokładnie tego wątku, więc się już trochę pogubilem z czym problem? Wysłanie czegoś do "pipy"? Proszę bardzo, poniżej fragment kodu, ktory po ustanowieniu prawidlowego uchwytu wysyła symulowanie naciśnięcia klawisza dzieki obsludze pipes przez debugger pod WinUAE. Może do czegoś Ci się to przyda. I nie ma co się "fochować", tylko ZANIM zapytasz o cokolwiek. Spróbować długo samodzielnie, googlować, kombinować i myśleć, a nie od razu sru smarować posta na forum. A to, że to dział Newbie nie stanowi od takiej zasady wyjątku.

function SendEventRawKeyCommand(RawKeyCode : Byte) : boolean;
var
  InBuf : string;
  Avail, Mode, Ret : DwORD;
begin
  Result := False;
  if (PipeH <> INVALID_HANDLE_VALUE) then
  begin
    if GetLastError <> ERROR_PIPE_BUSY then
    begin
      Mode := PIPE_READMODE_MESSAGE;
      if SetNamedPipeHandleState(PipeH, Mode, nil, nil) then
      begin
        InBuf := Event_Command_Prefix + #32 + AkToRawCodeText(RawKeyCode) + #32 + '0';
        if WriteFile(PipeH, InBuf[1], Length(InBuf) + 1, Ret, nil) then
        begin
          if PeekNamedPipe(PipeH, nil, 0, nil, @Avail, nil) then
          begin
            Result := ReadFile(PipeH, Buf, SizeOf(Buf), Ret, nil);
          end;
          Log(FormatC('Raw Key sended (Raw key code: $%.2X, AK code: "%s").', RawKeyCode, AkToRawCodeText(RawKeyCode)));
          RawKeySendedOk := True;
        end;
      end;
    end;
  end;
end;

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