C# - how to catch the exact moment a program is installed/uninstalled - c#

I'm working on an application (A) that has to react and do something when a specific program (B) is installed on the system.
I've been seeing a lot of examples about listing programs already installed using the registry keys and some code to monitor status changes on programs and services using WMI.
I'm thinking I could use those combined to do what I want, say:
1. When my application (A) is started, check on the registry if my program (B) is installed or not (initial condition).
2. Then, monitor for service changes on the local machine from my application (A).
3. And every time a report of status changes comes from service "msiserver", re-check if my program (B) has been installed/uninstalled (initial condition has changed), and do something if so.
This sounds to me like I'm trying to reinvent the wheel here, and I wonder if any of you know if there's a more "natural " or "immediate" way to catch the moment/event when a specific program has been installed on the system ...or not :/
Additional considerations: The default location where the program (B) can be installed is variable, so monitoring for folders (like C:\Program Files) is not an option.
Thanks!

I'm not aware of any mechanism that would allow you to subscribed to an OnInstalled type event. You'd have to loop and detect the installation status change. Perhaps using the Microsoft.Deployment.WindowsInstaller (DTF) library to enum products and/or components. Don't use WMI... the Win32_Product class is horribly slow and querying it causes reinstalls of applications. (Don't ask... it just sucks).

Related

Get last exe file Execution Date (or Time) in Windows using .NET or VB6

Basically, I wouldn't find this anywhere. All I really need is date last executed, or even date last shutdown (that is, exe ended execution). I don't even need a catalog of all runs/shutdowns, just the last one.
I'm sure they must keep it somewhere. Reason being, in control panel (Win Vista) when you go to "programs & features" you have the option to sort the programs by how often they are used (which is run/executed) since this will not be based on last accessed time. Then, in their description, they quote usage frequency with terms such as "rarely", "sometimes", "often", "regularly" etc...
Now in Win7, if you right click on the columns & select "more..." from the installed programs listing control, you'll see a "Last Used On" option! This implies that last used date is at least kept somewhere in Win7.
Any ideas anyone?
Update: About LastAccess DateTime: LastAccess is too unreliable it seems (correct me if i'm wrong) it keeps on changing as soon as something (such as windows) accesses it. Maybe i should ask, does windows mess this field up by accessing the file to read info out of it (such as file size/dates etc) especially when browsing folders or does windows access files secretly to prevent contaminating the last access dates?
UPDATE 2
This is apparently different for MSI installations.
Information got from this thread (last post):
http://www.tomshardware.co.uk/forum/55552-45-remove-program-date
For an MSI installation Windows Installer maintains a usage count in its own registry > >based on Product and Feature, which can be found for example under
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\\Usage
This is maintained by the Windows Installer API.
MsiUseFeature() increments the usage counter (http://msdn.microsoft.com/en-us/library/aa370502(VS.85).aspx)
MsiGetFeatureUsage() gets the Last Used Date and the Use Count
The usage counter is also incremented when launching an application via an advertised shortcut or when using one of the MsiProvide*() functions.
UPDATE
Check out this article:
http://blogs.msdn.com/b/oldnewthing/archive/2004/07/09/178342.aspx
It seems like those values aren't stored anywhere, but more like an assumtion. So you might aswell use the File.GetLastAccessTime to get this.
You could also use a FileSystemWatcher and Process. Then set a flag when the FileSystemWatcher sees a change and the exe is started.

Automatic update

I have a system with two web applications, one web service, one Windows service and a WPF application running 24 hours a day on a touch screen. All of them are connected to a database.
I want to be able to upgrade all of those applications by uploading upgrade files to the database and set the date and time for the upgrade to occur.
I have one idea on how to do this.
An application has a thread running to look for available upgrades.
When an upgrade is found, the file is downloaded to the application's computer.
When download is complete, the applications triggers a restart.
When application starts, it looks for an upgrade file on the local computer.
If upgrade is available, the application upgrades itself.
I'm not really sure how all these steps should be done yet, especially the last one. But I want some comments about this. Is this completely wrong? Am I on the right track? Any tips on how to do it like this or in another way?
I think you're going down the right lines here. A polling application to check the database for the existence of a new update followed by an xcopy deployment script would do it.
This might be doable from a PowerShell script too, that runs on a schedule, say every 10 minutes. It could check the database, close the process and service, xcopy the application (from a shared source) and restart the said service and app.
All this assumes that you are not using Windows Installer to package and deploy your application initially. Although an xcopy to directly replace binaries wouldn't hurt an MSI package, it's not recommended. We use AD MSI deployment at work and it's a pain at the best of times!
MSDN contains references for MSI vs XCopy deployment for WPF applications (as well as the security requirements).
This was the first link I found for querying SQL from PowerShell: http://elegantcode.com/2008/03/27/discovering-windows-powershell/
Good luck!
You will have trouble doing this with ClickOnce. ClickOnce would only work for your WPF app, it can't do anything with the services or web application. You could write a separate ClickOnce-deployed "Updater" app whose job is to update the other apps, but that still seems a little iffy.
It may sound stupid, but I'd start with the simplest thing I could think of. How about using Dropbox to push your update files; then an AutoHotKey script that runs on startup, watches the Dropbox folder for new updates, and runs them?
Sounds hokey, but it's something you could prove out in an hour or two.
Microsoft have an Updater Application Block which might be what you are looking for.
Do you really want to run an update from the database or is this just a possible solution? You are reinventing the wheel.
Have a look at ClickOnce deployment, everything you need is already done for you and integrated into VisualStudio. If you use something that already exists you have the benefit of existing documentation, helpful blogs of people who have already gone through the pain points and updates and fixes.
ClickOnce Deployment
ClickOnce Deployment in .NET Framework 2.0
How you want to use ClickOnce depends on what you want to get out of it. Out of the box you can very easily create a deployment that checks for an upgrade every time you run the application but you can also with a little bit of code have the application check for updates whilst it is running.
The Updater Application BlockVersion that Dominic Zukiewicz mentioned is the pre cursor to ClickOnce.
EDIT
ClickOnce provides a roll-back scenario on both the Server and Client end. The client can roll back to a previous version using the normal add remove programs dialogue and you can easily republish a previous version.
You could create another Windows Service that does the updates on a daily basis. The service would look on a specific folder if there are any updates to be process. For example it could look for an xml file which tells it the new version of the application and what the files to update are. It would shut down the application/services, backup the files that it needs to update, start the application/services, and clean up backup files keeping at least three backup files. The service should keep track of the last and current version installed so that when it reads the xml file it can check if it is a new update or not or you can simply delete the xml file when it completes.
How about Google Omaha? It's an open source tool, currently used to push updates of Google Chrome and Google Earth. Omaha can handle application installation, too. A high-level design overview can be found here.

Windows seems to lose track of .NET application

We have a .NET application that we distribute to our users via an MSI installer package. We have C++ applications that run each morning to see if the user's copy of the application is out of date, and if so, we pull down the new MSI and install it. If the application is running, we need to take it down so we can perform the update.
Our problem is that every once in a while it seems like windows "loses" our application. It will not report that the process is running - though it is. It will allow us to overwrite, or even delete, the in-use executable file without taking down the application.
Maybe this is something that is common -- but we can't figure out what is going on! Does anyone have any insight into this situation?
It seems like a temporary copy of our application is getting created, and the program is getting ran from that. But if that is the case, why doesn't it happen all the time?
EDIT:
In our program, We are using the "EnumProcesses" function from the Platform SDK, PSAPI.dll, to enumerate all of the running processes.
Could it be that either the script or the application runs as a 64-bit program, and the other as a 32-bit program? If so, then on 64-bit machines the update check could be looking in the wrong location for an existing application and thus reporting it as missing?
What mechanism are you using to check to see if the process is running or not?
Try using something like process explorer to see what path the executable image is loaded from - it should be listed in the modules section.

Patch an application

I need to create a patching routine for my application,
it's really small but I need to update it daily or weekly
how does the xdelta and the others work?
i've read around about those but I didn't understand much of it
the user shouldn't be prompted at all
Ok this post got flagged on meta for the answers given, so I'm going to weigh in on this.
xdelta is a binary difference program that, rather than providing you with a full image, only gives you what has changed and where. An example of a text diff will have + and - signs before lines of text showing you that these have been added or removed in the new version.
There are two ways to update a binary image: replace it using your own program or replace it using some form of package management. For example, Linux Systems use rpm etc to push out updates to packages. In a windows environment your options are limited by what is installed if you're not on a corporate network. If you are, try WSUS and MSI packaging. That'll give you an easier life, or ClickOnce as someone has mentioned.
If you're not however, you will need to bear in mind the following:
You need to be an administrator to update anything in certain folders as others have said. I would strongly encourage you to accept this behaviour.
If the user is an administrator, you can offer to check for updates. Then, you can do one of two things. You can download a whole new version of your application and write it over the image on the hard disk (i.e. the file - remember images are loaded into memory so you can re-write your own program file). You then need to tell the user the update has succeeded and reload the program as the new image will be different.
Or, you can apply a diff if bandwidth is a concern. Probably not in your case but you will need to know from the client program the two versions to diff between so that the update server gives you the correct patch. Otherwise, the diff might not succeed.
I don't think for your purposes xdelta is going to give you much gain anyway. Just replace the entire image.
Edit if the user must not be prompted at all, just reload the app. However, I would strongly encourage informing the user you are talking on their network and ask permission to do so / enable a manual update mode, otherwise people like me will block it.
What kind of application is this ? Perhaps you could use clickonce to deploy your application. Clickonce very easily allows you to push updates to your users.
The short story is, Clickonce creates an installation that allows your users to install the application from a web server or a file share, you enable automatic updates, and whenever you place a new version of the app on the server the app will automatically(or ask the user wether to) update the app. The clickonce framework takes care of the rest - fetching the update , figure out which files have changed and need to be downloaded again and performs the update. You can also check/perform the update programatically.
That said, clickonce leaves you with little control over the actual installation procedure, and you have nowhere close to the freedom of building your own .msi.
I wouldn't go with a patching solution, since it really complicates things when you have a lot of revisions. How will the patching solution handle different versions asking to be updated? What if user A is 10 revisions behind the current revision? Or 100 revisions, etc? It would probably be best to just download the latest exe(s) and dll(s) and replace them.
That said, I think this SO question on silent updates might help you.
There is a solution for efficient patching - it works on all platforms and can run in completely silent mode, without the user noticing anything. On .NET, it provides seamless integration of the update process using a custom UserControl declaratively bound to events from your own UI.
It's called wyUpdate.
While the updating client (wyUpdate) is open source, a paid for wybuild tool is used to build and publish the patches.
Depending on the size of your application, you'd probably have it split up into several dll's, an exe, and other files.
What you could do is have the main program check for updates. If updates are available, the main program would close and the update program would take over - updating old files, creating new ones, and deleting current files as specified by the instructions sent along with a patch file (probably a compressed format such as .zip) downloaded by the updater.
If your application is small (say, a single exe) it would suffice to simply have the updater replace that one exe.
Edit:
Another way to do this would be to (upon compilation of the new exe), compare the new one to the old one, and just send the differences over to the updater. It would then make the appropriate adjustments.
You can make your function reside in a separate DLL. So you can just replace the DLL instead of patching the whole program. (Assuming Windows as the target platform for a C# program.)

Updating a desktop application without touching the attached .mdf

Just a quick question:
I'm in the finalizing state of my current C# project, and I'd like to send a version out to people that has 90% of the features initially requested, but it'll be a version of the software that will do all they need - they need the software as soon as possible, basically.
Therefore I'm going to be using the online install option in VS2008 that will use updating to add the final few features, as well as additional things, later. What I'm wondering is the following:
The program will come packaged with a .mdf file. When I create a new version of the program however, I don't want to change all of the data that has been added to the database already. My question is how do I go about doing this?
Thanks!
How are you planning to distribute the update? An installer will have flags indicating when a file should be replaced. (Date, version etc)
One-Click installation has the ability to check for changes on program startup.

Categories

Resources