I need to update my executable with also the dll linked..
I've read about the AppDomainSetup.ShadowCopyFiles but I'm in trouble trying the right steps to do what I need
the question are:
the shadow copy I need to create only when I notify an update or each time I launch my executable?
what is the right step to copy and update the dlls and the .exe?
Creating a shadow copy is not going to update your application. The general sequence of auto-updating requires a third application that manages the process. It looks something like this.
Main application finds update and downloads update files to temp location
Main application launches updater application and terminates itself
Updater application copies update files over main application files
Updater application launches main application and terminates itself
Obviously there is going to be error handling logic built in to this. But that is the general idea. Shadow copies are nowhere in there.
Making use of the shadow copy feature of .NET is not a bad idea. It will allow you to update your assemblies without having to exit the application BUT you will need to restart the application in order to run the updated version. Shadow copy will simply allow you to overwrite the assemblies and nothing else.
Note that you cannot enable shadow copy on the default AppDomain. This means that you will need a loader that will create the AppDomain, and execute your application. Have a look at this answer for the steps you need to take and for a simple implementation.
If all you want to do is allow updates to be installed without having to exit the application then this is the simplest approach I can think of.
You should also have a look at Microsoft's ClickOnce technology. It solves a lot of the common problems of deploying and updating .NET GUI applications.
Related
I have a windows app (written in C#...) that is installed on multiple remote workstations, the installation is being done by a MSI package.
An updated installation with changes to the program is being conducted from time to time, at this point, for each update, for each station we need to go to where the .MSI is located copy it and run it and only than start the app.
I would like that: whenever a user tries to start the app a background process will be initialized that will compare the installed version with the most recent version on the .msi location and if an update in needed will run the installation and than start the app.
The problem is that it can't be done from within the program since the program cannot be running when the installation/upgrade is taking place. Another consideration is that not all the stations operating at the same time so I can't schedule a timely upgrade, and it can't be done on stations boot since sometimes the updates needs to be done while the station is already operating(the station has several functions beside my app).
I have considered several approaches, it seems like a windows service could do the trick but I don't know if it could be "bound" to the initialize of the program and if it could suspend the program to do the necessary checks and updates and only than to restart the app.
I am open to all ideas so please don't feel obligated to my ideas...
at this point, for each update, for each station we need to go to where the .MSI
is located copy it and run it and only than start the app.
Fire the guy pretending to be a system administrator.
Unless you have done something odd in your installer - it should be doable with your standard software distribution package. Heck, I can roll out updates with active directory ONLY and no third party software as long as the MSI allows administrative no ui installs.
You try to fix a non-problem. Software distribution is a solved solution for the last 15 to 20 years. MSI was particularly created to handle this issue because other approaches demonstrated issues.
So, whoever pretends to be the administrator on your company needs to get his act together and be one. Do nothing (except making a good MSI) and let the admin do his job.
Everything else just creates a lot of problems (at least in the cost side). And it is totally not needed.
I'm updating my answer,
This is what we did....
Create the Installer / Package ( you can install for all users here)
Generate Bootstrapper (https://msdn.microsoft.com/en-us/library/ms165429.aspx
You can use this tool create bootstrapper (http://www.softpedia.com/get/Programming/Other-Programming-Files/Bootstrapper-Manifest-Generator.shtml)
Add dependencies and other conditions in bootstrapper
Set the URL for updates
This will solve your problem. I was too quick to answer but this how we did.
Thanks.
Some comments and answers about the assumptions in the question:
"I would like that: whenever a user tries to start the app a background process will be initialized that will compare the installed version with the most recent version on the .msi location and if an update in needed will run the installation and than start the app."
The only time this is likely to be a useful approach is when the MSI is at a company's web server. The web site can host a web api that you send your ProductCode, Version, Upgrade to and it reports whether there is an upgrade, patch etc, and a location to download it from. In a company domain, just use AD, as has been said.
"The problem is that it can't be done from within the program since the program cannot be running when the installation/upgrade is taking place."
Why? Windows Installer will show FilesInUse dialogs for the end user to close down the running app. So this situation is already dealt with, and I'm not sure where you see a problem.
"...and if it could suspend the program to do the necessary checks and updates and only than to restart the app."
This is exactly what Restart Manager is for. Integrate your app with RM and Windows Installer will allow you to close down the app (saving whatever data you need to recover) and then restart you afterwards so you can recover your data and the user sees a minimal interruption. One example:
http://www.codeproject.com/Articles/772868/Restart-Manager-Support-For-Windows-Application
So I think TomTom's point is valid - there is no need to re-invent what AD does, or worry about how to update programs that are running, or how to restart a program after an installer update because all these problems were solved years ago.
Let me layout the scenario.
We have a 3rd party application (say, app.exe installed to C:\App). It actually cannot run directly, it needs a configuration file passed to it as an argument: "C:\App\app.exe config.ini". Everyone already has shortcuts that contain the necessary arguments.
This application supports plugins, of which we have developed a few. In order to distribute said plugins, they need to be copied to each users C:\App\Plugin\ folder, so when a change is made I have to travel around to everyone's desk and make sure the update gets applied.
This was cumbersome, so I developed an application that will scan a network folder and compare it to it's internal db of files. If there are any changes, it copies the files over to the proper destination folder.
This wasn't seamless though, as the user would have to make sure app.exe was closed - run my updater, and then rerun app.exe. So I renamed the original app.exe to app_launcher.exe, and my updater to app.exe. I modified my updater application to support arguments and pass them through to app_launcher.exe when the update was done. Once app_launcher.exe has started the updater program closes.
I should note - the above actually works.
The problem comes from users who have the app shortcut pinned to the taskbar. Once the real app finally starts it gets it's own new icon on the taskbar instead of being grouped with the original shortcut. This actually makes sense as they are technically two different applications. The users however, don't like this.
I have done some research on this, and found some 3rd party programs that can allow you to group multiple programs (Bins/Fences). I DO NOT WANT THIS.
More research revealed something called the AppUserModelID, which intrigued me. After some playing around, I got my updater to set it's own AppUserModelID. The original app.exe didn't set it's AppUserModelID (found that out via ProcessHacker), but I was able to get the updater to start it with the same ID it was using via the CreateProcess method found in kernel32.dll.
This did NOT work. The updater started under it's own pinned icon, and the original app started a new icon. I tweaked the updater to stay open until the original app was closed to see if that made a difference. This time it started under it's own pinned icon, the original app started it's own, and then the updater window switched to be grouped with the original app under the new icon. So AppUserModelID did group them together, but not how I wanted.
I am using C# for the updater application, and cannot make changes to (or have changes made to) the original app.
How can I get these applications to group under the pinned shortcut? Is it even possible?
I think I may have found a solution, though it's a bit of a hack.
The problem comes from having the final application not matching the shortcut being run.
So rather than replacing the EXE and running the real one when done, I made sure the updater application would always run before the real exe.
The only caveat is that it also runs for EVERY exe on the system (via HKCR\exefile). The first parameter is now the path to the true executable, which if it matches the application it runs the updater. Once the updater finishes or if it is any other app, it runs it.
Not an ideal solution (as it could be detected as malware), but it should work for us.
I searched that question over the internet and here , and saw all kinds of different solutions.
The most common solution suggested was ClickOnce .
My problem is :
my application is a backup application.
It runs 24/7 , and I want the update to be automatically without any user interface.
As backup apps usually runs on servers and aren't monitored at all times.
ClickOnce offers great update solution but it is with user interface and it isn't what I need.
The best thing I could think of is to build a separate app that my main app will call it,
the update app will close the main , download the update , extract the update , and recallthe main app , and then close itself.
I have several problems with my approach :
1. Where to place the folder(named: Update) containing the update exe file and all dlls that is neccecery to update. Is it a good idea to place it inside my main app folder ?
2. What will happen if I need to update the update.exe file ?
I would really appreciate if you could shed some light in this matter with your experience.
You can programmatically run ClickOnce. Will that work for your purposes?
http://msdn.microsoft.com/en-us/library/ms404263.aspx
I have a program that consists of two programs: Updater and WorkMaker.
Whenever there is an update for WorkMaker - Updater kills it, downloads updates, and runs it again.
But say I came up with new Updater program.
How do I update it? Through WorkMaker? Through the third program?
Thanks.
The simplest solution IMHO is:
At the moment was requested update MainProgram downloads Updater, along with updates, after launches Updater.
Updater closes MainProgram, makes update and relaunch MainProgram, or simply exit.
In this way you have flexible way to update your program (MainProgram), but also Updater itself, when its required.
Hope this helps.
I'm not sure how far along your application's architecture is, but as a total replacement for "Updater" have you considered using ClickOnce for managing the deployment of "WorkMaker"?
It will ensure that it's running the latest patch on startup. If the application is a long running one, then you can also manually kick off upgrades too.
I use a similar setup to run our msi and msp files when necessary. The solution consists of a small executable that loads a worker DLL in a second AppDomain using Shadow Copying. The executable is so simple that I've never needed to change it. However, I can now easily patch my worker DLL as I please since it's not locked in its original location on disk.
You could have your updater dowload the update, run it with some parameters and have the new updater delete the original.
You could also have WorkMaker act as the updater for your Updater program.
I have an application that is running fine.
I just want to add the auto update feature in that application so that the application can automatically download the updates and install it on the computer.
The easiest way to do this is to make your application a ClickOnce application. It is a method of application deployment which has a very simple process for deploying new versions and having the client check for and install updates. Here is a CodeProject articles which has a full overview
http://www.codeproject.com/KB/install/QuickClickOnceArticle.aspx
It depends on how your application is structured and what kind of files you want to update.
But, basically, what you'll need is a "place" (like a WebService, for example), where your application will get the necessary info to update. Then it's downloading the necessary files and placing them in the correct folders.
I'd also advice you to write a new program, "updater", whose whole purpose it's to update your "main" program.
It's difficult to give you code on how to do this, as it it's more like a pattern that you'll have to implement.
Edit Also, as said by JaredPar, some platforms may provide tools to do this.