Use Orca to remove assembly from installer - orca

I have a Visual Studio setup project that is built using Team Build. It has an extremely annoying habit of adding a duplicate assembly to the installer for an assembly that is already included in the installer as a project output. I am constantly having to check that the duplicate is excluded from the setup project but frequently the output from Team Build still includes the duplicate assembly. If this occurs, the install will fail with a message that it cannot write the duplicate to disk, because it has already just written the correct one and hasn't yet released the file handle.
I assume it is possible with Orca to remove the duplicate assembly from the installer which I'm contemplating doing in order to maintain a reasonable accord with the guy who has to run the installer. What do I need to do to remove an assembly from the installer?

Assemblies are usually added in two tables: File and MsiAssembly. So you can try removing the appropriate rows from these tables.
However, the best solution would be to determine why the assembly is added twice and prevent that action. Modifying the MSI after build it treating the symptoms, not the cause.

Related

How to express a file dependency using WiX

I have a couple of MSI files installing different applications. All these packages share the same underlying runtime which basically is a set of DLLs. This runtime is pulled in each of the installers as a merge module. Installing a couple of these packages works just fine, always the latest version of the runtime stays on the system and when the last package is removed everything is removed from the system.
Now I had to split one of the DLLs into 2 and added a new component to the runtime installing the new DLL. This new DLL is linked with other libs of the runtime. Now assume the following scenario:
install an old package with the merge module for the runtime without the new DLL
install a new different package with a newer version of the merge module for the runtime. Now there are 2 packages on the system
remove the new package again
Now the old package is broken because:
the new component for the new DLL had a reference count of one as the old package didn't have it and therefore gets removed
the other runtime DLLs stay on the system because they are still referenced by the older package. However as they are new they are already linked with the new DLL that is now no longer present
So my question is:
Is there either a way to explicitly state in the WiX code that file A depends on file B so that it stays on the system until all references have been uninstalled?
or is there a way to explicitly downgrade the dependees in a way the dependency does not longer exists?
Am I doing something fundamentally wrong?
What I did try on a clean machine was to follow Stein Åsmul suggestion like this:
<Component Id='OldLibsNowDependingOnNewLib' Guid='C8DCD2AB-CBE5-4853-9B25-9D6FE1F678DD'>
<File Id='LibOne' Name='LibOne.dll' Source='$(var.SourceDir)/LibOne.dll' />
<File Id='LibTwo' Name='LibTwo.dll' Source='$(var.SourceDir)/LibTwo.dll' />
</Component>
<Component Id='NewLibComponent' Guid='CD2DB93D-1952-4788-A537-CE5FFDE5F0C8' Shared='yes'>
<File Id='LibNew' Name='LibNew.dll' Source='$(var.SourceDir)/LibNew.dll' />
</Component>
However unfortunately this doesn't change the behaviour.
UPDATE: Looking in the SDK again, I see the flag msidbComponentAttributesShared for components. This
looks promising for the problem you describe. Please try to enable
this flag and recompile the version 2 of your setup (unless it is
live).
Enable the Shared flag for the component in question (last part):
<Component Feature="Product" Shared="yes">
This seems to be for patch support, but maybe it will work for your case too. From the MSI SDK:
"If a component is marked with this attribute value in at least one package installed on the system, the installer treats the component as marked in all packages. If a package that shares the marked component is uninstalled, Windows Installer 4.5 can continue to share the highest version of the component on the system, even if that highest version was installed by the package that is being uninstalled."
I think the above should work, but don't have time to test right now. Leaving the below for review.
Short Answer: Use WiX's Burn (setup chainer) to install in sequence the application setup and a new, separate runtime setup that can be handled
independently of your application setup versions.
Prerequisite Setup: Interesting case. This is why I like to split prerequisites into its own MSI package and deploy it via a Burn Bundle Bootstrapper. Burn is WiX's bootstrapper / downloader / chainer - essentially a way to run several setups in sequence - in a few different formats such as MSI, EXE, MSU, MSP. When doing this - putting the runtime in its own MSI - there are no entanglements and you get good decoupling of your runtime and application-specific files. In other words: you can update the runtime files on its own - with their own MSI. The files will even have a reference count of 1 meaning you can easily uninstall them all (not if you install via a merge module that also can be included in other packages - more below).
Merge Modules - Semi-Static Linking?: In a weird way merge modules are sort of semi-static linking. The whole merge module is a version - a binary bundle (think COM) - but its installation behavior is one of "higher version wins" only. Hence a single newer MSI with the newest merge module in it will update the shared files for all applications that use them. Uninstalling will then do what you see: preserve the files that were originally installed by older setups.
Options: One "solution" in your case could be to re-compile the older setup with the newer merge module and then reistall, which I understand you don't like. I don't like it either. I guess it is no solution at all. Some other suggestions:
Permanent component: You can set the hosting component for the new file to be permanent on the system. This is very easy, but also quite silly and not always very desirable. Uninstall will then not remove the file at all.
Prerequisite: This is my favorite option mentioned above. You compile a prerequisite MSI setup that installs the runtime components. This MSI can deliver updates to itself without affecting the main application. This is the primary benefit I am after: Cohesion & Coupling benefits.
Merge Modules: I would avoid merge modules altogether, but it is common to merge the same merge module into the prerequisite setup - if you have a merge module already.
In most cases merging a merge module is fine since you then install the prerequisite and then you can install and uninstall application versions at will without affecting the runtime since a different product (prerequisite MSI) installed the runtime - and that setup should stay behind and not be uninstalled.
If the merge module does not work and brings along the conflict that you already had, maybe try to combine with the msidbComponentAttributesShared "solution" mentioned above. Not tested by me so far. Always risky to suggest things like this, but it is "best effort".
WiX Include Files: I prefer to use WiX include files which allows me to pull in new files without re-authoring a whole merge module in binary format (think C++ include files as opposed to a merge module's COM-style binary reuse).
Side-By-Side: Many people prefer to install prerequisites side-by-side so that several versions of the runtime can co-exist. This may or may not involve the GAC. Switching runtime versions would then be a manifest-manipulation task. Generally somewhat confusing, but doable. You can use both merge modules and separate MSI files to deploy such runtimes - as described above. I would definitely use a prerequisite MSI.
I can't think of more right now, but I know I have forgotten something important this time. Let me persist what I have for now in case it sparks ideas for you.
Cumbersome Prerequisite Setups: Note that prerequisite MSI files are not so bad for corporate deployment since deployment systems will allow one to define relationships between MSI files and to set up deployment chains. For home users you can easily wrap everything in a large setup.exe.
Nonsense Options: Options that don't make sense would be to roll the new file into both setup versions. No gain, lots of overhead. Some people like to copy new files locally to the main installation folder. Does not work since the files it is linked to are likely elsewhere (runtime location). Static linking wouldn't be relevant in this case I think. Only as a last resort to solve a live problem I guess. Setting the SharedDllRefCounter flag will not affect MSI reference counting, it is for legacy reference counting (non-MSI setups), though tweaking this manually is an emergency "solution". The last resort people end up with is typically to abandon the runtime installation and install everything to the same installation folder. Then you have to always recompile everything for every release - which is what you want to avoid?
Some Links:
WiX (Windows Installer Xml), Create universal variables
Pre-Processor constructs, features, Burn Bundles and beyond

Referencing WiX extension in same solution as wixproj

I wrote up a quick WiX preprocessor extension to grab some product version information from a file we keep in our root folder.
I'd like to keep this extension in the same solution as our WiX setup project, because it's easier to maintain. But the problem is that when testing, we use a Debug configuration, and when releasing a build, we switch to Release. This means that I have two extensions to deal with.
How would I tell WiX to grab one depending on the current configuration?
I've been looking at the reference paths in the WiX project's properties, and added "..\MyWiXExtensions\bin\$(Configuration)\" as a folder, hoping that it would pick up the MSBuild property, but that doesn't seem to work.
I've also looked at the build events. I could copy the output dll to my setup project's folder, but wouldn't that break references if I clean my solution?
I'm using WiX 3.7 and Visual Studio 2012.
I ended up using a post-build event on my extension that would copy the output to my wixproj's folder.
I just have to build my wixproj separately from the rest of the solution to prevent file locking issues when overwriting the dll. If file locking does come up, I just have to close VS and reopen the solution.
As a side note, referencing the project itself instead of the dll could be a nice feature to have in Votive.

Build one MSI from separate components

We have a product that has three parts:
Application files (exe and dll files)
Help files
SSRS reports
All three things get installed together with the same installer built using WIX. In our company, each component is developed by separate teams and with different deadlines. We would like to break our MSI into three parts so that when one part becomes stable its installer part is also stable and is not rebuilt from scratch when the other parts are updated.
I've looked at merge modules and CAB files but I think that's the wrong direction. Is there anything in the WIX toolset that can help me achieve my aims?
(I have read the question Building MSI Installer and Separaete Installation Files but believe this question is a bit different.)
Thanks for your help.
WiX library (*.wixlib) seems to be the best approach to distribute the components in your case.
I would organize this process like this:
each team has a separate WiX installation project (Setup Library Project), which compiles into *.wixlib file instead of the MSI (or MSM) package
each project is evolved as the component is developed, and the output is shared to other teams
an integration build gathers all wixlib libraries and links (light.exe) them all together into a single MSI package
Hence, you'll always have a final installation package with the latest builds of components, which is what continuous integration is all about.
As far as I understand, you won't distribute the components separately, and for the end user it is still a solid installation package. Hence, merge modules could be an overhead. I suspect (but not sure) that light.exe performs some extra validation when linking the libraries, comparing to merging tool.
Well, merge modules are a solution. You could have two merge modules containing the help files ans SSRS reports, and add them in the main package that will contain only the application files. This can increase build time if nothing is changing in the two merge modules but you will still have a long build time for the main package changes.
Another option is to create separate packages for each of the components and bundle them into a single one using Burn. I would recommend using the merge modules, its more cleaner and easy to manage.

JNA try to Access native DLL and get module not found error, Dependencies are missing

I have Visual Studio 2010 installed and have a project I got from someone else which I can build successfully without any errors. I get a Wrapper.dll,
which I would like to access using JNA.
I am using Win7 64-bit.
But I get the error: java.lang.UnsatisfiedLinkError: Unable to load library 'Wrapper': The specified module could not be found.
Wrapper.dll of course is in the correct folder and it is a 32-bit dll and my Java program also uses a JRE with 32-bit, so this is not the cause of the error.
I used DependencyWalker to check whether *.dlls are missing:
MSVCP80.DLL
MSVCR80.DLL
GPSVC.DLL
IESHIMS.DLL
And yes there are some missing.
Can I conclude that the error is related with that these DLLs are missing?
But why does Visual Studio compile correctly then and does not throw an error?
How to solve this in order to access these functions in Wrapper.dll?
I also read that downloading dll's might not be the right thing to do!
(I know that Wrapper.dll relies on another dll or sourcecode which was built in Visual Studio 2005, if that is of interest.)
EDIT:
I found out, that Wrapper.dll relies on three other dlls which probably were built on MSVS2005. These require the above mentioned DLL's (checked with dependencywalker) and I guess therefore Wrapper.dll also links them.
So what do I actually do to get rid of these old dll's?
Would I need to build the other three DLLs with VS2010 or
is this a problem which always will appear, meaning, that you need to copy paste old DLLs in order to use the precompiled Libraries which are dependent on those.
Is there a way, that the program would run on any other system as well without copy pasting these DLL's?
All required DLLs must be available to the system for loading. If you define jna.library.path, that is where JNA will look for the initially loaded DLL, as well as any dependent DLLs. In addition, java.library.path (which is essentially PATH) will be searched for dependent DLLs.
MSVS often uses paths in addition to PATH when building, debugging, and running code within that environment.
Solutions:
a) remove dependencies you don't really need; this may include telling MSVS to build your DLL differently
b) include non-system DLLs next to your custom DLL (or include their location in PATH/java.library.path)
EDIT
a) you can include the offending DLLs in the same directory as yours. this is fairly low impact on the target system, but if they are DLLs that are expected to be on any system, you shouldn't have to do so. It's preferable to adjust java.library.path so that all system DLLs are accessible.
b) you can recompile your dependent DLLs and be more careful about backward compatibility and explicit linkage. Depending on features used by the DLLs, though, you may not be able to remove the dependencies.
MSVC[RP]80.DLL are C and C++ runtimes, respectively; you may or may not be able to link against a previous version.
IESHIMS.DLL is part of IE and should be on the system, but likely in a path inaccessible to your program.
GPSVC.DLL has to do with group security policy, so it should be available on the system (modulo whenever the DLL was introduced).

MsBuild: Changing References from ProjectReference to Reference

In our environment, we have two in-house frameworks and a separate website. During development, the references to the in-house frameworks tend to be set tp project references. However, once we move to release, the in-house frameworks are installed into the GAC as they are used for multiple instances of the website on each server. All of the ProjectReferences are changed, by hand, to References and the website assemblies and website are re-compiled and deployed.
I am attempting to automate this process. What is the best way to handle these issues? I have started to learn MsBuild in the attempt to accomplish this, but am totally confused. Any pointers and/or suggestions on how to proceed?
As far as I am aware there shouldn't be any need to change from using project references to file references simply because the assembly is registered in the GAC - as long as the referenced project is strongly typed at the point that it is built, the reference should still be valid.
Clarification:
There is no fundamental difference between a GAC reference and a file reference - if you have a reference to a strongly named assembly, and that assembly is placed in the GAC then the end application will load that assembly from the GAC.
See this link for more information on how the runtime locates referenced assemblies:
http://msdn.microsoft.com/en-us/library/yx7xezcf(VS.71).aspx
FYI - I believe it is recommended that you don't reference assemblies which are in physically in the GAC, and that you instead reference the strongly named assembly before it is placed in the GAC (not to be confused with whether or not the assembly should be installed to the GAC on the end-user machine)
If you leave the project references in, MSBUILD will copy all the project references as DLLs into the target website's bin directory, even though you've installed these DLLs into the GAC, which I assume is why you want to change this at the release level--so that space can be saved.
I also assume that you are intending to do this at the Release Branch only, and not at the development branch of your source control. Because if you are doing this at all branches of source control, then doing by hand is actually the best and fastest way of doing this for a one-time change.
To do this in MSBUILD, you will need to create a custom task that can modify the project file. The project file is an XML file, so you could use XPath as your custom task in MSBUILD. In the project file, you will find tags for "" to your referenced projects. You will need to change those to "" tags instead. Use existing examples of the tag in your project to see how it should look
Sorry I don't have sample code for this--doing it this way will be a bit of an undertaking, as there will be a number of things to take into consideration, and it might end up not being feasible.