CreateProcess/WaitForSingleObject problem

R

Rob Hughes

I'm trying to apply the "Launching Applications..." quickstart example
to one of my applications and I'm having problems. (See:
http://samples.gotdotnet.com/quickstart/compactframework/doc/waitforsingleobject.aspx)

To simplify things, application A is the application launching
application B.

The problem I'm having is that when WaitForSingleObject is called from
application A, execution stop in application A as expected but
application B doesn't ever load (no errors from CreateProcess). If I
go into "Running Programs" and stop the application A, then
application B finally loads. This only seems to be happening with my
applications. I tried using "calc.exe" as application B and it works
as expected. The only difference I can think of is that both of my
applications are .NET applications. That shouldn't matter, should it?

Anyone else get this to work right with two .NET applications?
 
P

Paul G. Tobey [eMVP]

The best way to get help with this is to post the code for both
applications, so we don't have to write something from scratch to try to
help you.

Paul T.
 
R

Rob Hughes

I posted a link to the code I used but I will post the code here this
time. The CreateProcess code is only used in one application. The
sample on gotdotnet uses CreateProcess to launch Calc.exe. That works
fine. I need to launch another .NETCF application. When I use that
code to launch a .NETCF application instead of Calc.exe, it doesn't
work right.

Here is the code from the link (minus the designer generated code):

Overloads Declare Function CreateProcess Lib "CoreDll.dll" (ByVal
imageName As String, ByVal cmdLine As String, ByVal
lpProcessAttributes As IntPtr, ByVal lpThreadAttributes As IntPtr,
ByVal boolInheritHandles As Int32, ByVal dwCreationFlags As Int32,
ByVal lpEnvironment As IntPtr, ByVal lpszCurrentDir As IntPtr, ByVal
si As Byte(), ByVal pi As ProcessInfo) As Integer
Declare Function WaitForSingleObject Lib "CoreDll.dll" (ByVal
Handle As IntPtr, ByVal Wait As Int32) As Int32
Declare Function GetLastError Lib "CoreDll.dll" () As Int32
Declare Function CloseHandle Lib "CoreDll.dll" (ByVal Handle As
IntPtr) As Int32

Public Class ProcessInfo
Public hProcess As IntPtr
Public hThread As IntPtr
Public ProcessId As Int32
Public ThreadId As Int32
End Class 'ProcessInfo

Overloads Public Shared Function CreateProcess(ExeName As String,
CmdLine As String, pi As ProcessInfo) As Boolean
Dim INFINITE As Int32
INFINITE = &HFFFFFFFF

Dim WAIT_OBJECT_0 As Int32 = 0
Dim result As Int32

If pi Is Nothing Then
pi = New ProcessInfo
End If
Dim si(128) As Byte

result = CreateProcess(ExeName, CmdLine, IntPtr.Zero,
IntPtr.Zero, 0, 0, IntPtr.Zero, IntPtr.Zero, si, pi)
If 0 = result Then
Return False
End If
result = WaitForSingleObject(pi.hProcess, INFINITE)
CloseHandle(pi.hThread)
CloseHandle(pi.hProcess)
If WAIT_OBJECT_0 <> result Then
Return False
End If
Return True
End Function

Private Sub button1_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles button1.Click
'TRY USING ANOTHER .NETCF APP INSTEAD OF "Calc.exe" TO SEE
PROBLEM
Dim progPath As String = "Calc.exe"
Dim pi As New ProcessInfo
If CreateProcess(progPath, "", pi) Then
MessageBox.Show(String.Format("Success! Resuming calling
application." + ControlChars.Lf + "PID = 0x{0:X8}" + ControlChars.Lf +
"({0})", pi.ProcessId), "Done Waiting...")
Else
MessageBox.Show(String.Format("Failed!" + ControlChars.Lf
+ "System Error = 0x{0:X8}" + ControlChars.Lf + "({0})",
GetLastError()), "Done waiting...")
End If
End Sub
 
P

Paul G. Tobey [eMVP]

I got back to this and ran a test. I *do not* see this behavior. I can
launch any sort of program, native or .NET CF, wait on it to exit, and have
it come up and operate correctly with no problems. This is on Windows
CE.NET 4.2...

Paul T.

Rob Hughes said:
I posted a link to the code I used but I will post the code here this
time. The CreateProcess code is only used in one application. The
sample on gotdotnet uses CreateProcess to launch Calc.exe. That works
fine. I need to launch another .NETCF application. When I use that
code to launch a .NETCF application instead of Calc.exe, it doesn't
work right.

Here is the code from the link (minus the designer generated code):

Overloads Declare Function CreateProcess Lib "CoreDll.dll" (ByVal
imageName As String, ByVal cmdLine As String, ByVal
lpProcessAttributes As IntPtr, ByVal lpThreadAttributes As IntPtr,
ByVal boolInheritHandles As Int32, ByVal dwCreationFlags As Int32,
ByVal lpEnvironment As IntPtr, ByVal lpszCurrentDir As IntPtr, ByVal
si As Byte(), ByVal pi As ProcessInfo) As Integer
Declare Function WaitForSingleObject Lib "CoreDll.dll" (ByVal
Handle As IntPtr, ByVal Wait As Int32) As Int32
Declare Function GetLastError Lib "CoreDll.dll" () As Int32
Declare Function CloseHandle Lib "CoreDll.dll" (ByVal Handle As
IntPtr) As Int32

Public Class ProcessInfo
Public hProcess As IntPtr
Public hThread As IntPtr
Public ProcessId As Int32
Public ThreadId As Int32
End Class 'ProcessInfo

Overloads Public Shared Function CreateProcess(ExeName As String,
CmdLine As String, pi As ProcessInfo) As Boolean
Dim INFINITE As Int32
INFINITE = &HFFFFFFFF

Dim WAIT_OBJECT_0 As Int32 = 0
Dim result As Int32

If pi Is Nothing Then
pi = New ProcessInfo
End If
Dim si(128) As Byte

result = CreateProcess(ExeName, CmdLine, IntPtr.Zero,
IntPtr.Zero, 0, 0, IntPtr.Zero, IntPtr.Zero, si, pi)
If 0 = result Then
Return False
End If
result = WaitForSingleObject(pi.hProcess, INFINITE)
CloseHandle(pi.hThread)
CloseHandle(pi.hProcess)
If WAIT_OBJECT_0 <> result Then
Return False
End If
Return True
End Function

Private Sub button1_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles button1.Click
'TRY USING ANOTHER .NETCF APP INSTEAD OF "Calc.exe" TO SEE
PROBLEM
Dim progPath As String = "Calc.exe"
Dim pi As New ProcessInfo
If CreateProcess(progPath, "", pi) Then
MessageBox.Show(String.Format("Success! Resuming calling
application." + ControlChars.Lf + "PID = 0x{0:X8}" + ControlChars.Lf +
"({0})", pi.ProcessId), "Done Waiting...")
Else
MessageBox.Show(String.Format("Failed!" + ControlChars.Lf
+ "System Error = 0x{0:X8}" + ControlChars.Lf + "({0})",
GetLastError()), "Done waiting...")
End If
End Sub



"Paul G. Tobey [eMVP]" <ptobey_no_spam@instrument_no_spam.com> wrote in
message news: said:
The best way to get help with this is to post the code for both
applications, so we don't have to write something from scratch to try to
help you.

Paul T.


http://samples.gotdotnet.com/quickstart/compactframework/doc/waitforsingleobject.aspx)
 
R

Rob Hughes

That's pretty interesting. I did some more testing myself and the only
way I could get WaitForSingleObject to work with a .NETCF app is to
throw in a loop of about 10 DoEvents between CreateProcess and
WaitForSingleObject. That seems to allow the process enough time to
get created (a single DoEvents isn't enough). If I have CreateProcess
followed directly by WaitForSingleObject, the main app gets locked up
at WaitForSingleObject before the second process completely loads -
preventing it from loading. If I go into the "task manager" and stop
the main process manually, the second process will finish loading (but
then there's no main process to go back to). So my test indicates to
me that there is some timing difference between creating a "Win32"
process and a .NETCF process (or maybe it's just that the .NETCF app
I'm loading is larger and takes more time to load than Calc.exe).
Regardless, I don't like the DoEvents solution, I'd like to get it to
work the right way. I'm using PPC2003. I haven't developed for CE.NET
4.2 before, so I don't know if that's why we're seeing a difference.

Thanks for taking the time to run your test.


Paul G. Tobey said:
I got back to this and ran a test. I *do not* see this behavior. I can
launch any sort of program, native or .NET CF, wait on it to exit, and have
it come up and operate correctly with no problems. This is on Windows
CE.NET 4.2...

Paul T.

Rob Hughes said:
I posted a link to the code I used but I will post the code here this
time. The CreateProcess code is only used in one application. The
sample on gotdotnet uses CreateProcess to launch Calc.exe. That works
fine. I need to launch another .NETCF application. When I use that
code to launch a .NETCF application instead of Calc.exe, it doesn't
work right.

Here is the code from the link (minus the designer generated code):

Overloads Declare Function CreateProcess Lib "CoreDll.dll" (ByVal
imageName As String, ByVal cmdLine As String, ByVal
lpProcessAttributes As IntPtr, ByVal lpThreadAttributes As IntPtr,
ByVal boolInheritHandles As Int32, ByVal dwCreationFlags As Int32,
ByVal lpEnvironment As IntPtr, ByVal lpszCurrentDir As IntPtr, ByVal
si As Byte(), ByVal pi As ProcessInfo) As Integer
Declare Function WaitForSingleObject Lib "CoreDll.dll" (ByVal
Handle As IntPtr, ByVal Wait As Int32) As Int32
Declare Function GetLastError Lib "CoreDll.dll" () As Int32
Declare Function CloseHandle Lib "CoreDll.dll" (ByVal Handle As
IntPtr) As Int32

Public Class ProcessInfo
Public hProcess As IntPtr
Public hThread As IntPtr
Public ProcessId As Int32
Public ThreadId As Int32
End Class 'ProcessInfo

Overloads Public Shared Function CreateProcess(ExeName As String,
CmdLine As String, pi As ProcessInfo) As Boolean
Dim INFINITE As Int32
INFINITE = &HFFFFFFFF

Dim WAIT_OBJECT_0 As Int32 = 0
Dim result As Int32

If pi Is Nothing Then
pi = New ProcessInfo
End If
Dim si(128) As Byte

result = CreateProcess(ExeName, CmdLine, IntPtr.Zero,
IntPtr.Zero, 0, 0, IntPtr.Zero, IntPtr.Zero, si, pi)
If 0 = result Then
Return False
End If
result = WaitForSingleObject(pi.hProcess, INFINITE)
CloseHandle(pi.hThread)
CloseHandle(pi.hProcess)
If WAIT_OBJECT_0 <> result Then
Return False
End If
Return True
End Function

Private Sub button1_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles button1.Click
'TRY USING ANOTHER .NETCF APP INSTEAD OF "Calc.exe" TO SEE
PROBLEM
Dim progPath As String = "Calc.exe"
Dim pi As New ProcessInfo
If CreateProcess(progPath, "", pi) Then
MessageBox.Show(String.Format("Success! Resuming calling
application." + ControlChars.Lf + "PID = 0x{0:X8}" + ControlChars.Lf +
"({0})", pi.ProcessId), "Done Waiting...")
Else
MessageBox.Show(String.Format("Failed!" + ControlChars.Lf
+ "System Error = 0x{0:X8}" + ControlChars.Lf + "({0})",
GetLastError()), "Done waiting...")
End If
End Sub



"Paul G. Tobey [eMVP]" <ptobey_no_spam@instrument_no_spam.com> wrote in
message news: said:
The best way to get help with this is to post the code for both
applications, so we don't have to write something from scratch to try to
help you.

Paul T.

I'm trying to apply the "Launching Applications..." quickstart example
to one of my applications and I'm having problems. (See:

http://samples.gotdotnet.com/quickstart/compactframework/doc/waitforsingleobject.aspx)

To simplify things, application A is the application launching
application B.

The problem I'm having is that when WaitForSingleObject is called from
application A, execution stop in application A as expected but
application B doesn't ever load (no errors from CreateProcess). If I
go into "Running Programs" and stop the application A, then
application B finally loads. This only seems to be happening with my
applications. I tried using "calc.exe" as application B and it works
as expected. The only difference I can think of is that both of my
applications are .NET applications. That shouldn't matter, should it?

Anyone else get this to work right with two .NET applications?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top