Despite my thorough googling, I am still confused on this matter.
Let me explain my situation. I created a c# project which gives the user the ability to back up the database manually (via a button click). Now the user must be able to schedule a time at which the database back up will run automatically. To achieve this, I am planning on creating a service which is started via the windows scheduler when the set back up time is reached.
I will need the deploy the service along with the main project (In my head, the service will be a different project. Maybe I am wrong here.).
My question is how do I deploy the service when the user installs the main project?
PS: I am using c# express and sql 2008 R2 express.
What are you using to install the main application. Chances are you the said packaging tool will also have hooks for allowing you to install the service. For example, if you are using Wix to create a msi package to install the main application, then you can configure Wix to also install the service.
This google search will point you to relevant articles for the same.
If instead you are not using any installer tool, say you simply give the user a zip containing all executables, then you will need to manually install the service. This article is perfect to create a self installable service. You could use Process.Start to execute the installutil exe to acutally install/uninstall the service.
Edit1:
Building on Rup's comment to your question, you already have the code required to backup the database. All you need, is to be able to schedule this. Once the user enters a schedule in your UI, you can create the corresponding task in the Task Scheduler. Have that task execute your main application, passing in the argument -backup "dbName" or what ever info is needed for the before mentioned backup code to run.
You may use the following template [which is meant for a console app, but will work just fine for your gui app as well. All you will need to check is if any switches have been passed in, then do not start the gui, instead simple execute the backup function code.] ... There are also a lot of existing questions on StackOverflow on which commandline parsing tool to use ...
The approach I would take is create the project for the UI, create a project for the service. The service would be a windows service that would always be running and would be responsible for creating the scheduled task. (Rather than having a scheduled task start the service.) How you go about creating the scheduled task is fairly open, you could shell out AT, or you could do some COM interop with the TaskScheduler type libs. I hope this helps.
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.
My application is installed on ATM-like machines arouns the world.
It is a WPF application which needs to be automatically updated behind the scenes and without user interaction at all.
Right now we're using Click-Once silent install API and it works perfectly. Our current functionality keeps checking constantly behind the scenes if there is a new version and if such exists, it updates the application, waits for the machine to be Idle (untouched by any users for 5 minutes) and only then it restarts the app. After the restart, a new version is loaded.
Is there a way i can achieve all this using MSI's ? Here's a summary of what i need:
Remote and silent updates for all machines - i already know i can achieve this using LogMeIn and MSIEXEC (so no need to answer this bullet)
Update the application while it is running, without restarting it.
Restarting the application and running the new version only when the application is Idle for 5 minutes.
Any suggestions? If not MSI then any other installer perhaps?
I Can't use clickonce because i want to set my application as the Shell (instead of cmd.exe) in Windows Embedded 8.
It's an interesting high availability story and I can' think of a way to solve it and while MSI will work, it's not really an installer problem per say.
I'd create two installers: ContentManager and Application
The CM once finished should hardly ever change. It's job is to check for available updates and the idle status of the application. When an update is available and the application is idle it can perform a new silent side by side install of application in the background. Note I said install not upgrade. Now you have 2 versions of application installed. When the old application is still reporting idle it could be shutdown and the new version launched.
This would be highly available and MSI wouldn't need to know anything about the scenario. It's simply performing an install.
If you don't need it quite this highly available, then the other thing to consider is that Windows Installer supports "Restart Manager". Your WPF application can also. Your application could check for updates and start an upgrade. The restart manager interaction would then stop and restart your application during the upgrade.
The nice thing about the HA solution is your old version is still there. The content manager could back out the change simply by running the old version of the application.
#Christopher Painter, Thanks for your response. A few thoughts:
The High-Availability solution is good at its base but it would require us to implement too much stuff on our own. A few things you haven't mentioned for such scenarios: 1. what happens if a download fails, what happens if the unzip fails, i would need to uninstall the previous version once install is complete, i would need to implement some security measures on my own (hashing for the 'version xml' or something like that...) how about shared resource locking? i would need to handle it on my own as well... Click once handles all this stuff nicely. Oh and one more thing i'd like to avoid is maintaining two applications instead of one as you suggested. I can't count on the 'Manager' so much that i wouldn't support updating it remotely. I can, however, use a 'push' methodology to activate the MSI using LogMeIn - It lets me upload and send a command to all machines (AMTs). The Restart Manager solution would work for me. Only thing i still haven't figured out is if i can make it hault until the application is Idle, and for how long (it must have some sort of a timeout). I've also researched MSI Custom Actions which can wait on a shared mutex ('idle'). What do you think?
I want to create an executable in VS 2010. This executable will be create an excel spreadsheet and will transfer that file via FTP. I want this executable to be fired off via Windows tasks.
What is the best way to accomplish this? Would I create a regular windows form application, dll, or Empty Project, or windows service?
Thank you in advance for any assistance.
A plain old console application scheduled with the task scheduler should do the trick.
If you need the application to run when a computer is turned on but no one is logged in, create a service. If your application runs only when someone is logged in, but has no UI, use a console application. If your application runs only when someone is logged in and has a UI, use a Winforms app.
I'm not sure what the current best practice is, but in our shop we create console applications and use the task scheduler to execute them.
A library (dll) won't be executable from the task scheduler AFAIK, and a WinForms app isn't very useful for any app that runs automatically (i.e.: doesn't require user interaction).
A service would be appropriate for an application that needs to respond to system events/changes when they occur, which doesn't sound like your use case.
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.
Usually a mobile dev would not have to do this because the smart-minimise feature handles it.
But I need to do it myself because my mobile app is kicked off by a bootstrapper app.
The start menu icon kicks off the bottstrapper which downloads a target version from a web service, kicks it off and then closes. If the app gets minimised for whatever reason, the user would normally activate it again using the start menu icon. However, this kicks off the bootstrapper and results in a second copy of the client.
This question comes up everywhere on the net for desktop apps (and is in fact on this site). The usually cited solution is to use a combination of Process.GetProcessesByName combined with API calls to re-activate the process once found. Another solution is to create a controller class that inherits from some VisualBasic dll that I forget the name of. None of the solutions I have come across today are supported by the comapct framework.
So the actual question is a combination of:
Is there a compact framework alternative to Process.GetProcessesByName?
If not, what API call do I have to do instead?
I'm not sure if you found this yet or not, but MSDN has an article on creating a process manager application that has the info that I think you need.
The article reccomends using toolhelp.dll and has a pretty detailed looking walk-through for getting a list of running processes. It's for Visual Studio 2003, so you should probably be good with whatever version of VS.NET you're running.