Replace running .exe file

G

Guest

Hello

I have a Windows.Forms application program running in kiosk mode on Windows
CE, and I want to add support for updating the program with a new version
located on a USB memory stick.
By updating I mean replacing the entire .exe file.

I have tried different approaches using the System.Diagnostics.Process and
System.IO.File
classes. Regardless of approach, the running .exe file (or process) must
somehow be stopped such that the lock placed on the .exe file is removed,
making it possible to delete or overwrite the file.
How can this be done?

One of my approaches is as follows:

1) Assume the running application program is located on
\ Hard Disk \ myApp_v1.exe

2) Insert a USB pen with two programs:
\ USB Disk \ myApp_v2.exe
\ USB Disk \ UpdateAssistant.exe

3) In 'myApp_v1.exe' then execute the following code:

Process updateProcess= new Process();
updateProcess.StartInfo.FileName = @"\ USB Disk \ UpdateAssistant.exe";
updateProcess.Start();

//Terminate myApp_v1.exe which has only 1 Form (Window)
this.Close();
Application.Exit();

4) In 'UpdateAssistant.exe' execute the following code from the constructor:

// Try deleting 'myApp_v1.exe' to see if lock is removed
File.Delete( @ "\ Hard Disk \ myApp_v1.exe");

This results in an IOException, meaning that 'myApp_v1.exe' is still in use
and therefore locked.
Is it not sufficiant to call 'this.Close()' followed by 'Application.Exit()'
to terminate a Windows.Forms application?
 
G

Guest

If the app is yours put in a shutdown watcher. Typically I'll start up a
Timer at app start that once every second or so checks for a named system
event. When it is set, it closes the main form of the application, causing
it to exit.

So your "updater" app would start up, set the event, wait a little while (I
often use a named mutex in the primary app to see if it's running in the
first place and to know when it exits) then update and relaunch.



--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Managed Code in an Embedded World
www.OpenNETCF.com
 
M

Milsnips

Hi there,

i had a similar problem i came across, what i did was create a "starter.exe"
app which checks if there is a "setup" file or updated exe file in a
specific folder, if so, it installs it / replaces the old file with the new,
then it continues to start the main app by starting the process for my
"app.exe"

Paul.
 
G

Guest

Another way to check for events is to create a class that inherits from
Microsoft.WindowsCE.Forms.MessageWindow. Override the WndProc class and look
for messages. In the constructor of the class use the RegisterWindowMessage
to create a named message. Here is the code:

[DllImport("coredll.dll", EntryPoint = "RegisterWindowMessage",
SetLastError = true)]
public static extern uint RegisterWindowMessage( string lpString );

Then check for the message id equal to the message id created using the
above call. In your update application create the exact same windows message
(Must be the exact same name) Call SendMessage using the Broadcast to all
parameter. When your initial application receives the shutdown message,
close it.

You can also create a named mutex in the application to be shutdown, and
release it on shutdown. YOur shutdown application could monitor this mutex
and wait for it to be released, signaling your initial app is shut down, then
you can overwrite the file.

Rick D.
Contractor
 
J

Jerod Houghtelling

I've did this before by passing in the process id to the
updateassistant program.

MyApp snippet
 
G

Guest

Thank you very much for advice.

By using the OpenNetCF which allows me to use named Mutexes I am now able to
replace the .exe files.
I do however still have one problem:
Before replacing the .exe file I want to check if the new .exe file found on
the USB hard disk is a new version. I have tried to use the
AssemblyName.Version property for this purpose, but it seems that since the
assembly name of the running .exe file is identical to the assembly name of
the .exe file located on the USB, the version of the currently executing
assembly (the running .exe file) is always returned. The code executed by the
running .exe file is as follows:

Assembly assem = Assembly.LoadFrom(sPathOfExeFileLocatedOnUSB);
AssemblyName assemName = assem.GetName();
return assemName.Version.ToString();

How can i retrieve the assembly version of the .exe file located on the USB
when the executing assembly has the same assembly name?
 

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