Changing version at Setup Project dynamically? - c#

I need to change version of Setup project in VS dynamically, from generated class? Can i do that?

All VS projects are basically text files, so theoretically you can do what you want, but maybe not from inside VS.
You will want to change the ProductVersion property of the project. In the text file, look for a line containing something like the following:
"ProductVersion" = "8:1.0.1001"
The "1.0.1001" part should be whatever your current version is. The 8: seems to be a type identifier; I would guess 8 means a string.
When you update the ProductVersion, you should also update the ProductCode. This is simply a GUID, so you can simply generate and ToString() a new random GUID. DO NOT TOUCH the UpgradeCode if you want the installer to find previous versions of your program and remove them.
This is all perfectly possible to do with a simple .NET program. Integrating it into a VS build is trickier, because the install project is not an MSBuild script like the others, so you don't have access to the kinds of custom build logic tools you have in MSBuild from directly inside the install project. You could set up your primary project's MSBuild script to include a build task to update the install project version when built, possibly. You could also set up a post-build action.

Here's an example of a script file you can use to increment that version number calling it from a PreBuild event of a setup project. (http://www.codeproject.com/Articles/22256/NewSetupVersion-for-MSI-Projects)
Read the issue raised by amthog in the comments though. The fact that the project is not reloaded after this script runs, but prior to the build can cause headaches. I have a post build event that is now failing due to changes made "externally" (by this script) which haven't been reloaded at the time the post build event runs.
If that doesn't concern you, this script seems to work well.

Related

How to share major and minor version of the main application with its DLLs?

I have a large WinForms application (C# , .NET 4.5.2) with several own DLLs (plug-ins for the application), all as different Projects in the same Solution. I use Visual Studio 2015 Community.
The main app and all the DLLs have their version number assigned in their respective AssemblyInfo.cs files like this:
[assembly: AssemblyVersion("1.0.*")]
Now I want to up the version of the application to, say, 2.0.. I also want all the DLLs to be 2.0.. The way I currently have it I would need to go into each DLL and manually change the version to 2.0.*.
Is there a way to inherit the "2.0" part from the application so that, in future, I would only have to change major and minor version number in one place?
I did some searching but was not able to find the answer.
Update:
What I was hoping is that I can replace
[assembly: AssemblyVersion("1.0.*")]
with something like:
[assembly: AssemblyVersion(some_string + ".*")]
where "some_string" is a string containing the major and minor version number. But I wouldn't know where I can define that string, or if this is possible at all.
Add a link to the original AssemblyInfo.cs file to the other project via the project solution explorer:
Right click on the project -> Add -> Existing item -> Add as link (from the dropdown menu)
Now, once you change the original AssemblyInfo.cs, any changes will be applied to all the projects to which the file was added as a link.
Edit:
To avoid duplicating attributes that should be unique per assembly (such as the GUID), make two files, one for the shared attributes like version number, and another for assembly specific attributes. No one forces you to put everything into the same file. It does not even have to be named AssemblyInfo.cs
In Visual Studio of you can set Pre build events.
Right click the project and select properties
Go to Build Events
then in the first box for pre-build event you can launch a simple script like this
if $(ConfigurationName) == Release C:\AssemblyChanger.exe $(ProjectDir)
This sample script above will Launch "AssemblyChanger.exe" located on your c drive and it will pass the current Visual Studio project folder as an argument. from there it is very simple to read the Assembly.cs on the specific project that manage the "version" and edit the one in the path that was pass as argument. Plus this will only be called if you are in Release mode (that "if" can be removed without a problem).
You can create a simple console application to do that.
That script can be set in all DLL pre build event so when they compile they call the script and they will get their assembly edited before the compiler create the DLL.

Why can't MSBuild resolve assembly version changes

My problem seems to be relatively simple. I have a c# solution created in VS2010 with several projects with project references configured appropriately. I use MSBuild on our build machine which works fine, building in the correct order incrementally to be efficient. However, if I extend the interface (adding a public property etc.) and increment the AssemblyVersion of one of the projects that others depend on, it seems that MSBuild is unable to refresh the caching on down stream dependents and throws an error that it cannot find the previous version of the changed dll. Interestingly if I run the build again immediately afterwards, it tells me that the output hasn't changed and completes the build without error but I have no longer any confidence that it has done the right thing.
There is a file 'ResolveAssemblyReference.cache' that seems to hold the old reference and if I delete this from the obj/x86/Release folder before each build I never receive any errors but don't know if the output has/should have been rebuilt.
I would like to understand why MSBuild struggles with this and why on a second build it seems to report that the first build did actually work and that the targets are up to date.
Until I understand what is going on I am going to have to always force a rebuild of the entire solution to be certain I have compatible files.
Incidentally if I build in VS2010 I never seem to suffer this as I suspect it updates that cache appropriately each build.
Update:
I have found that my use of 'OutDir' on the command line for MSBuild seems to be to blame. If I remove this then the referencing seems to be resolved appropriately. However now I do not have my output copied to where I need it for deployment...

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.

How to configure build numbers in Visual Studio to enable dll comparison

I am building a C# solution in Visual Studio 2008 that has several projects and project dependencies. I am looking for a way to change dll version numbers ONLY when the code that builds the project changes. I currently use Beyond Compare to compare my locally built version to the production file system. The goal is to ONLY deploy updated dlls. I am using autoincrementing version numbers, and each time you open visual studio and do a build, all dll version numbers increment. The same goes for a full solution rebuild and when a different developer does a build and tries to deploy. Is there a way that i can configure Visual Studio to ONLY increment the build number based on changed file contents? Is there an add in that will do this?It seems a binary comparison of these files will also fail because of the different version numbers within the dlls. Does anyone know of a better tool compare only the contents of dlls?Thanks in advance.
One option is to move to a continuous integration solution such as Cruise Control .Net this allows builds to be triggered on check in to a source control system.
Regarding assembly versioning what I usually do is create a single SolutionVersion.cs (to replace the default assembly version cs) that is linked to each project (use the add existing item but change the button to add as link)
Then I use a NAnt or MSBuild task to take the cruise control build label number and overwrite the SolutionVersion.cs verison numbers before the solution gets built
That way I can take an assembly and trace it back to the code via CruiseControl build version (even better I usually get CC.net to label the source with the same number in source control)
Its not quite what you are asking, but I found this helpful in dealing with large solutions: Versioning Controlled Build. According to its doc it detects the changes you are interested in :
"If there is a file with a more recent timestamp (which means that the source code has been modified after the previous version change), the project will be marked for version update."
The recommended, supportable solution would be for your project to NOT auto-increment the build number using the visual studio way. Then you would need to manually, or write a pre-build script/ MS Build Task to do the increment.
There is an interesting sample in this codeproject article which you should check it out... it involves a prebuild task which does the task of updating the build number based on the day of the year
I would suggest that you look into options that your revision control system provides to embed revision information into source files. I've had enough problems with auto-increment in the past that I promised myself never again. These days I prefer something a little more concrete than a build number though and embed unique identifiers into every product of the build system.
I describe my own system in Embedding mercurial revision information in Visual Studio c# projects automatically. While my solution probably isn't right for you, there were other interesting options suggested in response to my question, so some of the solutions I rejected may, nevertheless, be useful to you, even if you have to adapt them to whatever VCS you use.

How to keep the installer's version number in sync with the installed assemblies' version numbers?

In my current project, I'm producing weekly releases. I've been using the technique described in this post to keep the version numbers of all of the assemblies in my project in sync. (I don't presently have any good reason to track the assemblies' version numbers separately, though I'm sure that day will eventually come.)
When I push out a release, I build a new version of the installer. Unlike all of the assemblies, which can get their version numbers from a shared SolutionInfo.cs file, the version number of the installer isn't, as best I can tell, an assembly property. So my release process includes manually advancing the version number in the setup project.
Or, I should say, usually includes doing that. I'd like to turn that into something I can't screw up. I'm finding the documentation of setup and deployment projects to be surprisingly opaque (it was quite a bit harder to find out how to make it possible for the MSI to uninstall properly if the user installed it to a non-default path, which is a pretty freaking common use case to be undocumented) and have no idea if it's even possible to do this.
Any ideas?
Edit:
Just to clarify, this is a Visual Studio setup and deployment project I'm talking about.
CodeProject has a script to set the version number of an MSI file, which you could run in the pre-built step of the setup project. You find it here:
http://www.codeproject.com/KB/install/NewSetupVersion.aspx
More Details
Be aware that with Windows Installer things are a bit more complicated. MSI files (as the one that you create using a VS Setup and Deployment project) not only have a version number but also a product code which is a GUID value. This product code is used by Windows Installer to uniquely identify your product e.g. in Control Panel -> Add Or Remove programs where you can decide to uninstall or repair a product.
However, when changing you MSI version number, this product code must also be changed in a number of cases. MSI technology is poorly documented but you can find some recommendations when to also change the product code on the following MSDN page: http://msdn.microsoft.com/en-us/library/aa367850(VS.85).aspx.
In my projects I always generate a new product code for every new version. The script on CodeProject will also change the product code for you.
And one more thing: Windows Installer only checks the first three places of the version number afaik, anything in the forth place will be ignored, i.e. 2.3.0.1234 is considered equal to 2.3.0.5678. (ProductVersion)
(There is a related article on CodeProject which might also be interesting to you: http://www.codeproject.com/KB/install/VersionVDProj.aspx)
Its going to depend on the installer toolkit you are using.
We use TFS Team Build and WiX v3. I have a custom build task that increments the build number in Team build (5.0.0.X for example), then this version number is pushed to the common AssemblyInfo.cs AssemblyFileVersion field. It is also passed by MSBuild to our solutions/projects as a property which is then passed into WiX and used to update the installer version as well.
We probably will need to do better with the assembly versioning someday as well, but right now this has been working pretty well for us.
I use a workaround for VS2010 Setup projects (.MSI + setup.exe). Open the .vdproj in Notepad and edit the ProductVersion assignment value (3.2.1 in the example below). Save the file and launch VS2010 by double-clicking on the .vdproj file.
"Product"
{
"Name" = "8:Microsoft Visual Studio"
"ProductName" = "..."
...
"ProductVersion" = "8:3.2.1"
"Manufacturer" = "..."
...
}

Categories