Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setup Project does not replace assembly files

  1. I have a Windows Application project (A.exe) that calls another project Class Library (B.dll).

  2. A.exe has a button (myButton) that calls the method Method1 from B.dll.

  3. To install the application I created a Setup project ASetup.vdproj, whose Primary Output is project A.

  4. After compiling the setup, the installation runs without any problems, when A.exe starts and I click myButton, the aplication gives no error.

  5. Then I changed B.dll and added a new method Method2.

  6. myButton is now calling Method2 from B.dll instead of Method1.

  7. I increased the version of A.exe and increment the version of ASetup.vdproj, but do not increase the version of B.dll.

  8. After installing the application I noticed I had two installations of A.exe in Control Panel -> Add / Remove Programmes.

  9. When running A.exe and click myButton I obtain an error, "The method Method2 was not found in B.dll", it means that the setup does not replace B.dll during installation.

  10. I ran the uninstall and I noticed that the files were not removed from disk.

My question is:

Why doesn’t the second installation update B.dll? If the version of B.dll is incremented, B.dll will be replaced during the installation, but the problem is that my current project has many external assemblies, which is difficult to control if they have been modified or not. Basically, what I want is that all assembly files are replaced in each installation.

I await feedback from all of you. Thank you for all the attention.

like image 644
LR-TI Avatar asked Nov 03 '10 12:11

LR-TI


Video Answer


2 Answers

The 2 entries in Add/Remove Programs tells me that you changed the ProductCode property but didn't have a valid row in the Upgrade Table to properly define a Major Upgrade. MSI treats this as 2 different products that happen to get installed to the same directory. When you uninstall one of the two products the files remain until you uninstall the other product.

The DLL not being overwritten suggests to me that you didn't change the AssemblyFileVersion attribute from one build to another. The first install copies in 1.0.0.0 and the second install says "1.0.0.0 is already there, nothing to do here" and skips it.

like image 57
Christopher Painter Avatar answered Nov 07 '22 03:11

Christopher Painter


Besides the problem mentioned by @Christopher Painter, there is most likely another problem: The setup project created with Visual Studio (2008) will only replace files if the version number has been incremented. The obvious solution would be to just increment all version numbers; however, this might not always be what you want.

The behavior of the .msi file is basically determined by the moment when the RemoveExistingProducts action is executed. Installers created with VS 2008 schedule this action after the new product has been installed. Modified assemblies whose version has not been incremented therefore don't get replaced. Some more details about the update behavior are described in this thread:

RemovePreviousVersions=True but previous version is not removed from the target machine

To change the behavior, you can patch the created .msi file so that the RemoveExistingProducts action is executed before the new product gets installed (this actually has been the behavior if you created the setup with Visual Studio 2005). Patching can e.g. be done using a small VBScript that runs as a post-built step:

Dim objInstaller
Dim objDatabase
Dim objView
Dim objResult

Dim strPathMsi 

If WScript.Arguments.Count <> 1 Then
    WScript.Echo "Usage: cscript fixRemovePreviousVersions.vbs <path to MSI>"
    WScript.Quit -1
End If

strPathMsi = WScript.Arguments(0)

Set objInstaller = CreateObject("WindowsInstaller.Installer")
Set objDatabase = objInstaller.OpenDatabase(strPathMsi, 1)
Set objView = objDatabase.OpenView("UPDATE InstallExecuteSequence SET Sequence=1450 WHERE Action='RemoveExistingProducts'")

WScript.Echo "Patching install sequence: UPDATE InstallExecuteSequence SET Sequence=1450 WHERE Action='RemoveExistingProducts'"
objView.Execute
objDatabase.Commit

WScript.Quit 0
like image 34
Dirk Vollmar Avatar answered Nov 07 '22 02:11

Dirk Vollmar