Toon posts:

[Delphi] createprocess handles probleem

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik heb een probleem met een applicatie die ik werkend probeer te krijgen.
Vanuit mijn applicatie run ik een executable mbv een commandline, via de functie CreateProcess. Die executable geeft output, die ik via een pipe opvang en laat zijn in mijn programma.
Relevante code:

Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
  if Createpipe (ReadPipe, WritePipe,
                 @Security, 0) then
  begin
    FillChar(Start,Sizeof(Start),#0);
    start.cb          := SizeOf(start);  -> start = tStartupInfo
    start.lpReserved  := nil;
    start.hStdOutput  := WritePipe;
    start.hStdError  := WritePipe;
    start.hStdInput   := GetStdHandle(STD_INPUT_HANDLE);
    start.dwFlags     := STARTF_USESTDHANDLES +
                        STARTF_USESHOWWINDOW;
    start.wShowWindow := SW_SHOWNORMAL;//SW_HIDE;
    
    ......

  if( CreateProcess( nil,
       PChar(command),
       @Security,
       @Security,
        true,         // Set handle inheritance
        0,
        nil,
        nil,
        start,
        ProcessInfo )
  )


Nu heb ik ontdekt dat als de executable iets meer werk heeft dan anders, hij voortijdig ophoudt iets te doen, maar niet termineert en in het geheugen actief blijft. Dit zonder enige vorm van output of foutmelding. Bij een snelle executie verloopt alles prima en kan ik zonder problemen de output opvangen. Als ik nu de bInheritHandles in de CreateProcess-aanroep op 'false' zet, lopen alle processen goed, ook die wat meer tijd kosten. Alleen, dan kan ik dus de output niet opvangen en die heb ik wel nodig.

Wat is er met die inherited handles wat ervoor zorgt dat mijn executable zijn werk niet afmaakt?

.modbreak: gebruik [norml]
Delphi:
1
...
[/] tags om delphi code weer te geven :)

[ Voor 5% gewijzigd door .oisyn op 22-09-2003 18:09 ]


Verwijderd

Topicstarter
kan niemand helpen?

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 18:25

Creepy

Tactical Espionage Splatterer

Er staat ergens in Welkom in P&W: FAQ en Beleid *updated: 05-07* iets over niet kicken binnen 24 uur ;)

Anyway, waarom denk je dat het aan je code ligt en niet aan het proces dat je start? Geeft dat misschien ook geen output meer als je dat met de commandline start?

Edit: ow, en misschien ook handig als je wat code geeft hoe je de boel uitleest, hoe je Security initialiseert etc?

Edit2: overigens heb ik ook een stuk Delphi code liggen wat zowel de stdout als stdin afvangt. Het enige verschil wat ik kan ontdekken is dat ik i.p.v. @security in de CreateProcess call gewoon een nil heb staan.

[ Voor 33% gewijzigd door Creepy op 22-09-2003 18:15 ]

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Verwijderd

Topicstarter
@kicken: wist ik niet... sorry

@commandline: uiteraard heb ik hem daar uitgeprobeerd, hij start gewoon daar en levert de juiste output...

@security-code:

With Security do
begin
nlength := SizeOf(Security);
binherithandle := true;
lpsecuritydescriptor := nil;
end;

heb wel interesse in dat stuk code, hoe vang je stdin en stdout af? ik heb het zelf via files geprobeerd, vond ik niet handig.

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 18:25

Creepy

Tactical Espionage Splatterer

Verwijderd schreef op 22 september 2003 @ 18:25:
@kicken: wist ik niet... sorry

@commandline: uiteraard heb ik hem daar uitgeprobeerd, hij start gewoon daar en levert de juiste output...

@security-code:

With Security do
begin
nlength := SizeOf(Security);
binherithandle := true;
lpsecuritydescriptor := nil;
end;
Alleen de inheritedhandle op true? Dat doe je ook al in je CreateProcess, dus je kan ze net zo goed weg laten.
heb wel interesse in dat stuk code, hoe vang je stdin en stdout af? ik heb het zelf via files geprobeerd, vond ik niet handig.
Eeehh.. heb je enig idee waar je mee bezig bent? Want je vangt nu met behulp van pipes de stdout af van de app die je start. Stdin gaat om ongeveer dezelfde manier.

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • elevator
  • Registratie: December 2001
  • Niet online

elevator

Officieel moto fan :)

Als je zegt dat het programma actief blijft - zou het kunnen zijn dat ie op dat moment op input blijft staan te wachten ?

Verwijderd

Topicstarter
Creepy schreef op 22 september 2003 @ 18:39:
Eeehh.. heb je enig idee waar je mee bezig bent? Want je vangt nu met behulp van pipes de stdout af van de app die je start. Stdin gaat om ongeveer dezelfde manier.
ja, ik weet wel waar ik mee bezig ben, ik zal het herformuleren:
hoe vang JIJ stdout af? ik weet hoe IK het doe...

Verwijderd

Topicstarter
elevator schreef op 23 September 2003 @ 00:27:
Als je zegt dat het programma actief blijft - zou het kunnen zijn dat ie op dat moment op input blijft staan te wachten ?
dat denk ik niet, als ik exact hetzelfde op de commandline doe heeft ie ook geen input nodig...

het verschil moet hem toch echt in de handles zitten, maar waar...

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 18:25

Creepy

Tactical Espionage Splatterer

Verwijderd schreef op 23 September 2003 @ 16:26:
[...]


ja, ik weet wel waar ik mee bezig ben, ik zal het herformuleren:
hoe vang JIJ stdout af? ik weet hoe IK het doe...
Ah, op dezelfde manier als jij, voor zover ik aan je code kan zien :)
Het verschil is dat ik die Security dingen niet meegeef aan CreateProcess.

[ Voor 12% gewijzigd door Creepy op 24-09-2003 08:43 ]

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • BoomSmurf
  • Registratie: Maart 2003
  • Laatst online: 11:50

BoomSmurf

Am-Ende!

Is de executable die je opvangt ook een Delphi executable? Dan kan het zijn dat de output niet doorgelust wordt naar je 'opvangprogsel' voor ie termineert als de output data minder dan 128 bytes is. InheritHandles moet trouwens idd op true staan. Hoe zeker weet je dat je probleem in het stukje code zit wat je hier gequote hebt?

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 18:25

Creepy

Tactical Espionage Splatterer

BoomSmurf schreef op 24 September 2003 @ 11:17:
Is de executable die je opvangt ook een Delphi executable? Dan kan het zijn dat de output niet doorgelust wordt naar je 'opvangprogsel' voor ie termineert als de output data minder dan 128 bytes is.
Dit heb ik nog nooit gezien, mag ik vragen hoe je aan die info komt?

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • BoomSmurf
  • Registratie: Maart 2003
  • Laatst online: 11:50

BoomSmurf

Am-Ende!

De standaard text input/output routines (Read(Ln), Write(Ln), etc) gebruiken een buffer van 128 bytes. Zo ver ik weet is dit een compiler 'feature' van Delphi zelf, hetzelfde gebeurd nl. niet met MSVC executable e.d. Het is wel efficienter met grote hoeveelheden data maar het is niet altijd handig.

Het programma wat de output opvangt krijgt dus altijd alles in chunks van 128 bytes, tot het programma stopt, dan krijgt ie de resterende output.

Waar ik deze feiten origineel vandaan heb weet ik zo niet meer, maar het is wel zo. Ik heb dit zelf ook nog getest met een zelfsoortig iets als de topicstarter, en het klopt idd. Wat ik me nu wel afvraag is waarom de command interpreter wel deze gegevens unbuffered krijgt maar een pipe niet. Hier heb ik het antwoord nog niet op kunnen vinden.

Ik ben momenteel zelf bezig met 2 units, 1 een complete wrapper voor console input/output/error opvang, en een andere die Read(Ln) en Write(Ln) in een Delphi console app vervangt zodat dit buffering niet optreed. Dit is echter nog niet klaar anders had ik het wel gepost als antwoord op de topicstarter :)

  • elevator
  • Registratie: December 2001
  • Niet online

elevator

Officieel moto fan :)

Ik denk dat ie refereert aan de buffer in het textfile record in Delphi welke idd output buffering doet - maar voor zover ik weet wordt dat geflushed bij exit van je programma. Als je dat wil controleren zou je natuurlijk een "flush(output);" in je finalization op kunnen nemen.

  • BoomSmurf
  • Registratie: Maart 2003
  • Laatst online: 11:50

BoomSmurf

Am-Ende!

Dat wordt idd geflushed bij de exit, flush(output) in je finalization heeft dus weinig nut. Je kunt matige 'unbuffered' resultaten boeken met een flush(output) na elke WriteLn, maar dat is irritant veel werk en werkt ook niet perfect (voor zover ik het getest heb kreeg ik niet alle data binnen in mn opvang progsel)

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 18:25

Creepy

Tactical Espionage Splatterer

Dan zou dat dus alleen in het geval van een crash een probleem kunnen zijn. Ik ga dat binnenkort eens testen, want mij was het nog niet echt opgevallen. Maar de app. waarvan ik de stdout en stdin omleid is geschreven in C ;)

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • elevator
  • Registratie: December 2001
  • Niet online

elevator

Officieel moto fan :)

Als dat echt een probleem is kan je misschien SetTextBufsize() (iirc) aanroepen met een null buffer. Dat werkt dan een stuk performanter.

  • BoomSmurf
  • Registratie: Maart 2003
  • Laatst online: 11:50

BoomSmurf

Am-Ende!

SetTextBuf bedoel je, die heeft geen effect op input/output jammer genoeg

  • elevator
  • Registratie: December 2001
  • Niet online

elevator

Officieel moto fan :)

Rewrite je wel je Output nadat je SetTextbuf aanroept? Anders zou je bij het initialiseren van je text device driver gewoon je BufSize op 1 kunnen zetten (geloof ik :P )

Verwijderd

Topicstarter
BoomSmurf schreef op 24 September 2003 @ 11:17:
Is de executable die je opvangt ook een Delphi executable? Dan kan het zijn dat de output niet doorgelust wordt naar je 'opvangprogsel' voor ie termineert als de output data minder dan 128 bytes is. InheritHandles moet trouwens idd op true staan. Hoe zeker weet je dat je probleem in het stukje code zit wat je hier gequote hebt?
doordat als ik de true in een false verander, het is opgelost (zonder output), dus dat is het enige dat verandert...

de output die ik verwacht is trouwens vrij groot, dus dat is het ook niet

[ Voor 10% gewijzigd door Verwijderd op 25-09-2003 09:21 ]


  • BoomSmurf
  • Registratie: Maart 2003
  • Laatst online: 11:50

BoomSmurf

Am-Ende!

Hmm de code die daar staat is anders verder hetzelfde als mijn eigen code, die nog geen problemen opgeleverd heeft, op het volgende na:

Ik gebruik verschillende Pipes voor Input, Output en Error - ofwel ik roep CreatePipe 3x aan.

Verwijderd

Topicstarter
ok, ik ga ook eens verschillende pipes gebruiken.. wie weet.

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 18:25

Creepy

Tactical Espionage Splatterer

Ik hoop voor je dat het verschil maakt.

Ik gebruik alleen verschillende pipes voor Input en Output. Output en Error heb ik doorgelust naar dezelfde PIPE. Ik heb dus alleen de invoer en uitvoer pipes gescheiden. Dat is dus eigenlijk hetzelfde wat jij doet, alleen heb ji de stdin naar de standaard handle staan en ik naar een pipe.

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Verwijderd

Topicstarter
aha maar dan maakt het niets uit dus.. ik maak namelijk helemaal geen gebruik van de stdin, de executable krijgt alle invoer al mee op de comandline. die stdin uit mijn code hierboven zou ook weggelaten kunnen worden.

hoe vaak roep jij createpipe nou aan? 1 x toch?

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 18:25

Creepy

Tactical Espionage Splatterer

Verwijderd schreef op 26 September 2003 @ 14:33:
hoe vaak roep jij createpipe nou aan? 1 x toch?
2 keer in totaal, 1 keer voor de stdin en 1 keer voor de stdout + stderr

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Verwijderd

Topicstarter
weet inmiddels dat het aan de volgende regel code ligt (uit de code van eerste post):
Delphi:
1
    start.hStdError  := WritePipe;

als ik deze regel uitzet, verloopt alles prima... behalve dan dat ik geen output kan opvangen.

wanneer hangt een hStdError handle?

Verwijderd

Topicstarter
echt niemand een ander idee?

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 18:25

Creepy

Tactical Espionage Splatterer

Ik gok toch echt dat het niet aan je code ligt, maar aan de exe die je start. Reageert deze misschien iets anders als z'n output wordt afgevangen?

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Verwijderd

Hoi,

Ik heb de discussie wat meegevolgd, en veel van de problemen die ik heb ontmoet werden ook hier besproken.
Van Boomsmurf's unit zou ik ook wel eens een kopie willen zien, want ik ben heel benieuwd hoe hij de console volledig interactief kan maken, door een redirect van zowel in - als output.
Is die al klaar?

Greets,
Pagina: 1