Discussion:
ShellExecuteEx - WaitForSingleObject
(too old to reply)
Sinna
2006-08-02 11:42:54 UTC
Permalink
Hi,
Based on the code found at http://www.thescarms.com/VBasic/wait.asp, I
use WaitForSingleObject to get notification if a launched application
is closed. That piece of code works like a charm.
Now I want to mimick the Windows Explorer so the corresponding
application is launched for a given file (extension). To accomplish
SEE_MASK_NOCLOSEPROCESS Or SEE_MASK_FLAG_DDEWAIT Or _
SEE_MASK_DOENVSUBST Or SEE_MASK_FLAG_NO_UI Or _
SEE_MASK_UNICODE Or SEE_MASK_WAITFORINPUTIDLE
The documentation from the MSDN Library states that after a
successfull launch the hProcess parameter of the SHELLEXECUTEINFO
structure contains the handle to the process.
However, when I use the handle returned in the SHELLEXECUTEINFO
structure for the WaitForSingleObject call, the function returns
immediately with WAIT_OBJECT_0, regardless whether the application is
still running or not.
Private Declare Function WaitForSingleObject Lib "kernel32.dll" ( _
ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
Private Const INFINITE As Long = -1& ' Infinite interval
Private Const SEE_MASK_NOCLOSEPROCESS As Long = &H40
Private Const SEE_MASK_FLAG_DDEWAIT As Long = &H100
Private Const SEE_MASK_DOENVSUBST As Long = &H200
Private Const SEE_MASK_FLAG_NO_UI As Long = &H400
Private Const SEE_MASK_UNICODE As Long = &H4000
Private Const SEE_MASK_WAITFORINPUTIDLE As Long = &H2000000
Private Type SHELLEXECUTEINFO
cbSize As Long
fMask As Long
hWnd As Long
lpVerb As Long
lpFile As Long
lpParameters As Long
lpDirectory As Long
nShow As Long
hInstApp As Long
lpIDList As Long
lpClass As Long
hKeyClass As Long
dwHotKey As Long
hIcon As Long
hProcess As Long
End Type
Private Declare Function ShellExecuteEx Lib "shell32.dll" _
Alias "ShellExecuteExW" ( _
ByRef lpExecInfo As SHELLEXECUTEINFO) As Long
Note I use the Wide variant of the ShellExecuteEx call. This is a
requirement since I have to support unicode filenames.
TIA,
Sinna
Update!
It seems the issue only exists on WinXP systems. I've executed the code
on Win2K and Win2K3 without problems.
Can somebody confirm this?
Sinna
Update 2!

After some puzzling I found out that the function only fails in very
specific circumstances: when launching the ShellExecuteEx call with
lpVerb = "edit" and lpFile = StrPtr("foo.xml") the WaitForSingleObject
call returns immediately. In my case Notepad is launched.

If I launch the ShellExecuteEx call with another file (e.g. foo.txt)
everything works as expected.

Sinna
J French
2006-08-05 11:13:49 UTC
Permalink
On Wed, 02 Aug 2006 13:42:54 +0200, Sinna
<***@hotpop.com> wrote:

<snip>
Post by Sinna
Update!
It seems the issue only exists on WinXP systems. I've executed the code
on Win2K and Win2K3 without problems.
Can somebody confirm this?
Sinna
Update 2!
After some puzzling I found out that the function only fails in very
specific circumstances: when launching the ShellExecuteEx call with
lpVerb = "edit" and lpFile = StrPtr("foo.xml") the WaitForSingleObject
call returns immediately. In my case Notepad is launched.
If I launch the ShellExecuteEx call with another file (e.g. foo.txt)
everything works as expected.
Unless I am mistaken, you are asking ShellExecureEx to locate the
correct handler for the file, and then launch it.

Is there a handler for .xml files ?

The smart money is using FindExecutable to get the full path and name
of the EXE and control things directly.

Note that FindExecutable fails is a physical file does not exist on
disk, which has always struck me as rather silly.
Sinna
2006-08-07 06:32:46 UTC
Permalink
Post by J French
On Wed, 02 Aug 2006 13:42:54 +0200, Sinna
<snip>
Post by Sinna
Update!
It seems the issue only exists on WinXP systems. I've executed the code
on Win2K and Win2K3 without problems.
Can somebody confirm this?
Sinna
Update 2!
After some puzzling I found out that the function only fails in very
specific circumstances: when launching the ShellExecuteEx call with
lpVerb = "edit" and lpFile = StrPtr("foo.xml") the WaitForSingleObject
call returns immediately. In my case Notepad is launched.
If I launch the ShellExecuteEx call with another file (e.g. foo.txt)
everything works as expected.
Unless I am mistaken, you are asking ShellExecureEx to locate the
correct handler for the file, and then launch it.
Indeed, that is where I'm looking for. (But even more, I want to use the
hProcess property to monitor the launched application.)
Post by J French
Is there a handler for .xml files ?
Yes, on my system the default application is Internet Explorer, the
application for editing is Notepad (set by myself I think).
Post by J French
The smart money is using FindExecutable to get the full path and name
of the EXE and control things directly.
I'm aware of the FindExecutable API, but it doesn't fit for my
application unless I can specify that I want the application launched
for editing instead of opening a given file.
Note that in some cases FindExecutable fails to do its job properly.
I think it has something to do with the way some values are written into
the registry (quoting). Instead of returning the complete path only the
first part is retained (e.g.: 'C:\Program' instead of 'C:\Program
Files\foo).
Post by J French
Note that FindExecutable fails is a physical file does not exist on
disk, which has always struck me as rather silly.
This sounds familiar: SHGetFileInfo also fails if the physical file
doesn't exist.
Sinna
J French
2006-08-07 09:00:28 UTC
Permalink
On Mon, 07 Aug 2006 08:32:46 +0200, Sinna
<***@hotpop.com> wrote:


<snip>
Post by Sinna
Post by J French
Post by Sinna
If I launch the ShellExecuteEx call with another file (e.g. foo.txt)
everything works as expected.
Unless I am mistaken, you are asking ShellExecureEx to locate the
correct handler for the file, and then launch it.
Indeed, that is where I'm looking for. (But even more, I want to use the
hProcess property to monitor the launched application.)
Post by J French
Is there a handler for .xml files ?
Yes, on my system the default application is Internet Explorer, the
application for editing is Notepad (set by myself I think).
Post by J French
The smart money is using FindExecutable to get the full path and name
of the EXE and control things directly.
I'm aware of the FindExecutable API, but it doesn't fit for my
application unless I can specify that I want the application launched
for editing instead of opening a given file.
The 'verb' is something known by the App, it is just a convention set
by Windows that Apps may or may not follow
To be more accurate it is an exe and commandline that is stored in the
Registry
- I only see 'open' and 'print' for 'TxtFile'
- no 'edit' verb

You could check this out by replacing Notepad with a small EXE of the
same name that shows the Command Line

As for launching the App, you could use Shell, ShellExecute or
CreateProcess - personally I would use CreateProcess simply because
that is really what is going on anyway
Post by Sinna
Note that in some cases FindExecutable fails to do its job properly.
I think it has something to do with the way some values are written into
the registry (quoting). Instead of returning the complete path only the
first part is retained (e.g.: 'C:\Program' instead of 'C:\Program
Files\foo).
I see what you mean, but I'm rather surprized that it is a problem
- or rather any App that screws that up should screw up ShellExecute

The file path and name should be enclosed in quotes if it contains
spaces

You could cover that by fishing out the stuff from the Registry
yourself - but I would be inclined to regard such problems as a faulty
installation.
Post by Sinna
Post by J French
Note that FindExecutable fails is a physical file does not exist on
disk, which has always struck me as rather silly.
This sounds familiar: SHGetFileInfo also fails if the physical file
doesn't exist.
I can follow that, SHGetFileInfo needs to look at the file

However all FindExecutable does is root around in the Registry looking
for the associated EXE

Personally I dislike ShellExecute, it does not do very much, certainly
nothing more than one can easily do oneself, and when it goes wrong it
provides very little information.
Sinna
2006-08-07 12:03:11 UTC
Permalink
Post by J French
On Mon, 07 Aug 2006 08:32:46 +0200, Sinna
<snip>
Post by J French
Post by Sinna
Post by J French
The smart money is using FindExecutable to get the full path and name
of the EXE and control things directly.
I'm aware of the FindExecutable API, but it doesn't fit for my
application unless I can specify that I want the application launched
for editing instead of opening a given file.
The 'verb' is something known by the App, it is just a convention set
by Windows that Apps may or may not follow
To be more accurate it is an exe and commandline that is stored in the
Registry
- I only see 'open' and 'print' for 'TxtFile'
- no 'edit' verb
That's right. Most applications don't have the edit verb. In that case I
relaunch the call with the default verb ('open' in most cases).
In my case, xmlfile does have the edit verb. See
HKEY_CLASSES_ROOT\xmlfile\shell\edit\command.
Post by J French
You could check this out by replacing Notepad with a small EXE of the
same name that shows the Command Line
As for launching the App, you could use Shell, ShellExecute or
CreateProcess - personally I would use CreateProcess simply because
that is really what is going on anyway
Post by Sinna
Note that in some cases FindExecutable fails to do its job properly.
I think it has something to do with the way some values are written into
the registry (quoting). Instead of returning the complete path only the
first part is retained (e.g.: 'C:\Program' instead of 'C:\Program
Files\foo).
I see what you mean, but I'm rather surprized that it is a problem
- or rather any App that screws that up should screw up ShellExecute
The file path and name should be enclosed in quotes if it contains
spaces
You could cover that by fishing out the stuff from the Registry
yourself - but I would be inclined to regard such problems as a faulty
installation.
I do a lot of fishing in the Registry Pool but I don't like to re-invent
the wheel. ShellExecute(Ex) should do its job properly.
Most of all, when I do the fishing myself, the associated executable
when the application was installed is returned. In cases where the user
has changed the application to use for dealing with a given type of
file, I don't know how to find that out. I suppose this is also stored
in the registry somewhere.

That's the fishing line:
- HKEY_CLASSES_ROOT\"." + extension\(default) = FileType
- HKEY_CLASSES_ROOT\FileType\shell\edit\command, if not existing:
HKEY_CLASSES_ROOT\FileType\shell\open\command
- parse the file name into the command line
- launch Shell() with the full path

Note I haven't performed any tests already to check if ShellExecute
takes the default application or the user-defined one.
<snip>
Post by J French
However all FindExecutable does is root around in the Registry looking
for the associated EXE
There's the wheel again... I like some uniformity here.
In fact I want to mimick the right-click Edit functionality (or if not
available the right-click Open functionality).
Post by J French
Personally I dislike ShellExecute, it does not do very much, certainly
nothing more than one can easily do oneself, and when it goes wrong it
provides very little information.
That's true, but I'm used to it since Shell() doesn't provide much more
information either. ShellExecuteEx does have some interesting flags to
make the programmers life easier (like SEE_MASK_NOCLOSEPROCESS,
SEE_MASK_WAITFORINPUTIDLE and SEE_MASK_DOENVSUBST).


Sinna
Ralph
2006-08-07 14:12:15 UTC
Permalink
Post by Sinna
Post by J French
On Mon, 07 Aug 2006 08:32:46 +0200, Sinna
<snipped>
Post by Sinna
I do a lot of fishing in the Registry Pool but I don't like to re-invent
the wheel. ShellExecute(Ex) should do its job properly.
Most of all, when I do the fishing myself, the associated executable
when the application was installed is returned. In cases where the user
has changed the application to use for dealing with a given type of
file, I don't know how to find that out. I suppose this is also stored
in the registry somewhere.
<snipped>
Post by Sinna
- HKEY_CLASSES_ROOT\"." + extension\(default) = FileType
HKEY_CLASSES_ROOT\FileType\shell\open\command
- parse the file name into the command line
- launch Shell() with the full path
Note I haven't performed any tests already to check if ShellExecute
takes the default application or the user-defined one.
<snip>
<snipped>

Just to amplify.

A possible change of an associated app is the primary reason for using
ShellExecute/Ex(), but there are other reasons as well.

As Shell, WinExec, ShellExecute/Ex all launch a program by calling
CreateProcess. There are major differences in the prefabrication, the
info/parameters to be used by that prefabrication, and validation of the
instructions that are passed to CreateProcess, and in the information that
is returned to the caller. Therefore CreateProcess() is not an automatic
replacement for any of them.

In many cases where one attempts to replace ShellExecute with CreateProcess
one ends up duplicating the work that ShellExecute would have done for you -
for example: calling FindExecutable(), or check folder permissions.

In general Shell() mimics what happens if a program is launched from a
console. (Not as accurate as it once was, but still close enough.)
ShellExecute/Ex mimics what happens if a program is launched from the
Explorer (the Shell). CreateProcess() is the actual internal API call.

In most cases, ShellExecute/Ex is the appropriate call, because it consults
the Users Environment/Profile (file associations, mappings, security, ...),
and by definition must adhere to system policies. The first rule of Windows
programming is to play well with others in the sandbox. There are of course
quite valid reasons for taking more ownership - but these situations, IMHO,
are often fewer than many programmers seem to believe. <g>

-ralph
Sinna
2006-08-08 06:08:21 UTC
Permalink
Post by Ralph
Post by J French
On Mon, 07 Aug 2006 08:32:46 +0200, Sinna
<snipped>
Just to amplify.
A possible change of an associated app is the primary reason for using
ShellExecute/Ex(), but there are other reasons as well.
As Shell, WinExec, ShellExecute/Ex all launch a program by calling
CreateProcess. There are major differences in the prefabrication, the
info/parameters to be used by that prefabrication, and validation of the
instructions that are passed to CreateProcess, and in the information that
is returned to the caller. Therefore CreateProcess() is not an automatic
replacement for any of them.
In many cases where one attempts to replace ShellExecute with CreateProcess
one ends up duplicating the work that ShellExecute would have done for you -
for example: calling FindExecutable(), or check folder permissions.
In general Shell() mimics what happens if a program is launched from a
console. (Not as accurate as it once was, but still close enough.)
ShellExecute/Ex mimics what happens if a program is launched from the
Explorer (the Shell). CreateProcess() is the actual internal API call.
In most cases, ShellExecute/Ex is the appropriate call, because it consults
the Users Environment/Profile (file associations, mappings, security, ...),
and by definition must adhere to system policies. The first rule of Windows
programming is to play well with others in the sandbox. There are of course
quite valid reasons for taking more ownership - but these situations, IMHO,
are often fewer than many programmers seem to believe. <g>
-ralph
Thanks for clearing some things out. It just confirms my decision to use
the ShellExecute API. My goal is to mimick the 'Edit' functionality when
a user right-clicks a file. If that fails (e.g. because it's
unavailable) I fall back to the default action ('Open').
Unfortunately it does not always work as it should, resulting in this
thread.

Sinna
Ralph
2006-08-08 10:43:17 UTC
Permalink
Post by Sinna
Post by Ralph
<snipped>
Thanks for clearing some things out. It just confirms my decision to use
the ShellExecute API. My goal is to mimick the 'Edit' functionality when
a user right-clicks a file. If that fails (e.g. because it's
unavailable) I fall back to the default action ('Open').
Unfortunately it does not always work as it should, resulting in this
thread.
Sinna
As usual I was so busy adding my two cents, I forgot to address the original
question. <g>

Try adding some additional sleep time as per the following...
http://www.vbaccelerator.com/home/vb/code/libraries/Shell_Projects/Shell_And_Wait_For_Completion/article.asp

hth
-ralph
J French
2006-08-08 11:12:00 UTC
Permalink
Post by Ralph
Post by Sinna
Post by Ralph
<snipped>
Thanks for clearing some things out. It just confirms my decision to use
the ShellExecute API. My goal is to mimick the 'Edit' functionality when
a user right-clicks a file. If that fails (e.g. because it's
unavailable) I fall back to the default action ('Open').
Unfortunately it does not always work as it should, resulting in this
thread.
Sinna
As usual I was so busy adding my two cents, I forgot to address the original
question. <g>
Try adding some additional sleep time as per the following...
http://www.vbaccelerator.com/home/vb/code/libraries/Shell_Projects/Shell_And_Wait_For_Completion/article.asp
Unusually, Ralph, I don't agree with you about using ShellExecute

It conceals too much, and it totally opaque when it does not work
- like Sinna's current problem

I have a suspicion that Sinna's problem is that he is trying to run
some EXE that really kicks off another EXE

If he were trying to find the hWnd of the new App then I would suggest
using WaitForInputIdle to let the thing settle down
Ralph
2006-08-08 12:43:29 UTC
Permalink
Post by Ralph
Post by Ralph
Post by Sinna
Post by Ralph
<snipped>
Thanks for clearing some things out. It just confirms my decision to use
the ShellExecute API. My goal is to mimick the 'Edit' functionality when
a user right-clicks a file. If that fails (e.g. because it's
unavailable) I fall back to the default action ('Open').
Unfortunately it does not always work as it should, resulting in this
thread.
Sinna
As usual I was so busy adding my two cents, I forgot to address the original
question. <g>
Try adding some additional sleep time as per the following...
http://www.vbaccelerator.com/home/vb/code/libraries/Shell_Projects/Shell_An
d_Wait_For_Completion/article.asp
Post by Ralph
Unusually, Ralph, I don't agree with you about using ShellExecute
It conceals too much, and it totally opaque when it does not work
- like Sinna's current problem
I have a suspicion that Sinna's problem is that he is trying to run
some EXE that really kicks off another EXE
If he were trying to find the hWnd of the new App then I would suggest
using WaitForInputIdle to let the thing settle down
LOL

I knew you wouldn't agree with me about Shell/ShellExecute as *first
choice*, but I think you will agree that it is really a matter of ownership
or how much you need to 'get along' with others. ie. If I am launching an
"Editor" and don't much give a damn what the users uses then one of the
Shells makes sense. However, if I am launching one of my own tools in my own
suite - then I'll lean to total control and locking down every attribute I
can.

WaitForInputIdle is an excellent suggestion.

-ralph
Sinna
2006-08-08 12:55:29 UTC
Permalink
Post by Ralph
Post by Ralph
Post by Ralph
Post by Sinna
Post by Ralph
<snipped>
Thanks for clearing some things out. It just confirms my decision to
use
Post by Ralph
Post by Ralph
Post by Sinna
the ShellExecute API. My goal is to mimick the 'Edit' functionality
when
Post by Ralph
Post by Ralph
Post by Sinna
a user right-clicks a file. If that fails (e.g. because it's
unavailable) I fall back to the default action ('Open').
Unfortunately it does not always work as it should, resulting in this
thread.
Sinna
As usual I was so busy adding my two cents, I forgot to address the
original
Post by Ralph
Post by Ralph
question. <g>
Try adding some additional sleep time as per the following...
http://www.vbaccelerator.com/home/vb/code/libraries/Shell_Projects/Shell_An
d_Wait_For_Completion/article.asp
Post by Ralph
Unusually, Ralph, I don't agree with you about using ShellExecute
It conceals too much, and it totally opaque when it does not work
- like Sinna's current problem
I have a suspicion that Sinna's problem is that he is trying to run
some EXE that really kicks off another EXE
If he were trying to find the hWnd of the new App then I would suggest
using WaitForInputIdle to let the thing settle down
LOL
I knew you wouldn't agree with me about Shell/ShellExecute as *first
choice*, but I think you will agree that it is really a matter of ownership
or how much you need to 'get along' with others. ie. If I am launching an
"Editor" and don't much give a damn what the users uses then one of the
Shells makes sense. However, if I am launching one of my own tools in my own
suite - then I'll lean to total control and locking down every attribute I
can.
WaitForInputIdle is an excellent suggestion.
-ralph
WaitForInputIdle is indeed an excellent suggestion, but I'm already
using it as SEE_MASK_WAITFORINPUTIDLE flag in the mask property of the
SHELLEXECUTEINFO structure.

In the meanwhile I have found out J French to be right about an
application launching another application before displaying the given
file for editing. See somewhere else in this thread.

Sinna
Ralph
2006-08-08 13:10:59 UTC
Permalink
Post by Sinna
Post by Ralph
<snipped>
In the meanwhile I have found out J French to be right about an
application launching another application before displaying the given
file for editing. See somewhere else in this thread.
Sinna
He usually is.

-ralph
J French
2006-08-08 13:45:18 UTC
Permalink
On Tue, 8 Aug 2006 07:43:29 -0500, "Ralph" <***@yahoo.com>
wrote:

<snip>
Post by Ralph
LOL
I knew you wouldn't agree with me about Shell/ShellExecute as *first
choice*, but I think you will agree that it is really a matter of ownership
or how much you need to 'get along' with others. ie. If I am launching an
"Editor" and don't much give a damn what the users uses then one of the
Shells makes sense. However, if I am launching one of my own tools in my own
suite - then I'll lean to total control and locking down every attribute I
can.
WaitForInputIdle is an excellent suggestion.
-ralph
Ralph is the name of an extremely large, fat and highly intelligent
cat who was a welcome guest.

As a result, I cannot help chuckling whenever I see your name.

We and the neighbours got kittens from the same litter, and Ralph, who
lived nearby, took it upon himself to take on mentoring them.

I think he was the second smartest cat I've met, the smartest was a
ginger psychopath who grew up thinking his mother smelt of beer and
tobacco

Anyway, apart from that digression, my beef with ShellExecute is that
when something goes wrong it is incredibly difficult to trace.

At the very least Sinna should be trying a few different approaches to
try to locate where the glitch is.

He could try monitoring current Apps using the Win32Snapshot stuff
which is usefully rather different on 2k and XP to 95/8

The Registry stuff is pretty easy for this sort of thing, about 1999 I
ran up a cheapie for a company a friend of mine worked for.
One of their Jap bosses kept getting Emails with the extension .BIN
so I wrote a utility that attached itself to .BIN, sorted out the App
from the header bytes of the file, and launched the appropriate App.

Sinna needs to be encouraged down the path of sussing things out from
fundamental principles, some APIs are just plain daft, I distrust
ShellExecute, I'll bet that even MS interns are warned off it.

Usually I have to prevent myself posting 'Too Right!' after your posts
- but this time I reckon that you are being too trusting of Winders
Ralph
2006-08-08 14:33:35 UTC
Permalink
Post by J French
<snip>
Post by Ralph
LOL
I knew you wouldn't agree with me about Shell/ShellExecute as *first
choice*, but I think you will agree that it is really a matter of ownership
or how much you need to 'get along' with others. ie. If I am launching an
"Editor" and don't much give a damn what the users uses then one of the
Shells makes sense. However, if I am launching one of my own tools in my own
suite - then I'll lean to total control and locking down every attribute I
can.
WaitForInputIdle is an excellent suggestion.
-ralph
Ralph is the name of an extremely large, fat and highly intelligent
cat who was a welcome guest.
As a result, I cannot help chuckling whenever I see your name.
We and the neighbours got kittens from the same litter, and Ralph, who
lived nearby, took it upon himself to take on mentoring them.
I think he was the second smartest cat I've met, the smartest was a
ginger psychopath who grew up thinking his mother smelt of beer and
tobacco
Anyway, apart from that digression, my beef with ShellExecute is that
when something goes wrong it is incredibly difficult to trace.
At the very least Sinna should be trying a few different approaches to
try to locate where the glitch is.
He could try monitoring current Apps using the Win32Snapshot stuff
which is usefully rather different on 2k and XP to 95/8
The Registry stuff is pretty easy for this sort of thing, about 1999 I
ran up a cheapie for a company a friend of mine worked for.
One of their Jap bosses kept getting Emails with the extension .BIN
so I wrote a utility that attached itself to .BIN, sorted out the App
from the header bytes of the file, and launched the appropriate App.
Sinna needs to be encouraged down the path of sussing things out from
fundamental principles, some APIs are just plain daft, I distrust
ShellExecute, I'll bet that even MS interns are warned off it.
Usually I have to prevent myself posting 'Too Right!' after your posts
- but this time I reckon that you are being too trusting of Winders
Well, while in danger of backing-down too much <g>, you have an good point
about drifting down to lower calls when things go wrong. Shell is another
layer of indirection and an occasionally cloudy one at that.

The most fustrating condition is where you can launch something in Explorer
and it works fine, yet you can't duplicate the same with a Shell/Shellxxx().
If "Winders" really wanted to be helpful, they would have provided a...
SendClickToFile()
And not confused us with all the options. <g>

[A cat would not be a good anology - too active. An old turtle is better, as
I have found that I am only operative 6 months out of the year. For the
three months it is too hot (now) or the three months it is too cold; I like
to just bury myself in the mud and wait it out. <g>]

-ralph
Sinna
2006-08-08 15:13:29 UTC
Permalink
<snip>
Post by Ralph
Well, while in danger of backing-down too much <g>, you have an good point
about drifting down to lower calls when things go wrong. Shell is another
layer of indirection and an occasionally cloudy one at that.
The most fustrating condition is where you can launch something in Explorer
and it works fine, yet you can't duplicate the same with a Shell/Shellxxx().
If "Winders" really wanted to be helpful, they would have provided a...
SendClickToFile()
And not confused us with all the options. <g>
[A cat would not be a good anology - too active. An old turtle is better, as
I have found that I am only operative 6 months out of the year. For the
three months it is too hot (now) or the three months it is too cold; I like
to just bury myself in the mud and wait it out. <g>]
-ralph
Well, for Windows Explorer, ShellExecute(Ex) does its job as it should.
But for me, requiring a bit more (read: monitoring the launched
application) I *was* in serious trouble.
Thanks to yours and J Frenches valuable input I was able to clear all
things (for as far as I can see at the moment) out.


Sinna
J French
2006-08-09 06:45:29 UTC
Permalink
On Tue, 8 Aug 2006 09:33:35 -0500, "Ralph" <***@yahoo.com>
wrote:

<snip>
Post by Ralph
Well, while in danger of backing-down too much <g>, you have an good point
about drifting down to lower calls when things go wrong. Shell is another
layer of indirection and an occasionally cloudy one at that.
Not really backing down, more a synthesis of views
- Hegelian logic
Post by Ralph
The most fustrating condition is where you can launch something in Explorer
and it works fine, yet you can't duplicate the same with a Shell/Shellxxx().
If "Winders" really wanted to be helpful, they would have provided a...
SendClickToFile()
And not confused us with all the options. <g>
Very true
Post by Ralph
[A cat would not be a good anology - too active. An old turtle is better, as
I have found that I am only operative 6 months out of the year. For the
three months it is too hot (now) or the three months it is too cold; I like
to just bury myself in the mud and wait it out. <g>]
Comical, it is just the name that tickles me, the association <pun>

Programming in extreme heat is unpleasant, keyboards don't like being
drenched with sweat.

Sinna
2006-08-08 12:50:41 UTC
Permalink
Post by J French
Post by Ralph
Post by Sinna
Post by Ralph
<snipped>
Thanks for clearing some things out. It just confirms my decision to use
the ShellExecute API. My goal is to mimick the 'Edit' functionality when
a user right-clicks a file. If that fails (e.g. because it's
unavailable) I fall back to the default action ('Open').
Unfortunately it does not always work as it should, resulting in this
thread.
Sinna
As usual I was so busy adding my two cents, I forgot to address the original
question. <g>
Try adding some additional sleep time as per the following...
http://www.vbaccelerator.com/home/vb/code/libraries/Shell_Projects/Shell_And_Wait_For_Completion/article.asp
Unusually, Ralph, I don't agree with you about using ShellExecute
It conceals too much, and it totally opaque when it does not work
- like Sinna's current problem
Shell() itself suffers from the same.
Post by J French
I have a suspicion that Sinna's problem is that he is trying to run
some EXE that really kicks off another EXE
Damn, you're right! I've launched SysInternal's RegMon and reveiled that
before the Notepad application is launched, MSOXMLED (part of Office
2003) is launched. Afterwards Notepad is launched.

This is quite the same behavior as when launching the 'Open with...' dialog.
To keep track of this, I launch the following call:
mvarProcessID = Shell( _
"rundll32.exe shell32.dll,OpenAs_RunDLL " & PathName, _
WindowStyle)
I monitor the closing of the application by performing a
WaitForSingleObject on the hProcess returned by:
hProcess = OpenProcess(SYNCHRONIZE, 0, mvarProcessID)

When the process gets signaled, I look for the most recent process that
has mvarProcessID as its ParentProcessID (using
CreateToolhelp32Snapshot, Process32First and Process32Next).
Given this new ProcessID, I monitor the application by performing the
WaitForSingleObject again of the hProcess returned by the code line above.

After sorting this behavior out, the only thing left is how to get the
ProcessID from a process handle. On WinXP SP1 and above you have the
GetProcessId API, but I need to support W2K too!

Any ideas ?
Post by J French
If he were trying to find the hWnd of the new App then I would suggest
using WaitForInputIdle to let the thing settle down
I've tried to look up the launched application by finding its hWnd, but
it didn't work out. WaitForInputIdle is already set in the fMask member
of the SHELLEXECUTEINFO structure.

Sinna
Sinna
2006-08-08 13:43:34 UTC
Permalink
Post by Sinna
Post by J French
Post by Ralph
Post by Sinna
Post by Ralph
<snipped>
Thanks for clearing some things out. It just confirms my decision to use
the ShellExecute API. My goal is to mimick the 'Edit' functionality when
a user right-clicks a file. If that fails (e.g. because it's
unavailable) I fall back to the default action ('Open').
Unfortunately it does not always work as it should, resulting in this
thread.
Sinna
As usual I was so busy adding my two cents, I forgot to address the original
question. <g>
Try adding some additional sleep time as per the following...
http://www.vbaccelerator.com/home/vb/code/libraries/Shell_Projects/Shell_And_Wait_For_Completion/article.asp
Unusually, Ralph, I don't agree with you about using ShellExecute
It conceals too much, and it totally opaque when it does not work
- like Sinna's current problem
Shell() itself suffers from the same.
Post by J French
I have a suspicion that Sinna's problem is that he is trying to run
some EXE that really kicks off another EXE
Damn, you're right! I've launched SysInternal's RegMon and reveiled that
before the Notepad application is launched, MSOXMLED (part of Office
2003) is launched. Afterwards Notepad is launched.
This is quite the same behavior as when launching the 'Open with...' dialog.
mvarProcessID = Shell( _
"rundll32.exe shell32.dll,OpenAs_RunDLL " & PathName, _
WindowStyle)
I monitor the closing of the application by performing a
hProcess = OpenProcess(SYNCHRONIZE, 0, mvarProcessID)
When the process gets signaled, I look for the most recent process that
has mvarProcessID as its ParentProcessID (using
CreateToolhelp32Snapshot, Process32First and Process32Next).
Given this new ProcessID, I monitor the application by performing the
WaitForSingleObject again of the hProcess returned by the code line above.
After sorting this behavior out, the only thing left is how to get the
ProcessID from a process handle. On WinXP SP1 and above you have the
GetProcessId API, but I need to support W2K too!
Any ideas ?
Post by J French
If he were trying to find the hWnd of the new App then I would suggest
using WaitForInputIdle to let the thing settle down
I've tried to look up the launched application by finding its hWnd, but
it didn't work out. WaitForInputIdle is already set in the fMask member
of the SHELLEXECUTEINFO structure.
Sinna
After some googling the following page provides the sources I need
exactly: http://www.codecomments.com/Visual_Basic_Bugs/message525268.html.

Thanks for the tips and pointers!

Sinna
J French
2006-08-08 14:07:22 UTC
Permalink
On Tue, 08 Aug 2006 15:43:34 +0200, Sinna
<***@hotpop.com> wrote:

<snip>
Post by Sinna
After some googling the following page provides the sources I need
exactly: http://www.codecomments.com/Visual_Basic_Bugs/message525268.html.
Thanks for the tips and pointers!
Sinna, you are showing the signs of a good coder
- when you find a problem attack it from 360 degrees

The trick is to duplicate code rather than revise it
Sinna
2006-08-08 11:29:12 UTC
Permalink
Post by Ralph
Post by Sinna
Post by Ralph
<snipped>
Thanks for clearing some things out. It just confirms my decision to use
the ShellExecute API. My goal is to mimick the 'Edit' functionality when
a user right-clicks a file. If that fails (e.g. because it's
unavailable) I fall back to the default action ('Open').
Unfortunately it does not always work as it should, resulting in this
thread.
Sinna
As usual I was so busy adding my two cents, I forgot to address the original
question. <g>
Try adding some additional sleep time as per the following...
http://www.vbaccelerator.com/home/vb/code/libraries/Shell_Projects/Shell_And_Wait_For_Completion/article.asp
hth
-ralph
I've tried your suggestion, but I doesn't work out.
GetExitCodeProcess (as mentioned in the link you provided) returns 0
immediately.
Also adding some Sleep is not the way to go.

Perhaps I'd better re-explain the faulty behavior I'm facing:
When calling ShellExecuteEx with the 'edit' verb for an XML-file,
Notepad is launched (as expected since when I right-click an XML-file in
Explorer, choosing 'Edit', Notepad is launched).
I want to use the hProcess member of the SHELLEXECUTEINFO structure to
monitor the application, but it seems to be shut down immediately.
When I call ShellExecuteEx for a text-file, there's no issue at all.

Note that it only fails on my WinXP system: on W2K and W2K3 it works as
expected. So it really think it is a bug on WinXP.

Sinna
J French
2006-08-08 12:46:34 UTC
Permalink
On Tue, 08 Aug 2006 13:29:12 +0200, Sinna
Post by Sinna
Post by Ralph
Post by Sinna
Post by Ralph
<snipped>
Thanks for clearing some things out. It just confirms my decision to use
the ShellExecute API. My goal is to mimick the 'Edit' functionality when
a user right-clicks a file. If that fails (e.g. because it's
unavailable) I fall back to the default action ('Open').
Unfortunately it does not always work as it should, resulting in this
thread.
Sinna
As usual I was so busy adding my two cents, I forgot to address the original
question. <g>
Try adding some additional sleep time as per the following...
http://www.vbaccelerator.com/home/vb/code/libraries/Shell_Projects/Shell_And_Wait_For_Completion/article.asp
hth
-ralph
I've tried your suggestion, but I doesn't work out.
GetExitCodeProcess (as mentioned in the link you provided) returns 0
immediately.
Also adding some Sleep is not the way to go.
When calling ShellExecuteEx with the 'edit' verb for an XML-file,
Notepad is launched (as expected since when I right-click an XML-file in
Explorer, choosing 'Edit', Notepad is launched).
I want to use the hProcess member of the SHELLEXECUTEINFO structure to
monitor the application, but it seems to be shut down immediately.
When I call ShellExecuteEx for a text-file, there's no issue at all.
Note that it only fails on my WinXP system: on W2K and W2K3 it works as
expected. So it really think it is a bug on WinXP.
I don't

Text files are normally associated with a little front end that looks
at the size of the file and then runs either Notepad, or asks you
whether you want to run Wordpad (which handles larger files)

On my old system (and I can't be bothered to fire up the XP machine)
there is Write.exe which is tiny and Notepad.exe which is larger.

Probably Notepad.exe calls Write.exe on older systems, if the file is
a bit too large.

If you used FindExecutable you would see what is going on
Loading...