Issue 51767 - After CreateProcess API call WaitforSingleObject don't work well.
Summary: After CreateProcess API call WaitforSingleObject don't work well.
Status: CLOSED IRREPRODUCIBLE
Alias: None
Product: App Dev
Classification: Unclassified
Component: api (show other issues)
Version: 3.3.0 or older (OOo)
Hardware: PC Windows 2000
: P4 Trivial
Target Milestone: ---
Assignee: hennes.rohling
QA Contact: issues@api
URL:
Keywords: oooqa
Depends on:
Blocks:
 
Reported: 2005-07-09 23:55 UTC by ccill
Modified: 2013-02-24 21:07 UTC (History)
3 users (show)

See Also:
Issue Type: ENHANCEMENT
Latest Confirmation in: ---
Developer Difficulty: ---


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description ccill 2005-07-09 23:55:23 UTC
From Delphi 7 Language, I use the next well know routine for call external
programs an wait for terminate it. 

function WinExecAndWait32(FileName: string; Visibility: Integer): dWord;
var
  zAppName: array[0..512] of Char;
  zCurDir: array[0..255] of Char;
  WorkDir: string;
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
begin
  StrPCopy(zAppName, FileName);
  GetDir(0, WorkDir);
  StrPCopy(zCurDir, WorkDir);
  FillChar(StartupInfo, Sizeof(StartupInfo), #0);
  StartupInfo.cb := Sizeof(StartupInfo);

  StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
  StartupInfo.wShowWindow := Visibility;
  if not CreateProcess(nil,
           zAppName, { pointer to command line string }
           nil, { pointer to process security attributes }
           nil, { pointer to thread security attributes }
           false, { handle inheritance flag }
           CREATE_NEW_CONSOLE or { creation flags }
           NORMAL_PRIORITY_CLASS,
           nil, { pointer to new environment block }
           nil, { pointer to current directory name }
           StartupInfo, { pointer to STARTUPINFO }
           ProcessInfo) then
    Result := -1 { pointer to PROCESS_INF }
  else
  begin
    WaitforSingleObject(ProcessInfo.hProcess, INFINITE);
    GetExitCodeProcess(ProcessInfo.hProcess, Result);
    CloseHandle(ProcessInfo.hProcess);
    CloseHandle(ProcessInfo.hThread);
  end;
end;

    With any one application it works well. In a debug session I can see that
the step by step execution stops in WaitforSingleObject instruction and continue
when I close the external program.

   The problem is that with OpenOffice, executable starts well but they ignore
the WaitforSingleObject an continue, OpenOffice are open and my application
continues. They don't wait for OpenOffice execution end. :( 


    I tested a lot of programs and I see that only OpenOffice fails. 

   I need it for integration projects.

Thank you very much.
Comment 1 stephan.wunderlich 2005-07-11 08:14:18 UTC
sw->jl: can you please take a look at this ... I have no delphi here so I
couldn't confirm it yet.
Comment 2 joachim.lingner 2005-07-11 09:22:13 UTC
The soffice.exe is just a wrapper and starts the soffice.bin. I had a look at 
desktop/win32/source/officeloader/officeloader.cxx 
and it seems that the code waits until the soffice.bin has terminated. If that
is the right code for soffice.exe then it looks ok for me. 
JL->HR: Do you have an idea?
Comment 3 ccill 2005-07-12 09:14:31 UTC
I find this issue that is about the same problem. #28299

   The problem is this: 
When I start Windows, OpenOffice starts like a service and have his own handle,
that I will call "mother handle".

With CreateProcess API Call, I take a handle to a new process, but this process
have the only mission of to say the "mother Handle" what is what we want to do,
and inmediately they finish. ==>>This is the problem<<==. 

   I have not the oportunity to know when the user has finished the edition, I
only can know, when this auxiliar handle finish.
   
   This is not the expected behavior. The programmer, I, wait that when the user
finish the edition, by example, closing the file that is editing or closing,
then the program finish the "child process" we are created. Not before. 

     In my program the problem is: 
   I extract a document from a Database, putting it in a file.
   I call the default program for this kind of file.
   I wait for handle finish. (inmediately with this error).
   I take the file, still intact, and put it in the database.
   (and the soffice.exe continues editing the file, that will not back to the
database never) :( 

    I tryed to not start soffice in the windows start, but the problem is the same. 

        I suggest that this is not a standart behavior and that we need to
correct it. I can send you the complete code to the issue or personaly by e-email. 

    
Comment 4 christianjunker 2005-09-02 12:43:27 UTC
I am confused about what exactly is the problem here, but my first idea would be
that a possible problem lies in the COM bridge implementation, see
extensions/source/ole .

ccill:
Please post code to here and just the relevant part of it (where it fails).


Comment 5 hennes.rohling 2005-09-02 15:47:11 UTC
soffice.exe starts soffice.bin as a child process but waits until soffice.bin 
terminates. Therefor waiting for soffice.exe is nearly the same as waiting for 
soffice.bin.

The described behaviour occurs if soffice.exe is started while another soffice.exe is 
already running for the same user. The parameters from the new started 
soffice.exe process are dispatched to the already running process and then the 
new process terminates.

So this might happen if the Quickstarter is running (guess that's meant when 
talking about soffice.exe was started as a service) or an instance of soffice.exe is 
running for other reasons.

And no this has nothing to do with COM. You might try the same with MS Word or 
so. Start Word, create a new word process and you'll experience that it terminates 
immediatly.
Comment 6 ccill 2005-09-13 09:55:56 UTC
"So this might happen if the Quickstarter is running"

Are you triyed it? 
    I tried it and this is not true. Don't work in the same way.
The Quickstarter rest active after writer is closed.

hro say: 
   "You might try the same with MS Word or so. Start Word, create a new word       
   process and you'll experience that it terminates immediatly."
     
    I tried it with with MS-Word 97 and MS-Word 2000. The work well.

  Really this is my problem. I wan't to eliminate MS-Office from my net (over 75
installations). But I need to mantain it because our OO don't work like we spected.

    To try it you only need to change the default application for .doc documents. 

    Regards. 

Comment 7 christianjunker 2005-09-28 14:34:32 UTC
ccill, would you be so kind and explain exactly what fails in a short summary?
(details needed!)

There are many people that don't understand Delphi code - I believe - and so you
need to make clear what exactly should happen, even better would be if you have
some C++ code to show it.

Thanks.
Comment 8 hennes.rohling 2005-10-06 14:10:32 UTC
ccill said: "I tried it with with MS-Word 97 and MS-Word 2000. The work well."

No, if you start f.e. one WINWORD.EXE, leave the Word-Window open, start 
another WINWORD.EXE, you'll experience that a second Word-Window opens but 
the second process terminates immediatly. The first process will terminate after all 
open windows were closed.

Same is with OOo. 

Just if the quickstarter is enabled it keeps the SOFFICE.EXE process running. So 
it will never terminate. And every further SOFFICE.EXE process will forward the 
arguments to the already running process and terminates afterwards. 

This is by design and common practise for larger applications.

Closing the issue.
Comment 9 hennes.rohling 2005-10-06 14:11:31 UTC
Closed.
Comment 10 ccill 2005-10-06 17:21:33 UTC
I need to do the next operation: From my own Accounting program call to the
predefined program that open .doc files. My program stand for the end of the
this execution. 

    The code that I show you is good. Works with any type of extension. (pzh,
doc, xls, img, pdf, txt, etc) When my default program for open .doc files is
Microsoft Windows, they works well. When my defalt program is OOo, they don't
work. Don't stand to the end of de runing of the external program. They return
inmediately. 

  I don't call to WindWord or OOo directly. My program call "to de default
application in windows, that open .doc files". 

  This is a professional system to do the program compatible with a lot of
instalations. 

   I don't need to open serveral instantes of MS-Windows. Only one. But take in
mind that I call to "The predefined application for open .doc files". I don't
call any program directly. I leave the operating system to decide what program
open .doc files. Is like if I double clicked on the file, but making it into my
code. 

    CreateProcess is not Pascal Code. Is a routine from MS-Windows. If you
search in Win32 API help files you can see it.

    Thank you very much. ;)       See you. 
Comment 11 hennes.rohling 2005-10-07 10:33:39 UTC
It's not up to me to blame you :-) but I feel you misunderstood some details.

What you call "Microsoft Windows" to open the document is not exactly how it 
works.

I guess you retrieve the command line assosiated with an extension from the 
registry and pass that string along with the document file name to your function 
WinExecAndWait32.

For example for .doc and installed MS Office that would be

"C:\Program Files\Microsoft Office\OFFICE11\WINWORD.EXE" /n /dde 
filename.doc

Doing that you're right. The /dde parameter forces additional winword.exe 
processes to stay alive as long as the window is open, so you will have multiple 
winword.exe processes when opening multiple documents. This happens only 
when openeing .doc files by the desktop shell or the way you did.

For other extensions like .txt a seperate process is created for every document 
because notepad.exe does not consume many system resources.

But for .pdf and Acrobat 7 there no seperate process for every document openend 
that way.

OOo does not create a seperate process for every openend document even when 
it's done by the shell. Every new created process passes it's parameters to the 
already running process and terminates afterwards. This is by design.

BTW: What I guess you are doing (retrieving the commandline from the registry, 
merging the document file name and pass that to a CreateProcess call) can easier 
be done by a call to the Windows API call ShellExecuteEx. You can pass the 
document file name without retrieving the assosiated command line and you'll get a 
process handle back for synchronization.

But coming back to what you want OOo to act like. It is not mandatory for an 
application to create a new process for every single openend document. Many 
applications do so and other don't, so this is not a defect of OOo. Also OOo does 
not handle the WaitForSingleObject call, it's the OS that waits for a process to 
terminate and the new OOo process just terminates, that's all.

Try the following: Open to .doc files with MS Word by double clicking them in the 
desktop shell or using your application. You'll see to winword.exe processes in the 
taskmanager. Now select "file Open" in the second document window and open a 
third document by the file open dialog. Now you have three open document 
windows but only two processes. Now close the two document windows openend 
by double clicking. You'll see that the last winword.exe process will stay alive. So 
what is that behaviour good for ?

Answer:
There are some circumstance when the behaviour of a process instance for every 
document is desired. F.e. many mail clients like Mozilla, Outlook Express, will 
start assosiated external applications when double clicking on email attachments. 
They create a temoprary file, pass the filename to the assosiated application, sync 
for procesess to terminate and delete the temporary file afterwards. They need to 
do so because they must now how long they have to provide the temporary file. If 
they would delete it before waiting for the started process to terminate the process 
won't be able to open file because it was deleted to fast. And if the mail client 
would not delete the temporary file they will rest in the file system after they are no 
longer used.

I don't know if the intention of your application is identical to what a common mail 
client does. But OOo is aware of that problematic but it handles it in a different 
way:
Every additional started OOo process makes sure that the document was loaded 
(in memory, or temporary file) in the "main" process before it terminates.

Please describe exactly if that behaviour meets your requirements or what your 
intention is when waiting for the process to terminate.

Changed issue type and priority

Comment 12 hennes.rohling 2006-02-06 18:05:25 UTC
Resolved.
Comment 13 hennes.rohling 2006-02-06 18:06:23 UTC
closed.