I have a simple console application written in .NET. I need to make an installer for the console application and put it in the server directory. This can be achieved by using the Setup Project in MS Visual Studio. I also want the ability that whenever I open the app it checks for a new version. If the new version exists then it installs it. Any recommendations on how to achieve this in .NET?
ClickOnce handles versioning for you. Simply publish new versions to the same place as previous versions, and when the user starts the app they will receive notice of the new version. That's part of the whole point of ClickOnce. The downside is, you lose control over the location of your application in the user's filesystem (for a simple console app like yours, that's probably not a huge deal, but I'll leave that decision to you). We've also had difficulty with certificates; if you sign your ClickOnce manifests (strongly recommended) you have to keep exactly the same certificate, strongly identifiable from a major CA, to keep the ClickOnce process strictly "click once".
Pretty much the only other way to handle versioning is to implement some web service that will report the most current version, and have your app call that service on startup to notify the user of upgrades. The upside is that your users still control where the app goes, and you can control where the app is published (if the next version needs to go on a different server, no problem; just point the user there using some information returned by the web service). The downside is more work for you to develop and deploy.
Related
I have seen there are many technologies out there that make auto updating easy for the user (such as winsparkle). The problem we have is we want to be able to auto update our desktop (c#/c++) app without prompting.
If users have the ability to NOT update it makes our lives hell (10,000+ installs all need to be updated about once a month).
We currently install our application via WIX and it reinstalling a new version completely overwrites what was there before. This works fine but we'd love to not even have to run the new installer, thus the idea of auto updating.
I've looked at clickonce but since our app is both a tray icon/windows forms app and a Windows Service it appears installing a service via ClickOnce is somewhat unfeasible.
Any suggestions?
To do this update behavior you need two things:
1) An updater application which checks for updates regularly. If an update is found it should install it automatically. Most commercial setup authoring tools include good updater applications. You can try writing an updater yourself, but it's not as easy as it sounds.
2) Per-user installations for each of your product versions. A per-user installation writes data only in the user profile folder (AppData, Roaming folder etc.) and HKEY_CURRENT_USER. No Program Files or HKEY_LOCAL_MACHINE.
Per-user installations are required so you can perform the upgrade silently. If the installation is per machine, newer Windows version will show the elevation prompt and the user won't know what's happening.
The Updater
Some updaters use services. For automated updates this isn't a real solution because service installation needs Administrator privileges. So your install process and subsequent updates would show elevation prompts.
Another approach is to use a per-user Updater application. It doesn't require any elevation and it can be installed in the application folder. This type of updater can run either as a scheduled task or from within your application (execute it when your application starts).
In both scenarios you need to consider that the Updater may need to update itself. So the process which performs the update must be a temporary process (for example a temporary copy of the updater application). It also should run without elevation. This is why a service is not such a good idea. It would need to stop itself before the update, use a temporary process which handles the update and start again when finished.
Here's what I ended up doing for some applications that I manage, and that are written in C#.
I distribute an installer based on InnoSetup to deploy the files on the user system, and the application stores information version in the registry.
The application has a mechanism that checks at startup for available updates, and prompts the user. This system is based on a JSON manifest that contains a basic structure such as the following:
{
"releases": [
{
"CommitDate": "2020-09-05",
"Version": "0.1.0.0",
"VersionString": "0.1.0+19",
"SHA": "4ff750da44b41e569daf3c62f4495a8ee2b25f08",
"InstallerMd5Sum": "805497b5c13ee070b7465bb32689e0dd"
},
{
"CommitDate": "2020-09-07",
"Version": "0.1.0.0",
"VersionString": "0.1.0+22",
"SHA": "a04ec929b21230ba0e2577617713d10b106266e9",
"InstallerMd5Sum": "805497b5c13ee070b7465bb32689e0dd"
}
]}}
The application downloads that file and compares its local information with the latest entry in the file.
If the latest entry is more recent (based on things like commit date), it retrieves the installer from the distribution server, checks for integrity, and run the installer.
The installer takes care of updating the entries in the registry with the latest information.
Now, there are three angles to your question I believe.
The first one is whether a modularity is possible so that you don't end up replacing everything and can provide delta installers, the second is whether you can use a technology that knows how to deal with updates (which I believe MSI knows how to do). Finally, the third angle is whether or not you have a way for users to rollback in case the latest version has issue with their system or whatever your application is for.
I have a web app and want to transfer data from client's machines to us every day. Assume there is a common API on every client machine to extract data from. To make this work, I have to create:
An API to receive data from clients - using WCF, seems ok at this point
An application that's installed on client machines
The client app needs to store info from the user (eg username/password to access our API - encrypted with DPAPI). The app needs to run daily (probably with a random Sleep() command so our API isn't overloaded all at once). It also needs to be easy to install.
I've created a console app which talks with the client API and our own API. I've used Visual Studio's Settings.settings with a user scope to save the persistent settings - if parameters are provided then it stores these settings, if no parameters it uses the stored settings.
How can I make this usable for the end user? I'm thinking a separate installer/configuration program that installs the exe file (and its dependencies) and asks the user to enter the settings to be stored (which can also be read by the client app). It would have to set up the scheduled task and also offer the ability to change the configuration (the stored shared variables).
Hoping someone can help architect this solution?
Thanks so much!
I think that your idea about an installer is correct since you will most likely have dependencies or prequisites to install.
However, rather than building the settings logic into the installer, I would recommend that you build a UI for this in your application so that the user can adjust it post-installation if needed.
For example, if the user changes their password, in your current design, the user will have to uninstall and reinstall the app. Also, if the scheduled time is incompatible with some other operations on their machine, then they will need to adjust the time without uninstalling and reinstalling.
You could build the UI and API interface into a single application: just change the behavior (runtime or configuration) with a command line switch (for example, only use a /runtime command line switch for the scheduled task).
What are some best practices for being able to deploy a Windows service that will have to be updated?
I have a Windows service that I will be deploying but might require some debugging and new versions during the beta process. What is the best way to handle that? Ideally, I'd like to find a ClickOnce-style deployment solution for Windows services but my understanding is that this does not exist. What is the closest I can get to ClickOnce for a Windows service?
A simple solution that I use is to merely stop the service and x-copy the files from my bin folder into the service folder.
A batch file to stop the service then copy the files should be easy to throw together.
Net stop myService
xcopy \\myServerWithFiles\*.* c:\WhereverTheServiceFilesAre
net start myService
I have a system we use at work here that seems to function pretty well with services. Our deployed system has around 20-30 services at any given time. At work we use a product called TopShelf you can find it here http://topshelf-project.com/
Basically TopShelf handles a lot of the service related stuff. Installing, Uninstalling etc all from the cmd line of the service. One of the very useful features is the ability to run as console for debugging. You build one service, and with a different cmd line start you can run it as a console to see the output of the service. We added one custom feature to this software that lets us configure profiles in advance. Basically our profiles configure a few things like logging, resource locations etc so that we can control all that without having to republish any code. All we do is run a command like
D:\Services\ServiceName.exe Core.Profiles.Debug or
D:\Services\ServiceName.exe Core.Profiles.Production
to get different logging configurations.
Our build script creates install.cmd and uninstall.cmd scripts for each of our services all we do is copy the files to the server and run the script. If we want to see debug output we stop the service and double click the exe and we get a console to read all the output.
One more thing that topshelf has which we don't use because its not necessary is the concept of shelving (there is documentation on this website for this). This allows you to update the service without having to "restart" but you still need to copy the files manually unless you build an automated system for that.
However, my suggestion if you need 100% service availability is to have a redundant system. No matter how you configure your service for updates you cannot avoid hardware failure causing downtime without an automated failover system. If said system was in place my recommended update strategy would be to turn off 1 node, update, test, turn on turn off the other node, update, test and turn the 2nd node back on. You can do this all of course with a simple script. This may be a more complicated system than you need but if you can't take a service offline for a simple restart that takes 5 seconds then you really need some system in place to deal with hardware issues because I can guarantee it will happen eventually.
Since a service is long-running anyway, using ClickOnce style deployment might not be viable - because ClickOnce only updates when you launch the app. A service will typically only be launched when the machine is rebooted.
If you need automatic update of a service then your best bet might be to hand-code something into the service, but I'd forsee problems with almost any solution: most install processes will require some level of user interaction (if only to get around UAC), so I can't imagine this would lead an answer that doesn't involve getting a logged-on user in front of the screen at some point.
One idea that might just work is active-directory deployment (or some similar equivalent). If your service is deployed via a standard MSI-type installer, AD allows you to update the application silently as part of the computer policy. I suspect you'd have to force the server to refresh the AD policy (by rebooting or using gpupdate from the console), but other than that it should be a hands-off deployment.
I would suggest using the "plugin" approach on this, that is, using the Proxy Design Pattern.
While using this pattern, an independant thread may verify over a folder for updates. You will need to use ShadowCopy over your assembly deployment. When your service update-thread encounters a new version of your service, it shall unload the current production assembly and load the new version, without stopping the service itself. Even more! Your service should never notice the difference, if there is no breaking code within your assembly.
I would suggest to create a normal setup project, and add the windows service project output in that setup project.
For more information please refer to http://support.microsoft.com/kb/816169.
I have build an C# Winforms application which will need regular updates and patches in the future. To ease the update process for the users of my app I'd like to build an web-update class that looks for an update on my site.
What would be the most secure and reliable way to implement such a class, considering:
The site is build in PHP / Joomla
I haven't the foggiest idea how to program in PHP
All webserver directories are read-only by default (and only writeable by an FTP account I own)
The first and so far only idea that comes up to me is to create a file on my webserver that'll never be renamed, and in it I'll define the location of the latest version and number of it. The app will then be able to download the update from that path using the WebClient class.
However, if there's anyone with a better update-class idea that doesn't require an asp.net webserver nor webservices (already tried and failed on that one), I'll be grateful.
Edit:
I've tried the ClickOnce solution suggested by Gabriel McAdams, but on application startup I experience a "ClickOnce launch utility has stopped working" crash. So I'm again looking for a solution to update an application. For the moment, the answer of Kristian Damian is the most suitable.
I would look into ClickOnce Deployment.
Here is some of the text from that page:
ClickOnce deployment allows you to publish Windows-based applications to a Web server or network file share for simplified installation. Visual Studio provides full support for publishing and updating applications deployed with ClickOnce.
Maybe this link can help you:
http://themech.net/2008/05/adding-check-for-update-option-in-csharp/
I developed a Windows application in C# that does updates automatically over the Internet. After much grief, mainly because at that time I had very little experinece with Web development, I purchased a product that made it easy to update the application. If it is OK with StackOverFlow and you are interested, I can give you the URL.
I've got an app that publishes and updates from an http update location (I publish to the ftp site of the host, and update from the website).
The publish.htm page is very handy as I can install the app on any machine, anywhere without needing media. The problem is, so can anyone else. How can I secure the update location so that only authorized users can install the app without buggering the auto-update feature of clickonce?
Is this an internal application? If so you could just exclude the publish.htm page from your deployment. Then to install you would then just use the application manifest link http://yoursite/YourApplication.application which should kick the install off, this would not affect automatic updates. This may be just enough obfuscation to for your purposes.
Failing that you can dynamically generate the application manifest using a little bit of asp.net which would only produce the manifest for the users you want. The other benefit this has is that you can isolate a small group of users when rolling out a new version.
Just a thought.
If you're still transferring over HTTP, it's as easy as running a traffic sniffing program like Wireshark to see where the application is downloading from. To evade this you'll need to make sure to transfer over HTTPS, on top of whatever obfuscation you do to hide the update location.