Problems with Publisher Policy

bri189a

Senior Contributor
Joined
Sep 11, 2003
Messages
1,004
Location
VA
I'm stuck. I haven't been stuck for a while.

Manually doing a publisher policy in GUI tool works fine, but I'm trying to make a publisher policy assembly. I have a test app that I'm working with for simplicity.

version 1.0.0.0 is deployed to GAC.

my test console app is using version 1.0.0.0 returning a string ("Hello World")

version 1.1.0.0 modifies the string to "Hello Everyone"

Again, when manually doing publisher policy when I run the test program I get "Hello Everyone" and when view the 'fusion?' program (the one used for debugging binding) it shows the policy being found at the machine level and returns the right assembly (1.1.0.0) from the GAC.

Now when I create a config file and create the policy through the al tool (as seen in so many books/blogs/forums) everything compiles. (I've checked my config file for errors and can't find any).

I then use the gacutil tool to put this into the GAC and it shows up there nice and pretty. Oh, and I do have it named policy.1.1.TestAssembly as required (I also did policy.1.0.TestAssembly just in-case there's some weird thing, but I'm pretty sure it should be 1.1). I have also ensure I'm using the same SN key that the main assemblies are signed with (I saw a post where that could be a problem, but I don't see how, but I tried anyway) and have made sure to have the same processor specification when using the al tool (another post where I saw this could be a problem, but again, don't see how).

But now when I run (after remove the manually created policy if I had that in there at the time) I continue to get 'Hello World'. Looking at the fusion utility the framework isn't even looking for a publisher policy.

Now all the examples I've come across are for 1.1 framework; haven't seen any for 2.0 framework expect that which is in a book of mine; but the code is the same there.

I am absolutely stumped to what I'm missing. I can send all my test files if needed later this weekend.

Thanks so much.
 
Signing both versions of the dll (and the publisher policy) with the same key tells .Net that these files are produced by the same company (or individual) and can be substitued for each other. If .Net didn't have a way to verify this then anyone could provide a Dll of the corrects name and substitute it for one of your - this would be a major security risk.

The naming of the publisher policy is very important - get it wrong and it will not work.

If the Original assembly was called TestAssembly.dll and was of version 1.0.0.0 the publisher policy dll would need to be named
Code:
policy.1.0.TestAssembly.dll
the 1.0 in the name means this applies to any TestAssembly dll with a major version number of 1 and a minor of 0 - note this is the version of the original assembly.

Also the command line you are using to build the policy could be incorrect - it would need to be.
Code:
al /out:policy.1.0.TestAssembly.dll /version:1.0.0.0 /keyfile:<path to your keyfile> /linkresource:TestAssembly.config

To deploy this you would need to install the DLL / config file into the GAC on the target machine.
 
Thanks PD,

I've tried both 1.0 and 1.1 originally just for luck but as stated above neither worked.

I am using the same key for both assembly and publisher policy.

I'm calling:
Code:
al /link:TestAssembly.config /out:policy.1.0.TestAssembly.dll /keyf:MyKey.snk

When I've examined the assembly in reflector it has indeed the configuration information:

Code:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
   <runtime>
       <assemblyBinding>
            <dependentAssembly>
                   <assemblyIdentity name="TestAssembly" publicKeyToken="219ef380c9348a38" />
                   <bindingRedirect oldVersion="1.0.0.0"
                          newVersion="1.1.0.0"/>
                   <!-- I've tried without the below too since this is the default -->
                   <publisherPolicy apply="yes" />
            </dependentAssembly>
       </assemblyBinding>
    </runtime>
</configuration>

I can see the assembly in the GAC.

Whatever I'm doing wrong is something very minimal and trivial but is breaking my back.

I can zip up the files tomorrow if you'd like to take a look and send screen shots of the cmd line calls. I'm really stumped here on this, I just know it's something plain as the nose on my face but I just can't seem to figure it out.

Thanks again for your help.

***Oh and the tool I was talking about, from the cmd line it's 'fuslogvw'
 
Last edited:
Changing the policy dll to the right version fixed the fact that it wasn't even looking for the publisher policy...now it is, but it's still returning the original (see log):

Code:
*** Assembly Binder Log Entry  (4/2/2007 @ 9:40:42 AM) ***

The operation was successful.
Bind result: hr = 0x0. The operation completed successfully.

Assembly manager loaded from:  C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorwks.dll
Running under executable  C:\Visual Studio 2005\Projects\Test\GAC Testing\TestGacAssembly\v 1.0.0.0\Test Console App.exe
--- A detailed error log follows. 

=== Pre-bind state information ===
LOG: User = ********
LOG: DisplayName = TestGacAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=97f6fa8856473f86
 (Fully-specified)
LOG: Appbase = file:///C:/Visual Studio 2005/Projects/Test/GAC Testing/TestGacAssembly/v 1.0.0.0/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = Test Console App.exe
Calling assembly : Test Console App, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in default load context.
LOG: No application configuration file found.
LOG: Using machine configuration file from C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\config\machine.config.
LOG: Publisher policy file is found at C:\WINDOWS\assembly\GAC_32\policy.1.0.TestGacAssembly\1.0.0.0__97f6fa8856473f86\policy.1.0.TestGacAssembly.config.
LOG: Post-policy reference: TestGacAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=97f6fa8856473f86
LOG: Found assembly by looking in the GAC.
LOG: Binding succeeds. Returns assembly from C:\WINDOWS\assembly\GAC_32\TestGacAssembly\1.0.0.0__97f6fa8856473f86\TestGacAssembly.dll.
LOG: Assembly is loaded in default load context.

Perhaps I have something wrong in my config file...that's the only thing I can think:

Code:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
	<runtime>
		<assemblyBinding>
			<dependentAssembly>
				<assemblyIdentity name="TestGacAssembly"
					  publicKeyToken="97f6fa8856473f86" />
				<bindingRedirect oldVersion="1.0.0.0" newVersion="1.1.0.0" />
			</dependentAssembly>
		</assemblyBinding>
	</runtime>
</configuration>

If you don't see anything there I'll zip up everything, but at this point it looks like the problem is narrowed down pretty much to the wrong assembly being returned since the log says the policy is found.
 
Last edited:
The problem was that the xml namespace attribute was missing from the assemblyBinding element, it should be xmlns="urn:schemas-microsoft-com:asm.v1"

I would've though that the fuslogvw utility would of picked something like that up and I find it frustrating that it was something so simple. But now I know.

Thanks for you help PD, having the assembly point to 1.0 instead of 1.1 was defintley a part of it too. Also, you're right the public key token was part of it too, I had forgotton to recompile with the right key...but I thought I had updated the post before you had looked at it.
 
One quick final question. If I have versions 2.0.0.0, 2.0.1.0, and 2.0.2.0 out in production and I have bug fixes in 2.0.3.0 is this right:

oldVersion="2.0.0.0-2.0.2.0" newVersion="2.0.3.0"

in order for the first 3 to point to the bug fixes (backward compatibility in mind in the code of coarse).
 
Hi there, Pros!

I've stumbled into needing to be able to do something like this. Within our company, I have to deply an application that will include DLLs that I created.

Your thread above is very closely related, but it does not give me enough information to know what to do.

What are keywords that I could google for this? Is there a good site that steps through how to configure a runtime configuration?

In VS2005 Pro, Intellisence does not pick up <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">. Is this a hidden field, or do I need to add a reference to my project in order to gain access to it?

I really appreciate this forum!
 
Back
Top