.Net Publisher Policy: Both Assemblies required to be in the GAC? - c#

I have created a publisher policy assembly following the post How to: Create a Publisher Policy. The policy redirects assemblies from the version 1.0.0.0 to the version 2.0.0.0.
This does work for me as long as the old assembly (v1.0.0.0) is located on the server (in the GAC). Is it possible to remove the old assembly version from the server?
The configuration I used:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Assembly.Name"
publicKeyToken="d24d3f23b4455982"
culture="neutral" />
<bindingRedirect oldVersion="1.0.0.0"
newVersion="2.0.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

Shame on me. I did a mess with the assembly versions. So the answer is: Yes, it works without the legacy assembly.

Related

Load assembly from a path without copying it to bin folder

I have a simple c# application and I would like to reference an assembly from C:\..\..myassembly.dll without copying the thing to bin folder.
I there a way to change how is assembly being referenced/loaded?
Edit: the assembly is not in gac
Actually it is possible during runtime by using <codeBase> tag in your configuration:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="MyAssembly2" culture="neutral" publicKeyToken="307041694a995978"/>
<codeBase version="1.0.1524.23149" href="FILE://C:/Myassemblies/MyAssembly2.dll"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
You can refer to the MSDN to get more specific info. The downside of this solution is that you have to manually specify assembly version.
Multiple solutions to your problem.
To avoid copying library to output folder set Copy Local to false by selecting .dll property.
Option 1:
Include below section in your configuration file and let allow runtime to load from location you specified.
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="MyAssembly" publicKeyToken="2d65620afb84f19d" />
<codeBase version="1.0.0.0" href="C:\..\..myassembly.dll" />
</dependentAssembly>
</assemblyBinding>
</runtime>
Option 2:
Well known option, use reflection to load your assembly.
Assembly.Load(#"C:\..\..myassembly.dll")
Hope this helps !

How to use GAC assembly with specific version in C# app

I have 2 GAC assemblies called AAA (version 1.0.0.0 and version 2.0.0.0). The application currently is using version 1 (reference added by Browse-for-assembly, path is hardcoded to this file), but I want to use version 2.
To do it smoothly, I added some code to app.config:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="AAA"
publicKeyToken="dd8b40231cb0196b"
culture="en-us" />
<!-- Assembly versions can be redirected in app,
publisher policy, or machine configuration files. -->
<bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
But application still is using version 1.0.0.0 of assembly, why?
culture="en-us" />
That's wrong, assemblies that contain code are always neutral. Only satellite assemblies have culture. Or in other words, your bindingRedirect doesn't match any of the assemblies that the app is asking for. So has no effect. Be sure to delete the assembly from the project's bin\Debug directory so you can diagnose mistakes like this. The Fuslogvw.exe utility is also very handy, log all binds.
Fix:
culture="neutral" />

Runtime loading of private assemblies in a subdirectory

I have been trying to load a private assembly which is located in a subdirectory under the application base directory. I have an assembly named Sparrow.dll which is located under plugins directory (which is under application base dir also). Whenever I call Assembly.Load("Sparrow") I get a System.IO.FileNotFoundException.
I used app.exe.config with tag and it worked with a strong named version of the same assembly with the line below;
Assembly assem = Assembly.Load("Sparrow");
However, it does not work when I changed the assembly in to a weak assembly.
The content of the config file is below;
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly name="Sparrow, Culture=neutral, PublicKeyToken=xxxxxx">
<codeBase version="1.0.1.1" href="plugins/Sparrow.dll" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
I read many things, but I am not sure whether using tag for locating weak assemblies is a good practice or not.
You can use the probing element for that purpose:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="plugins" />
</assemblyBinding>
</runtime>
</configuration>
That element means that the plugins subfolder will be searched for assemblies.
Note however, that only directories that are on a descendent path of the application directory can be specified in that way.
The configuration file in your question has a mistake. According to documentation, the XML configuration should look like:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Sparrow"
publicKeyToken="null"
culture="neutral" />
<codeBase version="1.0.1.1" href="plugins/Sparrow.dll" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
However, I think that using the probing element would be a better choice in your case.

Conflict of version for NLog

I am trying to compile my project named MyAssembly, and when including other assembly named ExternalAssembly that also references NLog, I get the following error :
Assembly ExternalAssembly, Version=1.0.0.0 uses NLog, Version=2.1.0.0 which has a higher version than referenced assembly NLog, Version=2.0.0.0
I went to my app config and added the following entry:
<?xml version="1.0"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="NLog" publicKeyToken="5120E14C03D0593C" culture="neutral"/>
<bindingRedirect oldVersion="2.0.0.0" newVersion="2.1.0.0"/>
</dependentAssembly>
...
But I still get the same error.
Any ideas about why it is not working, and how to fix this error?
To solve this issue I had to upgrade the NLog reference of my project to match the one of the third party (2.1.0.0).

Another assembly referencing the old dll

I have 2 assemblies lets call them A and B. I've assigned strong names to them and now the problem arises that assembly B is looking for the old version of assembly A.
**EDIT2: If I delete AssemblyB the problem persists so it might just be VS2008 looking for the old version? Also via fusionlog I see the following warning: wrn application configuration file binding redirects disallowed. Does this have anything to do with it? **
I get multiple errors of the same kind, here's one snippet:
You must add a reference to assembly 'AssemblyA, Version=1.2.4737.25316, Culture=neutral, PublicKeyToken=null'.
The strong named AssemblyA inside the project shows these properties:
Inside app.config I've placed this piece of code:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="AssemblyA" culture="neutral"
publicKeyToken="a22e30ac6a0edfc0"/>
<bindingRedirect oldVersion="1.2.4737.25316" newVersion="1.3.0.19440"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
But this does not work. I have access to the source of both assemblies.
EDIT: If I delete the strong named and add the old (weak named) dll to the project it will give an error asking about the strong named version
You must add a reference to assembly 'AssemblyA, Version=1.3.0.19440, Culture=neutral, PublicKeyToken=a22e30ac6a0edfc0'.
What's happening here?
Some DLL's still referred to the old (weak named) version of other DLL's. Luckily the assemblies came with the source so I had to recompile everything including a key.
After that another error came up along the lines of "The located assembly's manifest definition does not match the assembly reference"
To fix this I added the following in the app.config.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<publisherPolicy apply="no" />
<assemblyIdentity name="Assemblyname" culture="neutral" publicKeyToken="3a5628535d42dbed"/>
<bindingRedirect oldVersion="1.3.0.15233" newVersion="1.3.0.40647" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

Categories