Installing a shared assembly to the GAC with COM interop - installation

Specifically, I am using Wise Installation Studio to install several shared .NET 2.0 assemblies into the GAC. These are being used by some legacy COM application files as well as other application assemblies.
I have the flag for "Generate COM interop registry keys for .NET assembly" set.
Reference counting appears to be working for removing the actual assembly from the GAC, but the COM registration information is getting removed with the first uninstall via ARP.
I am wondering if there is some work around for this, if I would be better off installing the assembly to Common Files, or if there are any other suggestions out there?

How I could read on the http://www.ssw.com.au/ssw/standards/wisesetup/WiseStandards.aspx page using of "Generate COM interop registry keys for .NET assembly" allow you just add a set of registry keys to MSI. As in all Windows Installer Setups it is important to define to which MSI component a registry key or a file belong. If you make these registry keys as a part of the same components as the file and the assembly, the keys will be removed always together with the assembly. If multiple setups use the same component GUID, then only if you uninstall the last setup used the component, the component will be uninstalled.

Related

Visual Studio - Register for COM interop manually on a second PC?

In Visual Studio (C#), ticking 'Register for COM interop' updates the Windows environment such that my Visual Studio project, its dependent Visual Studio projects (in same solution) & dependent DLL files are all available for another COM-consuming application on the same machine. This COM-consuming application works with no issue.
If I want the same COM objects to be available to a consuming application on another machine, what must I do?
I assume I still build with the same flag set (so that the DLL files have COM content)? I assume I must register the COM DLL file (e.g. regasm) - Unfortunately this doesn't work - do I register every DLL file that I am constructing & every DLL file library they reference?
Please make no assumptions about my COM knowledge.
You don't quite provide enough information to answer with certainty, but there are enough hints to guess at what you are doing.
When your client app asks for the COM object, the .NET runtime is invoked and it locates the COM-exposing assembly DLL from the information stored by RegAsm (specifically by the /codebase parameter). But after that, it's all .NET assembly loading rules - including the loading of dependencies.
If your COM assembly has dependencies, the dependent assemblies must be locatable from the client process. It doesn't matter whether the dependencies are in the same folder as the COM DLL - the one loading those dependencies is the process, not your COM DLL. The .NET runtime uses a process called Fusion to decide where to look for .NET assemblies.
You have two practical choices:
Put the COM DLL, its dependencies and the client EXE all in the same folder. This works if there is only one client, and you control the client (so, don't do this if the client is IIS, for example). It's the simplest solution.
Give all the .NET components a strong name and deploy them to the GAC1. You still have to run RegAsm; but don't use the /codebase argument.
It is also possible to customize the Fusion rules by giving the client app a manifest with the proper entries, but that's too much of a hassle. The other options are more practical.
If this doesn't describe your problem, then I would use a combination of SysInternals' (now Microsoft's) Process Monitor and the .NET fusion log functionality to look into where the process is seeking the different DLLs.
1Technically you don't have to put the main COM DLL in the GAC, but it makes no sense to use /codebase for the COM DLL when you have to deal with GAC anyway. At that point you might as well put them all in the GAC

How to install .NET4.0, .NET4.5, x86, AnyCPU DLLs side by side in Visual Studio Reference Manager

Related to this question here, I am trying to create an installer which installs DLLs on the target user's PC and makes them available to the Visual Studio Reference Manager (Project > Add References)
I have figured out that to make an assembly visible to the .NET4.0 Reference Manager, I need to add this Registry Key
Key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx\MyAsm
Value: <Directory on target PC of .NET4.0 assembly>
And for .NET4.5, I need this key
Key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.5.50709\AssemblyFoldersEx\MyAsm
Value: <Directory on target PC of .NET4.5 assembly>
However I now have a problem. When I go to Add-References, I see something like this
So my question is, what is the best practice here for distributing multiple DLLs compiled to different .NET Frameworks (e.g. .NET4.0, .NET4.0 Client Profile, .NET4.5) and targeting different machines (x86, x64, AnyCPU) so that only one version shows up in Add-References OR So that versions can be differentiated in the Add-References dialog?
In general the best practice is to not mess with the user's registry. Do note that a programmer won't expect to find a non-Microsoft assembly in the Framework list so might never even look there. The added convenience is fairly minor, the user can simply use the Browse button to pick the reference assembly you copied onto his machine. Albeit that you do need to provide him with a hint on where to look. Not much of a problem when you use the standard c:\program files\company\product naming strategy.
Avoiding the duplicate is otherwise easy. If your assembly is compatible with .NET 4.0 then only modify the v4.0.30319 key. A project that targets 4.5 will include 4.0 assemblies in the list. If you require 4.5 for some reason then modify the v4.5.50709 key.

visual studio/installshield set up project

i have implemented successfully custom actions in my visual studio setup project to encrypt app.config file and also to capture user input through textboxes. However my project has 3rd party dll references which I want to merge. I have done merging using redgate smart assembly and after that when I build the setup project using the merged obfuscated assembly there is an error during installation( unable to get installer type for assembly error 1001).
Can you show me how to encrypt app.config and capture user input via custom dialog using Installshield
InstallerClass Custom Actions ( InstallUtil ) are very fragile and should never be used. The problem you are having is most likely that your custom action assembly has a reference to an assembly that can no longer be found on the disk since it's been merged into another assembly.
This problem would happen with InstallUtil CA's whether it's being called by a Visual Studio Setup Project or an InstallShield Basic MSI project because the problem isn't in MSI, it's in your CA.
I would reccomend you look at WiX Deployment Tools Framework (DTF). It's a far cleaner way of implementing managed code custom actions so that the CA and all of it's dependencies appears as a single native DLL to the Windows Installer. At runtime the native stub extracts all the files, runs your .NET code and marshals all of the MSI API calls between the two sides for you.
It's very clean and it can be used in Setup Projects, WiX, InstallShield and other MSI authoring tools because the output is a simple Win32 DLL with exported stdcall functions. ( Msi Type 1 Custom Action Spec )

visual studio copy dll references to output folder

I am trying to extend a certain application. I am using a DLL which comes bundled with that application to extend its functionality. I am using visual studio 2010 express edition. I added a reference to the dll library. In the reference properties the option "Copy local" is disabled.(greyed out) why is that? I want visual studio to copy the dll to my release folder. If this can't be done is there another way to bundle the dll?
Your comment to Hans answer indicates this is a COM assembly and that you are using Visual Studio 2010.
This means the assembly reference was likely added with the "Embed Interop Types" setting set to true. This has the effect of linking the COM assembly into your binary removing the need to deploy it altogether. The following link has a more detailed explanation
http://msdn.microsoft.com/en-us/library/dd409610.aspx
If you do want to deploy it though then will need to do the following
Click on the reference in the references tab
Hit F4 to bring up the properties grid
Set "Embed Interop Types" to False (this will ungray Copy Local)
Set "Copy Local" to true
It depends on what kind of DLL it is. If it is a COM server then Copy Local is off when you have a PIA registered for that COM server. If it is a regular .NET assembly then it will be off when it is registered in the GAC.
Fix the issue by, respectively, using regasm /u to unregister the PIA or gacutil /u to remove it from the GAC. Do note that you might not want to do this if this DLL requires that its installer is executed on the target machine. Which is likely. Talk to the component vendor or author to find out what you should do.

Automatically strong naming COM Interop wrappers

I have a C# project in Visual Studio 2005 that is referencing a few COM libraries. When I build it errors like this are thrown:
Referenced assembly 'assemblyName' does not have a strong name.
Now, I used to reference COM assemblies in Visual Studio 2003, and it would automatically sign the Interop wrappers. All I had to do was set the setting 'Wrapper Assembly Key File'.
I tried finding a similar setting in Visual Studio 2005, but I couldn't find any. So I was wondering if there's any equivalent way of strong naming COM Interops in Visual Studio 2005 and getting rid of the above error.
It looks like it was already answered in "Where is the Wrapper Assembly Key File setting in VS 2008?" question.
Instead of using Visual Studio you could use Tlbimp.exe and
Aximp.exe to generate the Interops. Tlbimp.exe has options for signing.
I have used them to be generate an Interop file for each different version of the same COM component in my application. The COM components are vendor supplied COM components used for accessing data points in mass spectrometry files and the COM interface change from time to time as new versions of the vendor software is released. The application can then decide at runtime which Interop to use in order to match what version is installed on the computer where the application is installed.
The BAT file I use for generating the Interops is online.

Resources