How to tell if an Installer (InstallShield specifically) completes successfully? - c#

I am starting an installer from my application and then synchronously waiting for it to complete.
Process installerProcess = Process.Start("TheProcessName");
// Must EnableRaisingEvents before calling synchronous method WaitForExit
// according to MSDN documentation.
installerProcess.EnableRaisingEvents = true;
installerProcess.WaitForExit();
My application needs to know if this installer completed successfully or not. If the user cancelled it or it failed for any reason, I need to find out.
I tried the ExitCode property of the process thinking that '0' would signify success and all other codes would signify failure but it showed the same exit code for a successful or unsuccessful install so now I am stumped. Any ideas? Or is there a better way of doing this than I am currently doing it?

What type of InstallShield project are you using? MSI or script driven? I've always had msixec and setup.exe return meaningful exit codes. Something is not right here.

I believe the approach Windows uses for checking installer compatibility is to watch the number of keys under the Uninstall registry key. If this increases, chances are good that the install was a success. In your case you could probably look for just any relevant registry key installed by the particular installer you launch, but its uninstall key could be a good choice.

Related

Kill windows service forcefully in WIX

I have windows service which will get installed as part of wix installation . Problem is that, currently service is in production and it is not responding to stop due to some poorly written code in service OnStop method .
So next time when the user tries to install upgraded version installation will fail because service will never stop when wix tries to stop the service .
Is there any way in which i come to know if wix is taking too much time to uninstall and i can kill the process if i get that notification ?
Also, is there any way i can kill process based on product version ?
Thanks
I have found a solution for this after digging for sometime .
I am creating new C# custom action project and i am sequencing my action before InstallInitialize.
In my C# custom action method, i am reading the existing installed file version by using
FileVersionInfo.GetVersionInfo(filePath);
Then i am checking with desired version which i want to check and if condition matches i am killing my service process using
foreach (Process proc in Process.GetProcessesByName("ProcessName"))
{
proc.Kill();
session.Log("Service Killed");
}
in order to achieve this, Wix toolset v3.11.1 has to installed beforehand
Maybe try this: newer answer.
I shouldn't answer this since it has been ages since I have dealt with stuff like this, but what the heck, let's try.
CloseApplication Element: Maybe I would just try WiX's CloseApplication Element first. I doubt it will work for a service, but this is the most convenient approach I can think of off the top of my head.
Sysinternals PsKill: Mark Russinovich's PsKill would be worth a try. I think his tools are redistributable so you can include them in your setup, and they are always good. You have to invoke it from an elevated, deferred mode custom action - which is alway more involved than using a built-in WiX construct.
Taskkill: There is also the built-in Taskkill - which I have never used. Suggested use with the sc tool.
I want to emphasize that I haven't actually tested these tools for killing services, and I don't have time to do so right now. There could be issues with the sequencing whereby StopServices could be scheduled before the CloseApplication custom action from WiX is scheduled to run. Please check the InstallExecuteSequence using Orca (towards bottom) after compilation to see whether this is the case.

How to detect First run of the application after installation?

I want to catch first run of the application after installation. I know that I can use user settings. for example:
if(Properties.Settings.Default.CheckFirstTime == true)
{
MessageBox.Show("1st run");
Properties.Settings.Default.CheckFirstTime = false;
Properties.Settings.Default.Save();
}
else
{
MessageBox.Show("Later run");
}
But in this case, it is not possible to catch first run when the user uninstalls and reinstalls the application again.
Also, I don't want to use a database, because it may be replaced with a manipulated database.
What's the best way to ensure catching the first run of the application after installation?
Depending on your installation method, it could be worth using the registry for this.
When the program is initially installed, there will be no registry keys to store the properties.
If they are not present, write them into the registry as it's assumed to be the first run.
Using this approach, the keys will not be removed when uninstalling as the program manages them itself rather than allowing the installer to handle it.
The following link describes interacting with the registry in C#.
https://www.codeproject.com/Articles/3389/Read-write-and-delete-from-registry-with-C
If you're using MSI for the installer package, you can configure it to leave behind the registry data when uninstalling, which will work around the issue. This is configured differently depending on the tool you use to create the MSI, but as it's supported by the format, it should be implemented in most installation builders than support generating an MSI.
If using install shield, the following section of the documentation describes how to create and remove registry keys - http://helpnet.flexerasoftware.com/installshield23helplib/helplibrary/IHelpRegistryKeys.htm

Re-enabling Microsoft Word Add-In after Error

We are developing a COM Add-In for Microsoft Word (only local, not for cloud usage). One of our customers had the problem, that each time he started Word, he had to manually activate the Add-In (Word Options > Add-Ins > Go... > tick the checkbox for the corresponding Add-In). I could reproduce this behavior by forcing an error in the Add-In coding which caused Word to crash. When starting Word the next time, I got the following message:
Of course I saw this message several times before. But: back then the consequence of clicking on "Yes" was that the Add-In was disabled. In that case it was sufficient to re-enable it one time (as described above). The next time the Add-In was started, you didn't have to enable it any more.
But now, additionally to disabling the Add-In, there is a registry key created. That key has the name of the Add-In and is located at the following path: HKEY_CURRENT_USER/SOFTWARE/Microsoft/Office/15.0/Word/AddInLoadTimes.
And it seems that this key causes the behavior described at the beginning. Because if I delete the key, start Word, enable the Add-In, close word, set the "LoadBehavior" key in the registry to "3" and then restart word, everything is fine again.
Now my question: is there a user-friendly alternative to enable the Add-In? Since the fewest of our users have administrative privileges, we cannot ask them to change some registry keys in order to fix the problem.
I hope that someone can help me with this.
Best regards
Timo
The path we took to avoid this issue, was to check in the code any static initialize methods / properties (which are invoked when word tries to activates the addin), which potentially could throw exceptions (IO work, REST api requests ... etc) and added to them try / catch blogs with some notification to the user that the activation of the addin failed + logging of the exception.
Side Note: At the time we have struggled the same issue we could not find anything but the registry key which you have mention to resolve this behaviour, but we faced the same security restriction, so this was not an option.
Not knowing much about your add-in, I can think of 2 possibilities:
Since the registry key is in HKCU (which is normally fairly accessible) why not create a 2nd 'helper add-in' that checks for problems with this key and resets it when required?
Otherwise you could use Inno Setup to create a dummy installer that does this for you?
I think this is possible because your target location is HKEY_CURRENT_USER/SOFTWARE/Microsoft/Office/15.0/Word/AddInLoadTimes (i.e. HKCU) which usually can be modified without admin rights: Changing registry without admin rights
Solution seems to go to Options > AddIns, then click GO aside Word Add-ins:
Then select desired one and click ENABLE/DISABLE.

Starting an uninstaller from code

I would like to add an "Uninstall" button to my program that will start the uninstaller to remove the program and then immediately quit. What's the best way to a) determine if there is an uninstaller present, and b) find the correct uninstaller and launch it?
Can I use the registry in a reliable manner? I recall using the registry before to fix some broken installations and was thinking I could iterate over the entries and identify the appropriate one, but I worry that using the registry might not be reliable and/or work on all systems?
Another thought is that I could actually store the uninstall information to the registry during the installation itself, and then use that information to somehow find the correct uninstaller. That seems like it would be the most reliable method, but is there such an identifier that I could store that I could then pass back to Windows Installer?
Since you taged this with windows-installer, I will assume that you are distributing your application using an MSI. That said, you can call msiexec /x {ProductCode} from your application to initial the uninstall. You can obtain the product code by having the installer write to a registry key/value that your application can read or you can hard code it or your UpgradeCode in your application. If you hard code the UpgradeCode you'll have to call into the Windows Installer API to find out the installed ProductCode for that UpgradeCode.

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.

Categories

Resources