How to terminate a running program from another NETCF app

G

Guest

I'm working on a .NET CF app that I want to be able to do automatic updates
on. I am able to get the app to check periodically for updates on a web site
and then P/Invoke to ShellExecute another app to download the update and run
the installer (via another ShellExecute). What I can't figure out is how to
have my downloader app terminate the main application so I can install the
update. Is there a way to do it? I'm assuming I'll have to P/Invoke
something... just can't figure out what.

Thanks,
Rich Williams
Amos Data Systems, Inc.
 
D

Daniel Moth

You could listen in your app on an event (in the windows sense not a .NET
event) and signal that from your killer app. PInvoke CreateEvent or use the
wrapper in opennetcf EventWaitHandle.

Other option includes sending a WM_CLOSE to your app.

Searching the archives will give you other ideas on this FAQ

Cheers
Daniel
 
C

Chris Tacke, eMVP

Since you own the code for both, your "main app" should terminate itself.
The simplest mechanism is to listen for an event from the updater, and when
it's received, shut down gracefully.

--
Chris Tacke
Co-founder
OpenNETCF.org
Has OpenNETCF helped you? Consider donating to support us!
http://www.opennetcf.org/donate
 
G

Guest

Thanks for the answer. I've been looking into this and have run into a
problem. I can pinvoke CreateEvent and WaitForSingleObject in my main app.
That seems to go OK. But, when I try to pinvoke OpenEvent in the killing app
to get the event I created, I'm getting a MissingMethodException. I'm running
this on WM2003SE on WINCE4.2.

My pinvoke wrapper for OpenEvent is
<DllImport("coredll.dll", SetLastError:=True)> _
Public Shared Function OpenEvent(ByVal dwDesiredAccess As Int32, ByVal
bInheritHandle As Boolean, ByVal lpName As String) As IntPtr
End Function

What am I missing?

Thanks,
Rich Williams
 
D

Daniel Moth

Instead of using OpenEvent, use CreateEvent again with the same name. If you
are still having problems post the calling code.

Cheers
Daniel
 
G

Guest

OK, here's what I've got now. It's just 2 simple programs... One simply
updates a label after each wait timeout and has a button which launches a
second app that fires the event in the first. It doesn't terminate the app
right now. All I have the event trigger is a change in the label. The event
fires, but my first app hangs when that happens.

Here's code:
"Main app"
Private message As String
Public Const WAIT_TIMEOUT As Int32 = &H102
Private active2 As Boolean = True

Public Sub blah(ByVal sender As Object, ByVal e As EventArgs) Handles
MyBase.Load
Dim thread As New System.Threading.Thread(AddressOf argh)
thread.Start()
While active2
Application.DoEvents()
End While
Me.Close()
End Sub

Private Sub argh()
Dim active As Boolean = True

Dim ptr As IntPtr = CreateEvent(IntPtr.Zero, True, False, "KillEvent")

While active
If WaitForSingleObject(ptr, 1000) <> WAIT_TIMEOUT Then
'active = False 'This is commented so that the app doesn't
actually die
message = "Yes!"
Else
message = (Int32.Parse(Label1.Text) + 1).ToString
End If
Label1.Invoke(New EventHandler(AddressOf labelupdate))
End While
active2 = False
CloseHandle(ptr)
End Sub

Private Sub labelupdate(ByVal sender As Object, ByVal e As EventArgs)
Label1.Text = message
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
OpenNETCF.Diagnostics.Process.Start("KillerApp.exe")
End Sub

"Killer app"
Private Sub kill(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

Dim ptr As IntPtr = CreateEvent(IntPtr.Zero, True, False, "KillEvent")
EventModify(ptr, EventType._SET)
CloseHandle(ptr)

Me.Close()
Application.Exit()

End Sub

P/Invoke Wrappers:
<DllImport("coredll.dll", EntryPoint:="WaitForSingleObject",
SetLastError:=True)> _
Public Shared Function WaitForSingleObject(ByVal hHandle As IntPtr,
ByVal dwMilliseconds As Int32) As Int32
End Function

<DllImport("coredll.dll", EntryPoint:="CreateEvent",
SetLastError:=True)> _
Public Shared Function CreateEvent(ByVal lpEventAttributes As IntPtr,
ByVal bManualReset As Boolean, ByVal bInitialState As Boolean, ByVal lpName
As String) As IntPtr
End Function

<DllImport("coredll.dll", EntryPoint:="CloseHandle",
SetLastError:=True)> _
Public Shared Function CloseHandle(ByVal hObject As IntPtr) As Boolean
End Function

<DllImport("coredll.dll", EntryPoint:="EventModify",
SetLastError:=True)> _
Public Shared Function EventModify(ByVal hEvent As IntPtr, ByVal ef As
EventType) As Boolean
End Function

Thanks,
Rich
 
S

Sergey Bogdanov

You have encountered with the common mistake - you were trying to use
GUI from another thread in this line:

message = (Int32.Parse(Label1.Text) + 1).ToString

Just replace it with something like this:

Label1.Invoke(New EventHandler(AddressOf getlabel))

....

Private Sub getlabel(ByVal sender As Object, ByVal e As EventArgs)
message = (Int32.Parse(Label1.Text) + 1).ToString
End Sub


Best regards,
Sergey Bogdanov
http://www.sergeybogdanov.com
 
G

Guest

I made that change (thanks... just overlooked it in my haste to get something
together to test) but it didn't have an effect. When Button1 is clicked, the
second app does launch and I am getting the event to fire (Label1.Text
changes to "Yes!") but my main app freezes after that. I have to go into
Running Programs and terminate it to get rid of it. Anything else that anyone
sees?

Thanks,
Rich
 

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