Discussion:
How to wait for ShellExecute when hProcess is null
(too old to reply)
José Silva
2009-04-28 14:57:05 UTC
Permalink
I am writing an application that launches the viewer for the file to be
opened and then waits this application to close.

I am launching application using ShellExecuteEx() then I use hProcess
returned in ShellExecute to wait for the application. It happens that some
applications does not return hProcess filled. However I want to wait for
that application to close.

The question is, how can I determine if application as closed for the
situations where ShellExecuteEx returns NULL on hProcess?

Many thanks.
Joseph M. Newcomer
2009-04-28 15:16:27 UTC
Permalink
See below...
Post by José Silva
I am writing an application that launches the viewer for the file to be
opened and then waits this application to close.
****
That is almost certainly a Bad Idea. Why do you want to do this? It wil hang the process
that launched it, making it exhibit seriously bad behavior as far as the user is
concerned. Don't do it this way.
****
Post by José Silva
I am launching application using ShellExecuteEx() then I use hProcess
returned in ShellExecute to wait for the application. It happens that some
applications does not return hProcess filled. However I want to wait for
that application to close.
*****
This does seem odd. If ShellExecuteEx returns, the handle should be correct. This sounds
like a ShellExecute bug. Can you get a simple case that demonstrates it? It should be
reported via the Connect website.
****
Post by José Silva
The question is, how can I determine if application as closed for the
situations where ShellExecuteEx returns NULL on hProcess?
****
You can't. But I seriously suggest rethinking the approach. Blocking a process for an
unbounded time is usually a Really Bad Idea under nearly all conditions.
joe
*****
Post by José Silva
Many thanks.
Joseph M. Newcomer [MVP]
email: ***@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
David Lowndes
2009-04-28 15:40:10 UTC
Permalink
Post by Joseph M. Newcomer
Post by José Silva
I am launching application using ShellExecuteEx() then I use hProcess
returned in ShellExecute to wait for the application. It happens that some
applications does not return hProcess filled. However I want to wait for
that application to close.
*****
This does seem odd. If ShellExecuteEx returns, the handle should be correct. This sounds
like a ShellExecute bug.
It's expected behaviour if ShellExecuteEx doesn't need to start a new
process - for example, when opening a document in an MDI application
that's already running.

I don't think there's a neat solution to the situation though. For
some applications you might be able to examine the ROT (running object
table) to decide when the document that's been used is no longer in
use. Generally though there's no universal user mode solution that I'm
aware of.

Dave
Joseph M. Newcomer
2009-04-28 16:31:24 UTC
Permalink
I guess I (and the OP) should have RTFM.

So the answer is: you can't tell. But the idea of blocking until it exits therefore
cannot possibly make sense, so it is now Definitely A Bad Idea.
joe
Post by David Lowndes
Post by Joseph M. Newcomer
Post by José Silva
I am launching application using ShellExecuteEx() then I use hProcess
returned in ShellExecute to wait for the application. It happens that some
applications does not return hProcess filled. However I want to wait for
that application to close.
*****
This does seem odd. If ShellExecuteEx returns, the handle should be correct. This sounds
like a ShellExecute bug.
It's expected behaviour if ShellExecuteEx doesn't need to start a new
process - for example, when opening a document in an MDI application
that's already running.
I don't think there's a neat solution to the situation though. For
some applications you might be able to examine the ROT (running object
table) to decide when the document that's been used is no longer in
use. Generally though there's no universal user mode solution that I'm
aware of.
Dave
Joseph M. Newcomer [MVP]
email: ***@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
José Silva
2009-04-28 17:03:56 UTC
Permalink
I can use FindExecutable() function to know what application would be
launched by ShellExecute().

Can I know what is the hProcess for a given executable name? One of the
application that returned hProcess=NULL is the image viewer, my system call
the PhotoViewer.dll other examples are MDI applications. Can I know the
hProcess of an application launched with rundll32???
Is any other way to wait for an application to close only knowing its
executable name or dll?

Thanks
Post by David Lowndes
Post by Joseph M. Newcomer
Post by José Silva
I am launching application using ShellExecuteEx() then I use hProcess
returned in ShellExecute to wait for the application. It happens that some
applications does not return hProcess filled. However I want to wait for
that application to close.
*****
This does seem odd. If ShellExecuteEx returns, the handle should be correct. This sounds
like a ShellExecute bug.
It's expected behaviour if ShellExecuteEx doesn't need to start a new
process - for example, when opening a document in an MDI application
that's already running.
I don't think there's a neat solution to the situation though. For
some applications you might be able to examine the ROT (running object
table) to decide when the document that's been used is no longer in
use. Generally though there's no universal user mode solution that I'm
aware of.
Dave
Joseph M. Newcomer
2009-04-28 19:44:46 UTC
Permalink
But since, as David points out, if the process is already running for another instance of
your document (e.g., IE is already up), then for you to detect that the process has
terminated, you have to wait for the user to close EVERY document the process is reading.
For example, close all my .doc files in Word, or all my .htm/.html files in IE. Closing
the window displaying the document you are reading is not sufficient. So waiting for the
"process" to terminate is pointless. (Example: suppose, on my system, you launched an
HTML file. I open IE when I boot, and it never, ever closes. So your program would wait
forever, even though the *window* I was using had closed. But it is worse than that.
Suppose I brought up a separate view on that document. If you could discover what window
was brought up when I launched, you might assume that closing that window meant that I was
no longer using the document. But that's not true; you'd have to make sure that EVERY
window open on that document had closed! Overall, the whole thing is a bad strategy!)
joe
Post by José Silva
I can use FindExecutable() function to know what application would be
launched by ShellExecute().
Can I know what is the hProcess for a given executable name? One of the
application that returned hProcess=NULL is the image viewer, my system call
the PhotoViewer.dll other examples are MDI applications. Can I know the
hProcess of an application launched with rundll32???
****
But what good would this do you? You wouldn't know when I was done viewing whatever you
launched with?
*****
Post by José Silva
Is any other way to wait for an application to close only knowing its
executable name or dll?
*****
As already pointed out, knowing the application doesn't help you. If I close your Word
document, Word doesn't terminate execution; I've got sixteen other documents open in it
already. It will keep running.

I think the real problem is the idea that you *should* wait for the viewer to close. Since
I actually did RTFM after the condition was pointed out, what it boils down to is (a) you
can't tell which process is reading it and (b) you can't tell when the user has stopped
reading it. therefore (c) you cannot possibly know when to resume. The solution is (d)
don't wait for it. It is a common design error in a concurrent multitasking system to
think of asynchonous tasks as if they are subroutines, with distinct call and return
events. But the behavior of ShellExecuteEx says explicitly that you cannot treat a
process in this fashion, and you can't tell.

It is time to rethink the design.
joe
****
Post by José Silva
Thanks
Post by David Lowndes
Post by Joseph M. Newcomer
Post by José Silva
I am launching application using ShellExecuteEx() then I use hProcess
returned in ShellExecute to wait for the application. It happens that some
applications does not return hProcess filled. However I want to wait for
that application to close.
*****
This does seem odd. If ShellExecuteEx returns, the handle should be
correct. This sounds
like a ShellExecute bug.
It's expected behaviour if ShellExecuteEx doesn't need to start a new
process - for example, when opening a document in an MDI application
that's already running.
I don't think there's a neat solution to the situation though. For
some applications you might be able to examine the ROT (running object
table) to decide when the document that's been used is no longer in
use. Generally though there's no universal user mode solution that I'm
aware of.
Dave
Joseph M. Newcomer [MVP]
email: ***@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
David Lowndes
2009-04-28 20:05:43 UTC
Permalink
Post by José Silva
I can use FindExecutable() function to know what application would be
launched by ShellExecute().
Can I know what is the hProcess for a given executable name? One of the
application that returned hProcess=NULL is the image viewer, my system call
the PhotoViewer.dll other examples are MDI applications. Can I know the
hProcess of an application launched with rundll32???
Is any other way to wait for an application to close only knowing its
executable name or dll?
Even if you know the process the user can close your document and
leave the process running indefinitely, so the process isn't any
indication that your document is finished with.

Also consider that an application can open, close, re-open the same
document with or without modifying it, application's aren't consistent
in how they do their file operations.

Trying to detect when an application has finished editing one of your
documents is a difficult problem to solve generally.

Dave
kamani mohan krishna
2021-04-02 10:51:10 UTC
Permalink
Post by José Silva
I can use FindExecutable() function to know what application would be
launched by ShellExecute().
Can I know what is the hProcess for a given executable name? One of the
application that returned hProcess=NULL is the image viewer, my system call
the PhotoViewer.dll other examples are MDI applications. Can I know the
hProcess of an application launched with rundll32???
Is any other way to wait for an application to close only knowing its
executable name or dll?
Thanks
Hi Silva,

I am also facing the same issue when I want to open an image with ShellExecuteEx,
It is launching the image through photos application, but returning hProcess=NULL.
If I open the image in edit mode it is opening the image with paint and returning hProcess value properly. But I want to open the image through Photos application and need to wait till the application closes.
If you found the solution to this please let me know.

Thanks
Mohan

José Silva
2009-04-28 17:04:33 UTC
Permalink
I get documents from a remote database, I copy them to the local machine,
then I open them with the associated viewer. When the viewer closes, I write
the file back to the database.
Do you think its a bad idea using the ShellExecute and waiting process to
close?? What other ideas you have to achieve this goal???

It is known that ShellExecute not always returns hProcess filled. This is
not a bug. This happens when ShellExecute does not launch a process. For
instance if you launch an html file and IE is already open, it creates a new
tab under IE and ShellExecute does not return hProcess.

As you suggest I had a bad idea if you have better ideas they are wellcome.

Best regards,
José Silva
Post by Joseph M. Newcomer
See below...
Post by José Silva
I am writing an application that launches the viewer for the file to be
opened and then waits this application to close.
****
That is almost certainly a Bad Idea. Why do you want to do this? It wil hang the process
that launched it, making it exhibit seriously bad behavior as far as the user is
concerned. Don't do it this way.
****
Post by José Silva
I am launching application using ShellExecuteEx() then I use hProcess
returned in ShellExecute to wait for the application. It happens that some
applications does not return hProcess filled. However I want to wait for
that application to close.
*****
This does seem odd. If ShellExecuteEx returns, the handle should be correct. This sounds
like a ShellExecute bug. Can you get a simple case that demonstrates it?
It should be
reported via the Connect website.
****
Post by José Silva
The question is, how can I determine if application as closed for the
situations where ShellExecuteEx returns NULL on hProcess?
****
You can't. But I seriously suggest rethinking the approach. Blocking a process for an
unbounded time is usually a Really Bad Idea under nearly all conditions.
joe
*****
Post by José Silva
Many thanks.
Joseph M. Newcomer [MVP]
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Joseph M. Newcomer
2009-04-28 19:59:20 UTC
Permalink
"Viewer" implies "read-only". "Editor" has a different meaning.

You could watch for the local file to change, and based on that change, could write them
back. But it is clear from the specification of ShellExecuteEx that you can never
reliably tell when the editor has "finished" with them. The notion that "finished" is
equivalent to "process terminated" is where you are making your design error. As is made
clear from the description of the hProcess member, there is NO guaranteed correlation
between the concept of process and the concept of viewing (or editing).

Consider the following scenario:
======================
You download a .doc file.

You launch and get a handle to the Word process.

You wait for the Word process to terminate.

In order to edit the document, I have to open three other Word files. I do so.

I save the updated document and close it.

I have three other Word files open. Word does not exit. Word may not exit, ever.
======================

The notion that people actually "exit" programs is an error, anyway! I might close the
file but not exit Word. In fact, I right now have three open PowerPoint presentations,
five open Word files and two open Excel spreadsheets. The versions of PowerPoint, Word,
and Excel have been, literally, running for MONTHS. Perhaps when I download the next set
of Windows updates, these programs will close as part of the reboot cycle. But the bottom
line is that you are basing your decision on a non-credible premise, that (a) the viewer
is not already open and (b) having opened it to process a document, the user will actually
*exit* the viewer upon completion of editing the document. Both of these are not
practical in the Real World. Your expectations are not reasonable, so implementing
something that can be satisified by a user meeting these unrealistic expectations is
unlikely to be successful. You have to think of a different approach. For example, using
ReadDirectoryChangesW looking for the FILE_ACTION_MODIFIED event might be one approach,
although not the only one possible. Furthermore, it wouldn't make sense to block your
program while waiting; all you really want is an asynchronous notification that the file
can be written back. This leads to the question of what happens if the user simply does a
"Save" of some intermediate state while editing?

Note that you should not use the word "viewer" to describe something that can change the
contents of a file. There would be no need to write back a file that was merely being
examined.
joe
Post by José Silva
I get documents from a remote database, I copy them to the local machine,
then I open them with the associated viewer. When the viewer closes, I write
the file back to the database.
Do you think its a bad idea using the ShellExecute and waiting process to
close?? What other ideas you have to achieve this goal???
It is known that ShellExecute not always returns hProcess filled. This is
not a bug. This happens when ShellExecute does not launch a process. For
instance if you launch an html file and IE is already open, it creates a new
tab under IE and ShellExecute does not return hProcess.
As you suggest I had a bad idea if you have better ideas they are wellcome.
Best regards,
José Silva
Post by Joseph M. Newcomer
See below...
Post by José Silva
I am writing an application that launches the viewer for the file to be
opened and then waits this application to close.
****
That is almost certainly a Bad Idea. Why do you want to do this? It wil
hang the process
that launched it, making it exhibit seriously bad behavior as far as the user is
concerned. Don't do it this way.
****
Post by José Silva
I am launching application using ShellExecuteEx() then I use hProcess
returned in ShellExecute to wait for the application. It happens that some
applications does not return hProcess filled. However I want to wait for
that application to close.
*****
This does seem odd. If ShellExecuteEx returns, the handle should be
correct. This sounds
like a ShellExecute bug. Can you get a simple case that demonstrates it?
It should be
reported via the Connect website.
****
Post by José Silva
The question is, how can I determine if application as closed for the
situations where ShellExecuteEx returns NULL on hProcess?
****
You can't. But I seriously suggest rethinking the approach. Blocking a process for an
unbounded time is usually a Really Bad Idea under nearly all conditions.
joe
*****
Post by José Silva
Many thanks.
Joseph M. Newcomer [MVP]
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Joseph M. Newcomer [MVP]
email: ***@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
José Silva
2009-04-28 22:04:19 UTC
Permalink
You are sure, finished is not equivalent to process terminated, but "process
terminated" means document is saved. With that I mean when user closes all
instances of WinWord, I am sure that the file is already saved with all
modifications.
So, if I launch an application that do not return hProcess, I need to do
some work:
1) Verify what executable or dll was launched (use FindExecutable()).
2) ??? (what I really need) Know the process id of the previously launched
application.
3) Wait for that application to close.

The remainding considerations about how user uses Word, Powerpoint,... are
not important because my application is really blocked and if user wants to
continue he have to close the application (this behaviour would be described
in manuals, dialog boxes alerting of that, etc...). Soon users would
understand that for some applications they should really close them for
continuing using my application. In fact WinWord is like a modal dialog box,
that should be closed to continue using application.

I am sure there is a solution for someone that is trying to use Document
Editor (for instance WinWord) as it was a modal dialog box (I open it, and
wait user to close it), and that is what I am asking for.

Thanks.
Post by Joseph M. Newcomer
"Viewer" implies "read-only". "Editor" has a different meaning.
You could watch for the local file to change, and based on that change, could write them
back. But it is clear from the specification of ShellExecuteEx that you can never
reliably tell when the editor has "finished" with them. The notion that "finished" is
equivalent to "process terminated" is where you are making your design error. As is made
clear from the description of the hProcess member, there is NO guaranteed correlation
between the concept of process and the concept of viewing (or editing).
======================
You download a .doc file.
You launch and get a handle to the Word process.
You wait for the Word process to terminate.
In order to edit the document, I have to open three other Word files. I do so.
I save the updated document and close it.
I have three other Word files open. Word does not exit. Word may not exit, ever.
======================
The notion that people actually "exit" programs is an error, anyway! I might close the
file but not exit Word. In fact, I right now have three open PowerPoint presentations,
five open Word files and two open Excel spreadsheets. The versions of PowerPoint, Word,
and Excel have been, literally, running for MONTHS. Perhaps when I download the next set
of Windows updates, these programs will close as part of the reboot cycle.
But the bottom
line is that you are basing your decision on a non-credible premise, that (a) the viewer
is not already open and (b) having opened it to process a document, the user will actually
*exit* the viewer upon completion of editing the document. Both of these are not
practical in the Real World. Your expectations are not reasonable, so implementing
something that can be satisified by a user meeting these unrealistic expectations is
unlikely to be successful. You have to think of a different approach.
For example, using
ReadDirectoryChangesW looking for the FILE_ACTION_MODIFIED event might be one approach,
although not the only one possible. Furthermore, it wouldn't make sense to block your
program while waiting; all you really want is an asynchronous notification that the file
can be written back. This leads to the question of what happens if the user simply does a
"Save" of some intermediate state while editing?
Note that you should not use the word "viewer" to describe something that can change the
contents of a file. There would be no need to write back a file that was merely being
examined.
joe
Post by José Silva
I get documents from a remote database, I copy them to the local machine,
then I open them with the associated viewer. When the viewer closes, I write
the file back to the database.
Do you think its a bad idea using the ShellExecute and waiting process to
close?? What other ideas you have to achieve this goal???
It is known that ShellExecute not always returns hProcess filled. This is
not a bug. This happens when ShellExecute does not launch a process. For
instance if you launch an html file and IE is already open, it creates a new
tab under IE and ShellExecute does not return hProcess.
As you suggest I had a bad idea if you have better ideas they are wellcome.
Best regards,
José Silva
Post by Joseph M. Newcomer
See below...
Post by José Silva
I am writing an application that launches the viewer for the file to be
opened and then waits this application to close.
****
That is almost certainly a Bad Idea. Why do you want to do this? It wil
hang the process
that launched it, making it exhibit seriously bad behavior as far as the user is
concerned. Don't do it this way.
****
Post by José Silva
I am launching application using ShellExecuteEx() then I use hProcess
returned in ShellExecute to wait for the application. It happens that some
applications does not return hProcess filled. However I want to wait for
that application to close.
*****
This does seem odd. If ShellExecuteEx returns, the handle should be
correct. This sounds
like a ShellExecute bug. Can you get a simple case that demonstrates it?
It should be
reported via the Connect website.
****
Post by José Silva
The question is, how can I determine if application as closed for the
situations where ShellExecuteEx returns NULL on hProcess?
****
You can't. But I seriously suggest rethinking the approach. Blocking a process for an
unbounded time is usually a Really Bad Idea under nearly all conditions.
joe
*****
Post by José Silva
Many thanks.
Joseph M. Newcomer [MVP]
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Joseph M. Newcomer [MVP]
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Joseph M. Newcomer
2009-04-29 01:06:07 UTC
Permalink
See below...
Post by José Silva
You are sure, finished is not equivalent to process terminated, but "process
terminated" means document is saved. With that I mean when user closes all
instances of WinWord, I am sure that the file is already saved with all
modifications.
****
Note that I would never close Word, and it is therefore meaningless to wait for it to
close. It could be months. Seriously.
****
Post by José Silva
So, if I launch an application that do not return hProcess, I need to do
1) Verify what executable or dll was launched (use FindExecutable()).
****
The problem is that you don't know if you find the executable if it is the executable that
is working with your data. I could have nine other instances of some program running. You
have no idea which one is yours. Note that if it was launched, you would get a non-NULL
hProcess, which still doesn't help you much. If it was already launched, you only know
that everyhing is saved if the process terminates; you have no idea if the process will
*ever* terminate.
****
Post by José Silva
2) ??? (what I really need) Know the process id of the previously launched
application.
3) Wait for that application to close.
****
How many months do you expect to wait? Will you have a timeout after a year?

Note that if the user is shutting down, your program may be terminated before the program
whose termination you are waiting for.

The basic idea is flawed. You are making assumptions which cannot be valid; the *only*
thing you might have some confidence in is the fact that, in the unlikely event the
program closes, the processing of the document is complete. You cannot predicate the
success of your program in the trust that this will happen.
****
Post by José Silva
The remainding considerations about how user uses Word, Powerpoint,... are
not important because my application is really blocked and if user wants to
continue he have to close the application (this behaviour would be described
in manuals, dialog boxes alerting of that, etc...). Soon users would
understand that for some applications they should really close them for
continuing using my application. In fact WinWord is like a modal dialog box,
that should be closed to continue using application.
****
It is a poor design. You would force me to exit Word just to satisfy your bad design?
That is unacceptable, and you will find serious resistance to the idea once you deploy. My
successful use of Word should not be predicated on satisfying the bad design of some other
program. Note also that blocking the main GUI thread of your app while waiting for some
other app to finish is beyond poor design, and is more to be pitied than sanctioned. XP or
Vista will determine your program is non-responsive and ask the user if your app should be
killed.

Your design is deeply flawed. You need to rethink what you are doing. It simply doesn't
make sense.
****
Post by José Silva
I am sure there is a solution for someone that is trying to use Document
Editor (for instance WinWord) as it was a modal dialog box (I open it, and
wait user to close it), and that is what I am asking for.
****
I don't even understand this sentence. WHo has a modal dialog box? How is it that I can
see it? I think you are trying to build a design that actively works against how both
WIndows and users work. As such, the design is doomed. Better to figure that out now,
before you waste time building something that cannot work and will merely create ill will
with the end users.
joe
*****
Post by José Silva
Thanks.
Post by Joseph M. Newcomer
"Viewer" implies "read-only". "Editor" has a different meaning.
You could watch for the local file to change, and based on that change, could write them
back. But it is clear from the specification of ShellExecuteEx that you can never
reliably tell when the editor has "finished" with them. The notion that "finished" is
equivalent to "process terminated" is where you are making your design error. As is made
clear from the description of the hProcess member, there is NO guaranteed correlation
between the concept of process and the concept of viewing (or editing).
======================
You download a .doc file.
You launch and get a handle to the Word process.
You wait for the Word process to terminate.
In order to edit the document, I have to open three other Word files. I do so.
I save the updated document and close it.
I have three other Word files open. Word does not exit. Word may not exit, ever.
======================
The notion that people actually "exit" programs is an error, anyway! I might close the
file but not exit Word. In fact, I right now have three open PowerPoint presentations,
five open Word files and two open Excel spreadsheets. The versions of PowerPoint, Word,
and Excel have been, literally, running for MONTHS. Perhaps when I download the next set
of Windows updates, these programs will close as part of the reboot cycle.
But the bottom
line is that you are basing your decision on a non-credible premise, that (a) the viewer
is not already open and (b) having opened it to process a document, the
user will actually
*exit* the viewer upon completion of editing the document. Both of these are not
practical in the Real World. Your expectations are not reasonable, so implementing
something that can be satisified by a user meeting these unrealistic expectations is
unlikely to be successful. You have to think of a different approach.
For example, using
ReadDirectoryChangesW looking for the FILE_ACTION_MODIFIED event might be one approach,
although not the only one possible. Furthermore, it wouldn't make sense to block your
program while waiting; all you really want is an asynchronous notification that the file
can be written back. This leads to the question of what happens if the
user simply does a
"Save" of some intermediate state while editing?
Note that you should not use the word "viewer" to describe something that can change the
contents of a file. There would be no need to write back a file that was merely being
examined.
joe
Post by José Silva
I get documents from a remote database, I copy them to the local machine,
then I open them with the associated viewer. When the viewer closes, I write
the file back to the database.
Do you think its a bad idea using the ShellExecute and waiting process to
close?? What other ideas you have to achieve this goal???
It is known that ShellExecute not always returns hProcess filled. This is
not a bug. This happens when ShellExecute does not launch a process. For
instance if you launch an html file and IE is already open, it creates a new
tab under IE and ShellExecute does not return hProcess.
As you suggest I had a bad idea if you have better ideas they are wellcome.
Best regards,
José Silva
Post by Joseph M. Newcomer
See below...
Post by José Silva
I am writing an application that launches the viewer for the file to be
opened and then waits this application to close.
****
That is almost certainly a Bad Idea. Why do you want to do this? It wil
hang the process
that launched it, making it exhibit seriously bad behavior as far as the user is
concerned. Don't do it this way.
****
Post by José Silva
I am launching application using ShellExecuteEx() then I use hProcess
returned in ShellExecute to wait for the application. It happens that some
applications does not return hProcess filled. However I want to wait for
that application to close.
*****
This does seem odd. If ShellExecuteEx returns, the handle should be
correct. This sounds
like a ShellExecute bug. Can you get a simple case that demonstrates it?
It should be
reported via the Connect website.
****
Post by José Silva
The question is, how can I determine if application as closed for the
situations where ShellExecuteEx returns NULL on hProcess?
****
You can't. But I seriously suggest rethinking the approach. Blocking a
process for an
unbounded time is usually a Really Bad Idea under nearly all conditions.
joe
*****
Post by José Silva
Many thanks.
Joseph M. Newcomer [MVP]
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Joseph M. Newcomer [MVP]
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Joseph M. Newcomer [MVP]
email: ***@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
José Silva
2009-04-29 07:26:10 UTC
Permalink
Joseph is only concerned in convincing me that this is not a good solution,
not in getting an answer for a simple question.

Meanwhile I think I encountered the answer, that stays here for some others
who have the same stupid need I have:

Use CreateProcess() instead of ShellExecute().
CreateProcess() always returns hProcess. Then, simply call
WaitForSingleObject(hProcess, INFINITE) - a function created by microsoft
specially for me that have this strange idea of waiting for applications to
close.

Thanks for all.
Post by Joseph M. Newcomer
See below...
Post by José Silva
You are sure, finished is not equivalent to process terminated, but "process
terminated" means document is saved. With that I mean when user closes all
instances of WinWord, I am sure that the file is already saved with all
modifications.
****
Note that I would never close Word, and it is therefore meaningless to wait for it to
close. It could be months. Seriously.
****
Post by José Silva
So, if I launch an application that do not return hProcess, I need to do
1) Verify what executable or dll was launched (use FindExecutable()).
****
The problem is that you don't know if you find the executable if it is the executable that
is working with your data. I could have nine other instances of some program running. You
have no idea which one is yours. Note that if it was launched, you would get a non-NULL
hProcess, which still doesn't help you much. If it was already launched, you only know
that everyhing is saved if the process terminates; you have no idea if the process will
*ever* terminate.
****
Post by José Silva
2) ??? (what I really need) Know the process id of the previously launched
application.
3) Wait for that application to close.
****
How many months do you expect to wait? Will you have a timeout after a year?
Note that if the user is shutting down, your program may be terminated before the program
whose termination you are waiting for.
The basic idea is flawed. You are making assumptions which cannot be valid; the *only*
thing you might have some confidence in is the fact that, in the unlikely event the
program closes, the processing of the document is complete. You cannot predicate the
success of your program in the trust that this will happen.
****
Post by José Silva
The remainding considerations about how user uses Word, Powerpoint,... are
not important because my application is really blocked and if user wants to
continue he have to close the application (this behaviour would be described
in manuals, dialog boxes alerting of that, etc...). Soon users would
understand that for some applications they should really close them for
continuing using my application. In fact WinWord is like a modal dialog box,
that should be closed to continue using application.
****
It is a poor design. You would force me to exit Word just to satisfy your bad design?
That is unacceptable, and you will find serious resistance to the idea once you deploy. My
successful use of Word should not be predicated on satisfying the bad design of some other
program. Note also that blocking the main GUI thread of your app while waiting for some
other app to finish is beyond poor design, and is more to be pitied than sanctioned. XP or
Vista will determine your program is non-responsive and ask the user if your app should be
killed.
Your design is deeply flawed. You need to rethink what you are doing. It simply doesn't
make sense.
****
Post by José Silva
I am sure there is a solution for someone that is trying to use Document
Editor (for instance WinWord) as it was a modal dialog box (I open it, and
wait user to close it), and that is what I am asking for.
****
I don't even understand this sentence. WHo has a modal dialog box? How is it that I can
see it? I think you are trying to build a design that actively works against how both
WIndows and users work. As such, the design is doomed. Better to figure that out now,
before you waste time building something that cannot work and will merely create ill will
with the end users.
joe
*****
Post by José Silva
Thanks.
Post by Joseph M. Newcomer
"Viewer" implies "read-only". "Editor" has a different meaning.
You could watch for the local file to change, and based on that change,
could write them
back. But it is clear from the specification of ShellExecuteEx that you can never
reliably tell when the editor has "finished" with them. The notion that "finished" is
equivalent to "process terminated" is where you are making your design
error. As is made
clear from the description of the hProcess member, there is NO
guaranteed
correlation
between the concept of process and the concept of viewing (or editing).
======================
You download a .doc file.
You launch and get a handle to the Word process.
You wait for the Word process to terminate.
In order to edit the document, I have to open three other Word files. I do so.
I save the updated document and close it.
I have three other Word files open. Word does not exit. Word may not exit, ever.
======================
The notion that people actually "exit" programs is an error, anyway! I might close the
file but not exit Word. In fact, I right now have three open PowerPoint presentations,
five open Word files and two open Excel spreadsheets. The versions of
PowerPoint, Word,
and Excel have been, literally, running for MONTHS. Perhaps when I
download the next set
of Windows updates, these programs will close as part of the reboot cycle.
But the bottom
line is that you are basing your decision on a non-credible premise,
that
(a) the viewer
is not already open and (b) having opened it to process a document, the
user will actually
*exit* the viewer upon completion of editing the document. Both of
these
are not
practical in the Real World. Your expectations are not reasonable, so implementing
something that can be satisified by a user meeting these unrealistic expectations is
unlikely to be successful. You have to think of a different approach.
For example, using
ReadDirectoryChangesW looking for the FILE_ACTION_MODIFIED event might
be
one approach,
although not the only one possible. Furthermore, it wouldn't make sense to block your
program while waiting; all you really want is an asynchronous
notification
that the file
can be written back. This leads to the question of what happens if the
user simply does a
"Save" of some intermediate state while editing?
Note that you should not use the word "viewer" to describe something
that
can change the
contents of a file. There would be no need to write back a file that
was
merely being
examined.
joe
Post by José Silva
I get documents from a remote database, I copy them to the local machine,
then I open them with the associated viewer. When the viewer closes, I write
the file back to the database.
Do you think its a bad idea using the ShellExecute and waiting process to
close?? What other ideas you have to achieve this goal???
It is known that ShellExecute not always returns hProcess filled. This is
not a bug. This happens when ShellExecute does not launch a process. For
instance if you launch an html file and IE is already open, it creates a new
tab under IE and ShellExecute does not return hProcess.
As you suggest I had a bad idea if you have better ideas they are wellcome.
Best regards,
José Silva
Post by Joseph M. Newcomer
See below...
Post by José Silva
I am writing an application that launches the viewer for the file to be
opened and then waits this application to close.
****
That is almost certainly a Bad Idea. Why do you want to do this? It wil
hang the process
that launched it, making it exhibit seriously bad behavior as far as
the
user is
concerned. Don't do it this way.
****
Post by José Silva
I am launching application using ShellExecuteEx() then I use hProcess
returned in ShellExecute to wait for the application. It happens that some
applications does not return hProcess filled. However I want to wait for
that application to close.
*****
This does seem odd. If ShellExecuteEx returns, the handle should be
correct. This sounds
like a ShellExecute bug. Can you get a simple case that demonstrates it?
It should be
reported via the Connect website.
****
Post by José Silva
The question is, how can I determine if application as closed for the
situations where ShellExecuteEx returns NULL on hProcess?
****
You can't. But I seriously suggest rethinking the approach. Blocking a
process for an
unbounded time is usually a Really Bad Idea under nearly all conditions.
joe
*****
Post by José Silva
Many thanks.
Joseph M. Newcomer [MVP]
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Joseph M. Newcomer [MVP]
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Joseph M. Newcomer [MVP]
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Joseph M. Newcomer
2009-04-29 18:45:50 UTC
Permalink
Post by José Silva
Joseph is only concerned in convincing me that this is not a good solution,
not in getting an answer for a simple question.
Yes. Because it is not a "simple" question. It is a question that does not have a valid
answer, and by asking it, you are requiring that impossible situations shall exist.
Post by José Silva
Meanwhile I think I encountered the answer, that stays here for some others
Use CreateProcess() instead of ShellExecute().
CreateProcess() always returns hProcess. Then, simply call
WaitForSingleObject(hProcess, INFINITE) - a function created by microsoft
specially for me that have this strange idea of waiting for applications to
close.
Note that CreateProcess can only execute .exe files; if you give it a .doc file, a .txt
file, a URL, etc., then it cannot cause the correct program to execute.

Furthermore, it still doesn't work right. For example, if you CreateProcess on
WinWord.exe, WinWord will discover that there is already another WinWord running, will use
DDE or automation to inform the already-running application to open up the document, and
then the process you just launched will kill itself. So you will get a notification that
the process terminated, but in fact the *document* you are editing *has not even been seen
by the user yet*. See what I mean about not being a "simple" answer. You are making
naive assumptions that simply do not hold up in real life, and expecting that somehow the
world is going to come into correspondence with your naive assumptions, which it will not
do.

So your solution cannot work. You are deluding yourself. Of course, I knew this solution
would not work, which is why I didn't propose it. How is it you think that ShellExecuteEx
knows to return NULL for the handle of the process, as described in the documentation?
Simple: the process exits before going into its message pump. It knows this because it is
also doing a WaitForInputIdle; if the created process enters input-idle mode, then it has
come up for the first time, and the hProcess is set to indicate the process handle
returned by CreateProcess. If the process terminates without achieving the input-idle
state, ShellExecuteEx sets the hProcess to NULL, because it knows the responsibility has
been handed off to an existing process whose handle it cannot find out.

But since you obviously need proof that you are wrong, I suggest you try the following
code. I used this as a simple little program called runword.

First, I ran Microsoft Word and created a little file called test.docx in that directory.
Then I exited Word.

Next I created a command shell, changed to the Debug directory for the project, and typed
runword

This launched Word with a blank document. I typed something into the document. Then I
launched another command shell, command shell 2, and typed
runword test.docx

The results are shown below.

You are wrong, and I am right, and the proof is easily demonstrated by looking at the
resulting output! The difference is that I already knew what was going to happen, and you
remain clueless and apparently wish to stay that way. Your code will not work, as this
example demonstrates beyond any shadow of a doubt. CreateProcess will not solve your
problem, because it is based on an erroneous assumption that I already knew would be
erroneous, and therefore I would not have wasted your time proposing a solution that
cannot possibly work. You apparently, having discovered a tiny piece of the solution and
not having understood either the implications of the solution you propose, have gone off
blindly thinking you have a solution. You don't.

=============================================================
int _tmain(int argc, _TCHAR* argv[])
{
STARTUPINFO startup = {sizeof(STARTUPINFO) } ;
PROCESS_INFORMATION pi;

TCHAR cmd[1024];
_tcscpy_s(cmd, _countof(cmd), _T("\"c:\\Program Files\\Microsoft
Office\\Office12\\winword.exe\""));
if(argc > 1)
{
_tcscat_s(cmd, _countof(cmd) - _tcslen(cmd), _T(" "));
_tcscat_s(cmd, _countof(cmd) - _tcslen(cmd), argv[1]);
}

BOOL result = CreateProcess(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &startup,
&pi);
if(result)
{ /* started */
_tprintf(_T("%08u started \"%s\"\n"), GetCurrentProcessId(), cmd);
::WaitForSingleObject(pi.hProcess, INFINITE);
_tprintf(_T("%08u program exited\n"), GetCurrentProcessId());
::CloseHandle(pi.hProcess);
::CloseHandle(pi.hThread);
} /* started */
else
{ /* failed */
DWORD err = ::GetLastError();
_tprintf(_T("%08u failed to start \"%s\"\n"), GetCurrentProcessId(), cmd);
} /* failed */
return 0;
}
===========================================================

Command shell 1:

Microsoft Windows [Version 6.0.6001]
Copyright (c) 2006 Microsoft Corporation. All rights reserved.

C:\Users\flounder.KIRTLAND2>cd c:\tests\runword\debug

c:\tests\runword\debug>runword
00003544 started ""c:\Program Files\Microsoft Office\Office12\winword.exe""

===========================================================
Type something into the empty document

===========================================================
Command shell 2:

Copyright (c) 2006 Microsoft Corporation. All rights reserved.

C:\Users\flounder.KIRTLAND2>cd c:\tests\runword\debug

c:\tests\runword\debug>dir
Volume in drive C is Vista32
Volume Serial Number is 4025-0AC8

Directory of c:\tests\runword\debug

04/29/2009 02:19 PM <DIR> .
04/29/2009 02:19 PM <DIR> ..
04/29/2009 02:12 PM 40,960 runword.exe
04/29/2009 02:12 PM 326,836 runword.ilk
04/29/2009 02:12 PM 1,289,216 runword.pdb
04/29/2009 02:15 PM 11,123 test.docx
4 File(s) 1,668,135 bytes
2 Dir(s) 78,498,566,144 bytes free

c:\tests\runword\debug>runword test.docx
00007216 started ""c:\Program Files\Microsoft Office\Office12\winword.exe" test.docx"
00007216 program exited

c:\tests\runword\debug>
=====================================================
Note that although the process exited, test.docx IS STILL OPEN. In fact, I can now edit
it, make changes in it, and save it. So what you would write back upon process completion
is meaningless, because I have not had a chance to actually do any editing.

=====================================================
Close test.docx:

Nothing happens in command shell 1. The process is still running, so the WFSO is still
blocked.


====================================================
Close the document into which you had typed something. Note that this is the last
document that was open.

In command shell 1 you see:

00003544 program exited

c:\tests\runword\debug>
====================================================
Q.E.D.
joe
Post by José Silva
Thanks for all.
Post by Joseph M. Newcomer
See below...
Post by José Silva
You are sure, finished is not equivalent to process terminated, but "process
terminated" means document is saved. With that I mean when user closes all
instances of WinWord, I am sure that the file is already saved with all
modifications.
****
Note that I would never close Word, and it is therefore meaningless to wait for it to
close. It could be months. Seriously.
****
Post by José Silva
So, if I launch an application that do not return hProcess, I need to do
1) Verify what executable or dll was launched (use FindExecutable()).
****
The problem is that you don't know if you find the executable if it is the
executable that
is working with your data. I could have nine other instances of some
program running. You
have no idea which one is yours. Note that if it was launched, you would get a non-NULL
hProcess, which still doesn't help you much. If it was already launched, you only know
that everyhing is saved if the process terminates; you have no idea if the process will
*ever* terminate.
****
Post by José Silva
2) ??? (what I really need) Know the process id of the previously launched
application.
3) Wait for that application to close.
****
How many months do you expect to wait? Will you have a timeout after a year?
Note that if the user is shutting down, your program may be terminated before the program
whose termination you are waiting for.
The basic idea is flawed. You are making assumptions which cannot be valid; the *only*
thing you might have some confidence in is the fact that, in the unlikely event the
program closes, the processing of the document is complete. You cannot predicate the
success of your program in the trust that this will happen.
****
Post by José Silva
The remainding considerations about how user uses Word, Powerpoint,... are
not important because my application is really blocked and if user wants to
continue he have to close the application (this behaviour would be described
in manuals, dialog boxes alerting of that, etc...). Soon users would
understand that for some applications they should really close them for
continuing using my application. In fact WinWord is like a modal dialog box,
that should be closed to continue using application.
****
It is a poor design. You would force me to exit Word just to satisfy your bad design?
That is unacceptable, and you will find serious resistance to the idea
once you deploy. My
successful use of Word should not be predicated on satisfying the bad
design of some other
program. Note also that blocking the main GUI thread of your app while waiting for some
other app to finish is beyond poor design, and is more to be pitied than
sanctioned. XP or
Vista will determine your program is non-responsive and ask the user if
your app should be
killed.
Your design is deeply flawed. You need to rethink what you are doing. It simply doesn't
make sense.
****
Post by José Silva
I am sure there is a solution for someone that is trying to use Document
Editor (for instance WinWord) as it was a modal dialog box (I open it, and
wait user to close it), and that is what I am asking for.
****
I don't even understand this sentence. WHo has a modal dialog box? How is it that I can
see it? I think you are trying to build a design that actively works against how both
WIndows and users work. As such, the design is doomed. Better to figure that out now,
before you waste time building something that cannot work and will merely create ill will
with the end users.
joe
*****
Post by José Silva
Thanks.
Post by Joseph M. Newcomer
"Viewer" implies "read-only". "Editor" has a different meaning.
You could watch for the local file to change, and based on that change,
could write them
back. But it is clear from the specification of ShellExecuteEx that you can never
reliably tell when the editor has "finished" with them. The notion that
"finished" is
equivalent to "process terminated" is where you are making your design
error. As is made
clear from the description of the hProcess member, there is NO
guaranteed
correlation
between the concept of process and the concept of viewing (or editing).
======================
You download a .doc file.
You launch and get a handle to the Word process.
You wait for the Word process to terminate.
In order to edit the document, I have to open three other Word files. I do so.
I save the updated document and close it.
I have three other Word files open. Word does not exit. Word may not exit, ever.
======================
The notion that people actually "exit" programs is an error, anyway! I
might close the
file but not exit Word. In fact, I right now have three open PowerPoint
presentations,
five open Word files and two open Excel spreadsheets. The versions of
PowerPoint, Word,
and Excel have been, literally, running for MONTHS. Perhaps when I
download the next set
of Windows updates, these programs will close as part of the reboot cycle.
But the bottom
line is that you are basing your decision on a non-credible premise,
that
(a) the viewer
is not already open and (b) having opened it to process a document, the
user will actually
*exit* the viewer upon completion of editing the document. Both of
these
are not
practical in the Real World. Your expectations are not reasonable, so implementing
something that can be satisified by a user meeting these unrealistic expectations is
unlikely to be successful. You have to think of a different approach.
For example, using
ReadDirectoryChangesW looking for the FILE_ACTION_MODIFIED event might
be
one approach,
although not the only one possible. Furthermore, it wouldn't make sense
to block your
program while waiting; all you really want is an asynchronous
notification
that the file
can be written back. This leads to the question of what happens if the
user simply does a
"Save" of some intermediate state while editing?
Note that you should not use the word "viewer" to describe something
that
can change the
contents of a file. There would be no need to write back a file that
was
merely being
examined.
joe
Post by José Silva
I get documents from a remote database, I copy them to the local machine,
then I open them with the associated viewer. When the viewer closes, I write
the file back to the database.
Do you think its a bad idea using the ShellExecute and waiting process to
close?? What other ideas you have to achieve this goal???
It is known that ShellExecute not always returns hProcess filled. This is
not a bug. This happens when ShellExecute does not launch a process. For
instance if you launch an html file and IE is already open, it creates a new
tab under IE and ShellExecute does not return hProcess.
As you suggest I had a bad idea if you have better ideas they are wellcome.
Best regards,
José Silva
Post by Joseph M. Newcomer
See below...
Post by José Silva
I am writing an application that launches the viewer for the file to be
opened and then waits this application to close.
****
That is almost certainly a Bad Idea. Why do you want to do this? It wil
hang the process
that launched it, making it exhibit seriously bad behavior as far as
the
user is
concerned. Don't do it this way.
****
Post by José Silva
I am launching application using ShellExecuteEx() then I use hProcess
returned in ShellExecute to wait for the application. It happens that some
applications does not return hProcess filled. However I want to wait for
that application to close.
*****
This does seem odd. If ShellExecuteEx returns, the handle should be
correct. This sounds
like a ShellExecute bug. Can you get a simple case that demonstrates it?
It should be
reported via the Connect website.
****
Post by José Silva
The question is, how can I determine if application as closed for the
situations where ShellExecuteEx returns NULL on hProcess?
****
You can't. But I seriously suggest rethinking the approach. Blocking a
process for an
unbounded time is usually a Really Bad Idea under nearly all conditions.
joe
*****
Post by José Silva
Many thanks.
Joseph M. Newcomer [MVP]
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Joseph M. Newcomer [MVP]
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Joseph M. Newcomer [MVP]
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Joseph M. Newcomer [MVP]
email: ***@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Joseph M. Newcomer
2009-04-29 22:02:02 UTC
Permalink
I can't resist. This is the only accurate statement you've made about your design.

By the way, it took me less than 20 minutes to prove your solution cannot work. It took
me longer to track down the path to WinWord than to write the failing code.
joe
Joseph M. Newcomer [MVP]
email: ***@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Goran
2009-04-29 09:06:30 UTC
Permalink
Post by José Silva
Joseph is only concerned in convincing me that
this is not a good solution, not in getting an answer for a simple question.
But it's not a simple question at all, it's more that you don't see
the complexities!

Joe is right in every way telling you that there are use-cases you
don't cover. What if you use ShellExecute to launch Word, but it's
already running; it displays your document. Say that you __do__ get
hProcess from ShellExecute. Your user saves and closes the document.
Yet, Word is __still running__ because there's another *.doc file
open, completely unrelated to what you're doing. Your code hangs. Is
that what you want to achieve?

(Here, in case of Word, you should probably use COM. Open document
through COM, attach to Document.CloseEvent and wait for that. See e.g.
http://msdn.microsoft.com/en-us/library/microsoft.office.tools.word.document.closeevent(VS.80).aspx.
But that's specific to Word and you won't get that for all your
"viewers".)

Instead, how about offering your users a "Next" button. That way, they
can do whatever they want, when done, one click on "Next", presto, all
good and well. If you poop the word open, when they close it (simple
scenario), your button will be sitting there one click away. Not that
this way you can give your users possibility to cancel changes at the
last moment (e.g. by adding "Skip my last changes" button). (Do you
check that the file is modified after opening BTW? 'cause if not,
perhaps it's a bad idea to try to write them back).

HTH,
Goran.
José Silva
2009-04-30 09:00:07 UTC
Permalink
This post might be inappropriate. Click to display it.
Geeky Badger
2009-04-30 13:53:24 UTC
Permalink
Wow Jose,

That's good information about the /n command line switch. Now all you
have to do it to prevent your users from opening up another document
using your separate copy of winword.

-GB
Post by José Silva
By the way, if I use /n switch to open word, it really opens a new word and
I can control the closing, but your suggestion is more global.
David Lowndes
2009-04-30 14:59:44 UTC
Permalink
Post by Geeky Badger
That's good information about the /n command line switch. Now all you
have to do it to prevent your users from opening up another document
using your separate copy of winword.
... and then start considering how to handle other applications that
don't behave like Word.

Dave
Joseph M. Newcomer
2009-04-30 15:02:47 UTC
Permalink
At least in the current version of Word. Maybe other Office apps. It applies to nothing
else. And it may not exist in the future. It may not have existed in the past (do you
know which version of Word/Office your users are using?)

Hacks, kludges, and wishful thinking do not create robust software. Robust design creates
robust software. How do you know the user has Office? Perhaps the user has a third-party
"universal viewer" that can look at .doc files. And it would have no such override.
joe
Post by José Silva
It is a good suggestion to use the buttons to go to next step after document
is saved.
By the way, if I use /n switch to open word, it really opens a new word and
I can control the closing, but your suggestion is more global.
Many thanks.
Post by Goran
Post by José Silva
Joseph is only concerned in convincing me that
this is not a good solution, not in getting an answer for a simple question.
But it's not a simple question at all, it's more that you don't see
the complexities!
Joe is right in every way telling you that there are use-cases you
don't cover. What if you use ShellExecute to launch Word, but it's
already running; it displays your document. Say that you __do__ get
hProcess from ShellExecute. Your user saves and closes the document.
Yet, Word is __still running__ because there's another *.doc file
open, completely unrelated to what you're doing. Your code hangs. Is
that what you want to achieve?
(Here, in case of Word, you should probably use COM. Open document
through COM, attach to Document.CloseEvent and wait for that. See e.g.
http://msdn.microsoft.com/en-us/library/microsoft.office.tools.word.document.closeevent(VS.80).aspx.
But that's specific to Word and you won't get that for all your
"viewers".)
Instead, how about offering your users a "Next" button. That way, they
can do whatever they want, when done, one click on "Next", presto, all
good and well. If you poop the word open, when they close it (simple
scenario), your button will be sitting there one click away. Not that
this way you can give your users possibility to cancel changes at the
last moment (e.g. by adding "Skip my last changes" button). (Do you
check that the file is modified after opening BTW? 'cause if not,
perhaps it's a bad idea to try to write them back).
HTH,
Goran.
Joseph M. Newcomer [MVP]
email: ***@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Loading...