1

I am working on Wix and I have to place a new dll (Let's say New.dll) as a part of MSI installation into a specific path in GAC where some other dll already resides.(Let's say Exisiting.dll. Please note this dll exists before installing my MSI). So is there a way I can achieve this? Please note New.dll contains native code and is not .net assembly. Thanks.

Ajn
  • 573
  • 3
  • 8
  • 18
  • Just for the record (a bit old): [**When should I deploy my assemblies into the GAC?**](http://stackoverflow.com/questions/2451123/when-should-i-deploy-my-assemblies-into-the-gac). What kind of file is this anyway? And why is it a **native file** going into the GAC? I assume you will change this to use the /linkresource switch as suggested by Tom. – Stein Åsmul Nov 25 '14 at 03:44

3 Answers3

3

The GAC is only for files in strongly-named assemblies. An assembly is a versioned set of files, one of which has a manifest. Creating multi-file assemblies is easy but most tools neither help create nor respect that an assembly may have multiple files. The basic tool is the assembly linker. See How to: Build a Multifile Assembly.

A native DLL can be made part part of an assembly with the /linkresource switch for the C# compiler. If you want to fiddle with a C# project file, you can override the standard Compile target and Csc task with your own that will pass linkresources.

WiX does not handle multi-file assemblies. You have to create File elements for each file in the assembly. All such Files should be in the same Component. This is an instance where having a single component makes sense when Organizing Applications into Components.

If want want a different behavior (that is, replace one of the files), then you have to create a new version of the assembly/Component. Hopefully, that is how the previous native DLL got into the GAC in the first place.

Tom Blodget
  • 20,260
  • 3
  • 39
  • 72
  • Thanks for the /linresource tip. I knew I've deployed multiple DLL's in the same component to the GAC before but I didn't know what happened at the compile stage before the DLL's made it to me as an installer dev. My read of the question is that the DLL didn't previously need the second DLL. – Christopher Painter Nov 23 '14 at 15:15
  • BTW, there is no general Windows Installer rule of one File per Component. The link you cite is merely one opinion / interpretation of the component rules with a vauge "unless you have a good reason". There are many good reasons. The original guidance was 1 com server per component and is cited here: http://msdn.microsoft.com/en-us/library/aa370561(v=vs.85).aspx and here http://msdn.microsoft.com/en-us/library/aa368269(v=vs.85).aspx – Christopher Painter Nov 23 '14 at 15:19
  • @ChristopherPainter I've revised out the "rule" of one File per Component. Thanks for your feedback. – Tom Blodget Nov 25 '14 at 03:15
1

I've only done this a little bit years ago. I'm 99% certain that the new.dll would be a companion file of the old.dll. In other words, the old.msi has a component with old.dll as the keyfile. The new.dll has to be added as an additional file to this component so that MsiPublishAssemblies / Fusion API can publish them together into the same storage directly.

You may be able to do this in a new.msi provided that you sync up the component ID (GUID) and mark it as a shared component. You would have to rebuild old.dll with the same strong name (and AssemblyVersion) but with a higher AssemblyFileVersion / Win32 File Version.

MSI component rules require newer DLL's to be backwards compatible. This goes double for the GAC. This seems to be a substantial change to old.dll. It might make sense to just rev the AssemblyVersion and define this as a whole new component and install side by side in the GAC.

Christopher Painter
  • 54,556
  • 6
  • 63
  • 100
  • From what I understood of the question, it wasn't clear that he had access to the old.msi. I think he was just looking for a specific file in the GAC (not necessarily one that he placed there with an old.msi). I think he was just looking for that file. – Joe Nov 21 '14 at 20:01
  • The old MSI would be cached in C:\Windows\Installer. Sometimes you have to sleuth to figure out who owns a component and what the metadata is. – Christopher Painter Nov 21 '14 at 20:06
0

The first thing you are going to want to do is search for the file on the system... You can do this with the FileSearch WiX statement:

<Property Id="PROPFILESEARCHEXISTINGDLL" Secure="yes">
  <DirectorySearch Id="EXISTINGDLLFOLDERPATH" Path="[WindowsFolder]\assembly\" Depth="5">
    <FileSearch Name="Existing.dll"/>
  </DirectorySearch>
</Property>

DirectorySearch Reference: http://wixtoolset.org/documentation/manual/v3/xsd/wix/directorysearch.html FileSearch Reference: http://wixtoolset.org/documentation/manual/v3/xsd/wix/filesearch.html

This will put the full path to the file in the PROPFILESEARCHEXISTINGDLL property. From here you can then reference this property when placing the file on disk. (Assuming of course your have permissions to write to that location...)

Joe
  • 335
  • 1
  • 9
  • I see a couple problems with this. If multiple versions of the DLL exists (v1/v2/v3) you are going to get the first one it finds. Another problem is you shouldn't be interacting directly with the assembly directory structure. This is private storage for component based servicing / Fusion API. – Christopher Painter Nov 21 '14 at 19:57
  • There is a version attribute you can use on the FileSearch that will allow you to specify which version you want to find. So that shouldn't be a problem if you need to specify that. However, I agree that directly accessing the assembly is not ideal, but that is what the original inquiry was asking about. – Joe Nov 21 '14 at 20:00
  • The GAC uses AssemblyVersion not AssemblyFileVersion. I bet you I could easily create a scenario where two assemblies are in the GAC with two different strong names but with the same file version. :( – Christopher Painter Nov 21 '14 at 20:02