Running Custom Action before installation - Visual studio installer - c#

I am working on a project where I need to run an action before installing a new version, this action is to check if there a product already installed and to uninstall it. I tried to add custom action in visual studio installer but I can't add a DLL file from the outside of the project so the action won't run before the installation. My application is a Microsoft office addin so that why I used visual installer because it is very simply and straightforward. Is there any another solution ?
Note : Changing product code and set DetectNewerVersion to true didn't work,
now I have two same product in Program and Features

Here you can find InstallExecuteSequence numbers. You just should put yours custom action in right place, for example you can set Sequence=750 - it will be run before CostInitialize.
Also here's video tutorial how to use orca.exe. It's amazing app to check and debug your msi. In your case you can check is your CustomAction in right place or you should change number, or even your custom action isn't working.
And about "I tried to add custom action in visual studio installer but I can't add a DLL file from the outside of the project so the action won't run before the installation". I can't get what do you mean, but seems that you can't add dll with custom actions. Here's tutorial about it.

Related

How to embed the version information in the executable file name when building C# application in Visual Studio?

This question is a complement for the post How to change the output name of an executable built by Visual Studio.
After reading this post I did the following:
Firstly, I followed the answer for this post and I could define the executable file name successfully.
Now, I would like to know if instead of only define the name as "Demo.exe" as mentioned in the example post above, it would be possible to embed the version defined in AssemblyInformationalVersionAttribute or in AssemblyVersionAttribute in the built file, resulting in something like "Demo_v1.0.0.0.exe"?
I'm developing my application in C# WinForms, using Visual Studio Express 2017.
Why would you want to change the name of the executable? Whenever you try building a Setup for your application, you need to change the Setup to include the new file. And when you install an update, your Setup needs to know all versions of your executable in order to delete the old version. That's just not what you want to do.
If you want to keep all versions of the software for yourself, come up with a different solution, e.g. moving the executable into a folder which has the version number.
That said, I have done this for Setups, so customers can download different versions of the Setup. I did that using a commercial tool called Visual Build, but there are other build automation tools available. So, my answer is: set up a continuous integration / continuous delivery pipeline (CI/CD) and automate the step there, not in Visual Studio.
From the project properties, you can add Post build event command line to rename your exe
pseudo
Maybe you can create another console renamer.exe which reads version defined in AssemblyInformationalVersionAttribute or in AssemblyVersionAttribute of your app and renames it and then call that renamer.exe from Post build event command line
write a powershell script to rename the newly built exe and call that script from Post build event command line

C# How to install Windows Service as part of application installation

I have created an installer that takes the primary output from a selection of sub-projects, one of the sub-projects that make up my application is a Windows Service. This service needs to be installed as part of the main application.
So far I have tried adding an installer to the Service project, publishing this separately and installing the resultant Setup.exe as a custom action for the project installer but have not had any success with this method. I would install the thing from the command line, however I'd need to then package in the Visual Studio CMD Tool to get access to the installutil command.
My question is, can I install a Windows Service from a "Visual Studio Installer - Setup Project" as part of a larger project and if so how? As the process has eluded me thus-far.
I suppose I could try having the custom action trigger a script that executes the ServiceInstaller as part of the process, so I'll be trying that.
Thanks in advance
Since VS2013 does not contain the old (VS2010) Visual Studio installer project, I have these suggestions:
Use WiX installer: https://wix.codeplex.com
There is even a service installer template (not tested):
https://visualstudiogallery.msdn.microsoft.com/7f35c8ce-1763-4340-b720-ab2d359009c5
Use VS 2013 install extension
There were many complaints that MS abandoned the old setup project, so they brought it back as an extension:
http://blogs.msdn.com/b/visualstudio/archive/2014/04/17/visual-studio-installer-projects-extension.aspx
I have not yet tested this, but as I understand it, it will bring back the old capabilities of the internal VS setup project type.
I have written some Windows services using VS2010 setup project and even wrote a step-by-step instruction how to do this. Some steps are not self-explanatory, so I use this myself as a guide for service projects.
I did some first tests with WiX, which seems a good solution, however I had not yet used that for service installation.
Another link regarding this topic:
https://superuser.com/questions/727643/installing-a-windows-service-without-visual-studios-installutil-exe
I plan to check my step-by-step instructions regarding service installation with VS2013 soon and probably compare this to WiX, if you are interested, please tell me, I can make this publicly available.
Here are my step-by-step instructions for creating a Windows service.
(you can find this also on http://www.rsprog.de/samplewindowsservice)
File => New => Project...
Visual C# => Windows Desktop => Windows Service
Name: SampleService
"Create directory for solution" checked
In Solution Explorer, select Service1.cs, right-click => Rename
Rename file to SampleService.cs
Select Yes for "... Would you also like to perform a rename ..."
SampleService.cs should be shown in Design View now
Click in the background of the designer view
right-click => Add Installer
(serviceProcessInstaller1 and serviceInstaller1 have been added)
open SampleService.cs in design view
in Properties, set ServiceName to SampleService
open ProjectInstaller.cs in Design View
Click serviceInstaller1
In the Properties window, set the ServiceName property to SampleService.
Set the DisplayName property to Sample Service or something else
(This will be shown later in services console as service name)
Here you can also optionlly set StartType from Manual to Automatic
click serviceProcessInstaller1
Edit Account:
Here you can change if the service will run under a technical account (User)
or e.g. as LocalSystem
If you set it as User, a popup during setup will allow user / password to be set
At Solution right-click => Add => New Project...
Other Project Types => Visual Studio Installer => Setup Project
Name: SampleServiceSetup
Select SampleServiceSetup project, right-click => Add => Project Output...
As Project "SampleService => Primary output" should be already selected,
as Configuration "(Active)" should be already selected.
Press OK
Select SampleServiceSetup project, in properties view:
change InstallAllUsers to True
change ProductName to SampleService (remove Setup at the end)
change Title to SampleService (remove Setup at the end)
By default, the target platform of the setup project is x86.
You can change it here to x64 (TargetPlatform)
Right-click the setup project in Solution Explorer => View => Custom Actions
In the Custom Actions view, right-click the Custom Actions node => Add Custom Action...
Double-click the Application Folder in the list to open it,
select Primary Output from SampleService (Active), and click OK.
("Primary output from SampleService (Active)" was added to the four nodes)
Select SampleServiceSetup project, right-click => View => User Interface
Start => Installation Folder => Properties => InstallAllUsersVisible: change to False
Build solution
Windows Installer has a mutex that prevents multiple installations from running at the same time. For this reason one installer can't call another installer. There's an exception to this but the resulting pattern can't be installed silently and is not a best practice.
You need to research the concepts of a bootstrapper / chainer. InstallShield has one they call suite installers and Windows Installer XML (WiX) has one called Burn.
Also Visual Studio Installer projects are well known by Windows Installer experts for their low quality. I'd consider rewriting that installer using another tool such WiX. I maintain an open source project called Industrial Strength Windows Installer XML (IsWiX - CodePlex) that provides project templates (scaffolding) and graphical designers that make it possible to author an MSI that installs a service without writing a single line of XML by hand. The resulting project is then built by WiX to create an MSI.

Is it possible to embed a script into MSI installer package?

I am trying to create an MSI installer/uninstaller for my Windows project, consisting of a service, a couple of user-mode exes/dlls and some data files. I was able to use Visual Studio 2010 to compile an MSI package using its Setup Project. It works fine for installation, but uninstallation requires some additional steps before files are actually removed along with the registry settings.
So I was wondering, is there any way I can run a script (C#, or WSH JScript) before removing files/registry settings?
Yes, you can add as well scripts (VBS or JScript) to an MSI as C# or C++ custom actions in compiled MSI enabled Dlls, you can call .exe files, etc. There is a table called CustomAction and the Custom actions can be sequenced with the sequence tables, the most important are InstallExecuteSequence and InstallUISequence.
Working with custom actions is not so an easy task I think. If it is possible for you to ask experts, I would consider it.
Most times, when you want to add a custom action for uninstalling resources, there is maybe something wrong with your MSI.
4 of 5 custom actions one wants to add, are not necessary but can be replaced with correct MSI table entries.
Generally, I don't recommend using Visual Studio installer, because it gives you not very much control, and it is easy to make things wrong, especially for upgrading and more complicated task.
But if you still want to add a custom action here is some basic idea:
For example for starting a VB script you can add a custom action of type 38. Choose a name in the "Action" column, let the "Source" columns empty, and type the VB script code in the "Target" column:
E.g. with something like that you have an VB "interface" to the MSI properties like the newly invented "MYDIR_EXISTS" here.
on Error Resume Next
set filobj = Createobject( "Scripting.FileSystemObject" )
If filobj.FolderExists("C:\MyDir") Then Session.Property("MYDIR_EXISTS") = "True"
...
If you work with Visual Studio Installer you could consider adding the custom actions with a transform afterwards. Again this needs some MSI knowledge.
Me, personally, I would not work with script files for distributed setups, only if the setup is an infrastructural one for the same company. But it is a starting point.
Calling an compiled .exe with Custom Action type 34 or 50 would be an alternative.

Steps to extract values from "USER INTERFACE" custom window textbox into my code, WHILE CREATING A SET UP PROJECT?

HI, I have created a setUp project for my windows application.
My Solution has 2 Projects(1st is the Windows application and 2nd project is the setUp project that I added)I want to add custom welcome screens during installtion, so I did the following actions.
1) Created a setUp project and added it to solution having a windows application.
2) Added the primary output of the only windows application (within the solution) to the setUp project.
3) Right click on SetUp project -> VIEW -> USER INTERFACES; then added a textboxA.
4) Right click on SetUp project -> CUSTOM ACTIONS; This has 4 options Install, UnInstall,Commit,RollBack.
5) Added a new class to the Windows Application project, inherited "Installer" class to this new class. Overridded "Install" method of this class.
6)Right Click on INSTALL option -> ADD CUSTOM ACTION; and the primary output of the windows application was already added, so I didnt add anything.
HERE THE WINDOWS APPLICATION PROJECT HAS BOTH APPLICATION CODE AND ALSO THE OVERRIDDED Install METHOD.
bUT WHEN i TRY TO INSTALL THIS ITS SHOWING SOME ERROR CODE 2869.
Kindly help me with the procedure to extract values from custom textBox into my overridden Install method.
Frankly speaking I have no idea if it is possible to add anything custom to VS setup project.
I had a similar issue and soon lost my patience and migrated to WiX. It integrates with VS very well (you can add WiX XML schema to have your code coloured and Intelisense enabled). With Wix you can do far more custom things than in VS Setup.
Moreover WiX has a great community, loads of examples and last but not least, you can adjust user interface as the VS Setup projects look REALLY ugly.

Windows Service not appearing in services list after install

I've created a windows service in C#, using Visual Studio 2008
I pretty much followed this:
http://www.codeproject.com/KB/dotnet/simplewindowsservice.aspx
I created a setup project, as instructed to in the article, and ran it...
it installs my service to C:\Program Files\Product etc.... however, it does not then appear in the services list..
What am I missing?
The most important part of the article you linked, is here
To add a custom action to the setup project
1.In Solution Explorer, right-click the setup project, point to View, then
choose Custom Actions. The Custom
Actions editor appears.
2.In the Custom Actions editor, right-click the Custom Actions node
and choose Add Custom Action. The
Select Item in Project dialog box
appears.
3.Double-click the application folder in the list box to open it, select
primary output from MyNewService
(Active), and click OK. The primary
output is added to all four nodes of
the custom actions � Install, Commit,
Rollback, and Uninstall.
4.Build the setup project.
If you skip these steps, your setup project will build and copy your files to the correct directory; however, they will not register your binary as a service without these steps.
I should also note that this works for older versions of Visual Studio that had/have the built-in Setup/Deployment project template. The newer versions of Visual Studio have different setup/deployment projects (some requiring third party software.)
I'd recommend looking into WiX Toolset and check here for WiX Installation of Windows Services.
I got owned in the face by this one, so I'm putting it here just in case anyone else runs into it.
If you followed the instructions in the guides but are still having issues installing, ensure your Installer class is public. Internal won't work.
I had this same issue and then I realized that I never set the parent for the ServiceInstaller.
Double-click on your project installer. The designer should show a Service Installer and Process Installer. When you click on either and view the properties you should note the Parent attribute which must both be set to the class name of the Project Installer.
Or, if you do it in code, make sure you set:
serviceInstaller.Parent = this;
and
serviceProcessInstaller.Parent = this;
When installing services, I would highly recommend using NSSM, which worked well for me for all my WinService needs. It can install any executable (even if .bat, .cmd) as a service, and guarantees your service is always up and running.
To use this tool:
Download from here
And follow the instructions here
Then check the services list, it should be there, up, and running.
Follow these instructions, they worked for me. For the setup specifically, that part is near the bottom of the article.
MSDN: Walkthrough: Creating a Windows Service
In Visual Studio 2013 I ran into the same problem using InstallShield template for service application. But it works like charm when using Setup Project template https://visualstudiogallery.msdn.microsoft.com/9abe329c-9bba-44a1-be59-0fbf6151054d
so download Setup Project template close your Studio, run this installation and start your Studio, this will work.
Dunn.
Here is a good tutorial from tgeek001 from CodeProject.com that helped me. It includes several things I didn't see in the posts above:
1. Event handler code to stop the service before uninstalling it
2. Specific conditions and properties in the Custom Actions code to set in order to prevent failures (these fixed the Error 1001 that I experienced while following the instructions in the accepted answer above)
3. Win Service property "Remove Previous Version" dropdown set to true
http://www.codeproject.com/Tips/575177/Window-Service-Deployment-using-VS
The following is from the tutorial for Custom Actions Settings (case matters):
Install, set the Condition property to the following: "NOT (Installed or PREVIOUSVERSIONSINSTALLED)"
Uninstall, set the Condition property to: "NOT UPGRADINGPRODUCTCODE"
Commit: set "Custom Action Data" field to: /OldProductCode="[PREVIOUSVERSIONSINSTALLED]"
Lastly, in the WinService project, make sure to set the dropdown "Remove Previous Versions" to true.
cheers
I discovered that your installer class much be in the same project as the Service. The installer cannot exist in a library project referenced by the Service.
remember to check the name you've given your service before you search. (right click-> properties->check the service name

Categories