Force Reboot from Custom Action in Msi in C# - c#

How can we prompt for a computer restart after install from within a C# custom action?
We are using VS 2005's setup project for our setup, and we need to programmatically decide to prompt for a restart (so it will not happen on every install, just on some).
UPDATE: We're looking for something that is already built into the MSI custom action system first. If that doesn't exist, we can resort to restarting the PC ourselves somehow, but would like to avoid that.
UPDATE: We see where you can set REBOOT=Force when edited the Msi in Orca, can you modify these tables from a C# custom action at runtime? We could set this to restart every time, but that might make our setup annoying (it will only need to restart on rare occasions).
UPDATE: We tried setting:
savedState["REBOOT"] = "Force";
From within the Install() method of our custom action, but no luck. It doesn't seem like the IDictionary, savedState really does anything.
Also tried:
Context.Parameters["REBOOT"] = "Force";
But I think this collection is just the command line arguments passed to the custom action.
UPDATE: Is there a way to edit our MSI with Orca to make this trick work? Maybe schedule a reboot on a condition of some file existing? We have not found how to set MSI properties from a C# custom action.
UPDATE: We tried hooking into AppDomain.ProcessExit and AppDomain.DomainUnload and starting a new thread and calling Process.GetCurrentProcess().WaitForExit() and none of those events will fire from within a C# custom action...

You need to add or call the MSI custom action ScheduleReboot http://msdn.microsoft.com/en-us/library/aa371527(VS.85).aspx in your InstallExecuteSequence, . You can do this by using the MSI function MsiDoAction, http://msdn.microsoft.com/en-us/library/aa370090(VS.85).aspx inside a custom action. Please note that the custom action that schedules this must be an immediate custom action, not a deferred custom action. This means you will probably need to schedule it after InstallFinalize. You could also add it to the InstallExecuteSequence with a condition on a public property that your custom action sets.

When I've had to do this before we used a Win32 API function from user32.dll, I think this was it: ExitWindowsEx()

LanceSc has given you the answer. You need to run ScheduleReboot, and the best way to do so is to insert it in the InstallExecuteSequence conditioned by your own custom property that you set inside your custom action.
As you mention, Wix is the way to go for future flexibility. Wix now also includes DTF (Deployment Tools Foundation) which is a rich set of .NET class libraries that wrap the entire Windows API. You can use this to easily access MSI databases from C# or to write C# custom actions. I can provide more info on this if desirable.

As it seems, the only way for us to solve this is to either:
A) Modify the MSI with orca to make the setup restart for every install
B) Redo the setup project with WiX or Install Shield
Thanks for the help guys.

Related

C#: Create custom msi file

I need to create a custom installer to deploy a specific program. But there are a few checks and balances that needs take place during intallation, and even though I have an Advanced Installer license, it just struggles to do everything I need.
I'm looking for a way to create my own msi file using c#. Running the msi file it will then start a win forms wizard, which in turn will do a number of items, including copying files to the host PC.
I'm not sure how I can "include" my set of files into a single msi file. How to you "copy" files into an msi and how can you read again from it?
I can't even give a proper sample code of what I've tried as I don't know where to start.
This just feels like it should be a duplicate question, but I can't find it.
I work at Advanced Installer, since you said you already have a license let's help you get a return of investment on that ;)
First of all, I seriously doubt you need to reinvent the wheel and write your own code that installs/copies files on the machine. This is a basic action performed by all installer authoring tools, and even though it seems simple when you first think about it, it is not. You don't want to write code that handles rollbacks (if your install fails), reference counts (if a file is shared somehow), repair/self-healing operations (if somehow a DLL gets corrupted or missing post-install), or cover other standard Windows Installer scenarios.
Since you didn't explain with full details what you are trying to do I will give you some short example on how to do each of the steps you mentioned:
Adding files in a setup package - this is a link to a tutorial created with a free edition, but the same steps apply for Professional and Enterprise editions.
Searching files on a disk and retrieving values from them. - for this, you need to use the built-in support from Search page. There you can either simply search for a file and return its path or search for an element inside an INI or XML file and return its value inside a property.
Windows Installer properties are the equivalent of variables in your code. You can use them all over the installer project to pass/get/validate values.
Designing custom dialogs. Most professional installer authoring tools have support to build custom dialogs. The previous link is for a tutorial on how you can do that with Advanced Installer.
During the UI stages, you can include and custom C# code to perform additional validations or data retrieval operations and pass that to or from the installer using properties. if you need it.
The custom installer dialogs support is available starting with the Enterprise edition. The Professional and Free editions include the standard dialogs, but with no options to customize them.
Another way to interact with users is to design an UI experience inside your application that is visible only when the users launch the application for the first time. So, this is not a part of your installer. It will be code that you write inside your application and you can provide a first-launch experience similar to what you see when you install Office for example. If you can give me more details on what you want to do/capture in those custom dialogs, I will try to recommend you the best approach.

Apply Visual Studio Quick Actions and Refactorings across entire C# solution

I am trying to cleanup/refactor a legacy C# solution and am therefore exploring options how certain refactorings or quick actions could be applied for the entire solution.
For example, Visual Studio 2017 offers 'Replace xxx and xxx with property' and 'Use auto-property' actions, which I can apply via the lightbulb icon for individual classes and methods/properties.
How could I apply these to the entire application or semi-automatically iterate all occurrences (300+) and apply these?
I am open for all options - command line, powershell, VBA, even VISX-development.
I do not want to re-develop the refactoring itself and I don't think that a simple find&replace will do either.
When the quick action window is visible, you can apply the selected fix to the single instance, or across the entire document/project/solution:
If you apply each identified fix across your solution (or project) then you should only need to process each suggestion once, as the first one you change will apply to all further instances.
Alternatively, you could use the dotnet Format tool to apply a set of specific formatting rules to your project via the command line, although this depends upon you having an editorConfig file with your rules defined.
Have a look at the EditorConfig. What you're looking for is the Language Conventions topic and you can flag an action as silent (synonym for refactoring in v15.8):
# $slnRoot\.editorconfig
[*.cs]
dotnet_style_prefer_auto_properties = true:silent
Then when you run across that action in your code, you can apply the quick action to your entire solution, file, project, etc.
Note: there have been some bugs with EditorConfig in VS2017. I've had to close the solution and restart the IDE to get changes to take sometimes.

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.

c# Visual Studio Project Installer retrieve data from Textbox

I'm trying to retrieve data from a Textbox in Visual Studio Project Installer but I simply keep failing. I have no idea how to retrieve data from, let's say the EDITA2 field and it seems the internet has no answers so far.
The project I'm talking about is a windows service you install with the mentioned installer. In the installer you can configure the service. I want to get data like server IPs and computer names and I want to use this data later in the running service. Talking of service, is there a possibility to automatically start the service after installation?
Summing up, i want to write data from the installer to a text file and to start a batch file after the installation process is completet. Can you help me please?
Thanks in advance for an answer.
I think you are searching for Custom Actions
https://msdn.microsoft.com/library/d9k65z2d(v=vs.100).aspx
https://msdn.microsoft.com/en-us/library/9cdb5eda(v=vs.100).aspx
To setup the StartType of a Service you require a ServiceInstaller
Maybe this helps
http://www.docstorus.com/viewer.aspx?code=7c7ccc28-6503-4779-877e-f350faab6741
This is the documentation for the Textboxes user interface dialog:
https://msdn.microsoft.com/en-us/library/e04k6f53(v=vs.100).aspx
The identifier EDITA1 (and others) is a property name that you can use later in (for example) custom actions. Without knowing exactly what kind of custom action you might be thinking of it's hard to say how you use it. In general, specifying it as a parameter to the custom action as [EDITA1] will cause it to be resolved to its actual value. But if you just want to store the values in the registry you'd create a registry item with the value [EDITA1].
To start the service in Visual Studio setups that install services with installer classes you'd need to overwrite the Install method, calling base.Install() and then adding code to start the service. Similarly at uninstall or upgrade time you can override the Uninstall method and stop the service before calling base.Uninstall().
These posts have some Textboxes examples:
Overriding "Textboxes" dialog fields from the command line in MSI installer (Visual Studio 2010 Web Setup)
Setup Project: user enters a value then store it in a text file or database
Visual Studio setups are not very useful with services and UI. There is no way to validate what the user enters at the time it is entered - if you validate it with a custom action it will be at the end of the install and the entire install will fail and roll back. Windows Installer has built-in support to start/stop/delete/install services but VS setups don't use it. If this is something you do regularly it might be useful to consider another tool, and that might have a learning curve but the resulting MSI will be more reliable and easier to use.

How to delete a file after installation is over in c#?

I am developing a windows application in .NET Framework using c#. I want to run two exe files at the time of installation of my application, one after the other, in a specific order.
I know that I can run an exe at the time of installation, by using the custom action, but I don't know how to run it in a specific order.
I am new to c#, so a detailed walk through is prefered.
using Custom action you can perform the same, you need to use "Commit" option of custom action for this

Categories

Resources