how to install multiple instances of the same application using msi Installer - c#

I am using visual studio set up project to create my msi Installer.My requirement is to create multiple instances of the application using this same installer without changing version number/product code.
Is there is any way to do it without using Wix/Installshield.

Sorry, if you want to use MSI and install multiple instances, you need instance Transforms (i.e. changing the Product Code)
http://msdn.microsoft.com/en-us/library/aa369528(v=VS.85).aspx
Why don't you want to change the product code using and instance transform?

Windows Installer doesn't support multiple instances with the same Product Code and Upgrade Code. Product Version can remain the same. A different instance is actually considered a different product.
Multiple instances are not supported by Visual Studio setup project files and they are not easy to implement. The general approach is this:
Create a MST transform for each instance. Each transform should use a different Product Code and different component GUIDs.
Write a custom EXE bootstrapper which can apply these transforms to your original MSI.
Optionally find a way to include the transforms and MSI in a single EXE setup file.
Other authoring tools do offer support for multiple instances, but the instances number is usually limited. It all depends on how many transforms you create.

Related

How do I build multiple "targets" or "flavors" of an app using Visual Studio?

I need to build three completely different flavors or targets for my C#/XAML UWP app. Each of them will get placed in the Windows Store using a different name and will have different branding on it. Essentially, I produce three apps that have very similar features but need to be three different apps for business reasons. There is almost zero difference in the source code for these variations.
In Visual Studio, I created three folders and each contains the icons, manifest, certificate files, etc., for the target apps. I use a pre-build event to detect the configuration that I selected for the build and copy the appropriate files to the root of the project. Note that instead of "release" and "debug" builds, I have "release1", "release2", etc. and my configuration folders use matching names.
This all worked great with Visual Studio pre-2019! When I first set things up this way, it worked and was the easiest way I could find.
Visual Studio 2019 validates the element in the project file and my build process no longer works. If I make this empty, something during the build process sets it. I think it gets set when I create app packages for the store and is otherwise untouched.
What is the better way to build multiple targets or flavors of the app? Alternatively, how can I avoid this problem (and it's a problem since that value doesn't actually help me anywhere!)
So far, I have the way I do it now and I've also considered creating separate projects for each flavor with each project using all of the code from a shared project. In fact, I have a shared project that contains code that was once shared with the Windows Phone app that was part of the same solution. I just don't know if that multiple-project solution will work or not and it's hard to justify to the boss the day or two it might take to change the project structure.

Setup Project for two applications that share dependencies

I am using Visual Studio 2008
I have two applications (AppA and AppB) that I what to be installed using one msi-installer.
Both applications have reference AppC.
This is what I did:
I created Setup Project
I created two subfolders inside of Application Folder (AppA and AppB)
I added Project Output for AppA into related subfolder
I added Project Output for AppB into related subfolder
Problem: AppC did not appear in subfolder for AppB. It looks like dependency can only appear once.
Could please tell me how to resolve this?
You should be adding "Primary Output from AppC" specifically to each of the application folders. This version of VS Setup does not appear to detect that the same dependency needs to be included in two application folders.
There are a lot of recorded problems with the VS Setup and Deployment project, especially in regards to dependency detection. Also consider that MS has stopped shipping this project type, and has chosen the ISLE as its replacement (I would recommend using WIX instead - its free and is a more modern toolset when compared to Flexera's offerings).
A merge module is overkill for a single assembly. If you had a package of assemblies that need things like COM exposure or other group behavior things that you dont want to repeat (and possibly get wrong), then a merge module is more appropriate.

How to add some code to c# Installer

I have made an installer which contains the exe and dlls, made in using Visual studio the thing is can i add some code to it?
example when it install i just want to run 3-4 lines of code.
1- Get mac address add to database, with a unique key.
And similarly on uninstall remove the mac address from the database .
Is this possible in this current scenario using the default setup project?
You will need to use a CustomAction for your installer. With this you can run a program, script, write a registry key, or whatever. Here's a simple example using a custom installer class to show a message during the installation (in VB.NET but easily translatable):
Public Overrides Sub Install(ByVal stateSaver As System.Collections.IDictionary)
MyBase.Install(stateSaver)
Dim myInput As String = Me.Context.Parameters.Item("Message")
If myInput Is Nothing Then
myInput = "There was no message specified"
End If
MsgBox(myInput)
End Sub
You would need to follow the steps in the link to fully reproduce the sample.
You could use the .NET installer classes and wire those up from the default setup project. You override some methods and then they get called at install/uninstall time. Here's a tutorial on how to do this.
That said, a lot of people hate these .NET installer classes (and the default setup projects) altogether and implement true Custom Actions using a WIX or InstallShield based project.
Depending on what exactly you want to do and when you want to do it, you also introduce a .NET dependency. For example, if you are checking for .NET being installed, you won't be able to do this from a .NET custom action if the user does not have .NET already installed.
Adding Custom Actions is a bit of a slippery slope. Once people realize you can customize the installer, you'll likely be asked to do more and more. At that point it may make sense to use a more flexible tool (WIX (open source) or InstallShield ($)).

Solution Output Directory

The project that I'm currently working on is being developed by multiple teams where each team is responsible for different part of the project. They all have set up their own C# projects and solutions with configuration settings specific to their own needs. However, now we need to create another, global solution, which will combine and build all projects into the same output directory.
The problem that I have encountered though, is that I have found only one way to make all projects build into the same output directory - I need to modify configurations for all of them. That is what we would like to avoid. We would prefer that all these projects had no knowledge about this "global" solution. Each team must retain possibility to work just with their own sub-solution.
One possible workaround is to create a special configuration for all projects just for this "global" solution, but that could create extra problems since now you have to constantly sync this configuration settings with the regular one, used by that specific team. Last thing we want to do is to spend hours trying to figure out why something doesn't work when building under global solution just because of some check box that developers have checked in their configuration, but forgot to do so in the global configuration.
So, to simplify, we need some sort of output directory setting or post build event that would only be present when building from that global, all-inclusive solution. Is there any way to achieve this without changing something in projects configurations?
Update 1
Some extra details I guess I need to mention:
We need this global solution to be as close as possible to what the end user gets when he installs our application, since we intend to use it for debugging of the entire application when we need to figure out which part of the application isn't working before sending this bug to the team working on that part.
This means that when building under global solution, the output directory hierarchy should be the same as it would be in Program Files after installation, so that if, for example, we have Program Files/MyApplication/Addins folder which contains all the addins developed by different teams, we need the global solution to copy the binaries from addins projects and place them in the output directory accordingly.
The thing is, the team developing an addin doesn't necessary know that it is an addin and that it should be placed in that folder, so they cannot change their relative output directory to be build/bin/Debug/Addins.
The key here is that team is responsible for a deliverable. That deliverable is a collection of binaries. So the "global" solution ... or "product that uses the deliverables from teams" is interested in ensuring that all of the 'current deliverables' work together. That is, that you have a deliverable from the collaborative effort.
So this begs a few questions. Do the team deliver what they consider to be a 'release'. This may be automatic in the build system. If it builds and all tests pass then publish it.
What you are looking for is a team publishing or promoting a release. The source code is how you got there, the binaries are the result. Each team controls what binaries it considers to be a release (this may be automated by the build system).
Not exactly what you asked, but I hope it is the answer that leads to the right questions to give good results.
One very simple way would be to create the solution. Include all the projects and add a project (or more) to handle the global solution build tasks. The projects in the global solution should then have a reference to the projects they need and then let Visual Studio handle how to get the binaries from each project. They will (under normal circumstances) be copied to the output folder of the build project. So the project added specifically for the global build tasks would have a copy of all the referenced projects
Another way would be to create a global MSBuild script that references the rest of the build scripts. Each project is on it's own a MSBuild script
EDIT
From the comments it would seem that there are two categories of projects. One that needs building and one that does not.
For those that need building reference them as projects in the aggregating project for those that do not require building add them either as references or add the dll as resources.
Using the later change the property of the Build action to None and copy to output directory to Copy if newer
In both cases you now have all dll's in the output directory you can then have a post build action on the aggregating project moving the dlls that should be in a specific folder (ie not in the output folder)
Have a look at the practice of Continuous Integration and the usage of a Build Server with scripted builds. This is an indispensable instrument when developing different parts of an application as a team, and your problems are a great illustration of the reason why.
You've not mentioned if you use a Version Control system. I've found in practise that each developer maintains his/hers/their teams configuration and builds locally on there machine, since you don't check *.suo or *.user files most of the personal configuration only affects the individual team member.
On a completely seperate machine check-out the same code from all repositories and compile the project on the build machine (this can be completely automated). This maintains your build servers independance.
Don't worry about it being a "Solution". You can easily build multiple solutions one after the other.
Since the output path is relative (and probably "bin\Debug") it'll get built wherever you check it out to. If you want all the binaries in the same output folder you could tweak the output path on every configuration to match. Something like "....\bin\Debug" (obviously this affects where the projects get built to on the local machines but it might not matter). That way multiple projects would get built the same target output.
You could also include a seperate setup build on the build server which isn't on each developers local machine to package up the final product.

Ensure required install actions for a dll are executed without duplicating code

I have a c# solution with two regular projects and a setup project. One of the regular projects is an executable, while the other is a dll, that I also use in other solutions. The dll project relies on there being a certain event log source, that it can log to, and since the program is intended to be run by users that are not allowed to create log sources, this source must be created at installation.
I have done this by creating an installer class for my executable project, creating the log source in the installer, and included that installer in my custom actions in the setup project. This works, but now I have to create a similar installer for every other project, that also uses that dll.
The best solution would be, if I could write an installer for the dll, and then choose the dll for the custom actions in the setup project. This way I would only have to state the log creation requirement once. However, I am not able to select the dll project output for the custom actions in the setup project.
Another good solution would be, if I could somehow specify that the installer for the executable should be transitive, such that it would also perform install actions for any projects that the executable project depended on, but I don't know how to specify that requirement.
So what can I do to avoid duplicating installation code between different projects?
You should be able to add an installer class to your DLL then register the DLL for execution of custom actions in a setup project. If you have tried this and encountered problems, could you please be more specific about which version of Visual Studio and which type of setup project you are using?
I just have a MyApplication.Installation assembly where I put a custom action that creates the event source. All my setup projects reference this assembly and invoke its custom action.
How about this? You create a simple batch file or a powershell script to create the log file that you want to create.You could make an installer for the dll file(or even the entire solution it doesn't matter.) You can then invoke the batch file that you just wrote from the installer.[Refer here] . This way, you are not duplicating the creation logic for a dependent files/resources; and you can use the same batch file for multiple setup projects basically(provided they use the same resources.)
I hope this answers your question.
One step further, what environment are your clients on? Are they still on Win XP(SP2 or before)? If that is the case, you have to do something similar to what you already have in mind right now. However, if that is not the case, if your clients are on Win 7, You could use nuget to publish your bins(Refer here). I admit that this is still looked at as a source code sharing solution. But I believe that the approach can be extended to publishing binaries too.

Categories