6. Publisher Policy Files
In the previous examples an application is told to use a new version of a library through the application configuration file. If the library is a shared library it could be used by many applications, so this mechanism would require an administrator to install the new library and then search the hard disk for all the applications that use the library and edit their configuration files. This could involve editing lots of files, and the administrator may not find all of the applications. This problem is solved using publisher policy files.
I have to reiterate that configuration files are associated with process assemblies, however, publisher policy files are associated with libraries but still have the same format as configuration files.
It is worth pointing out at this point that you should use publisher policy files sparingly. The classic situation for a publisher policy is if your library has a security fault and you want to publish a new library that adds no features but fixes the security fault. Your overriding reason to deploy the new version of the library is to ensure that the existing applications will be fixed. Using a publisher policy file means that you do not need to change the existing applications.
A situation where a publisher policy file is not a good idea is when you change the library to add new features. This is likely to lead to an incompatibility nightmare because you will not be able to test that all the old versions of the applications that use the shared library will work with the new version. In this case it is far better to build new versions of the applications against the new version of the library.
| If you have any doubt about using a publisher policy file then the best course of action is to avoid publisher policy files and instead create new versions of the applications that use the new version of the library. |
6.1 Creating a Publisher Policy
In this example you will create version 1.0.0.0 of the
library that you used on previous pages and
the process
that uses the library. The library has a strong name (provided through a
key file) and install the library into the GAC. Then you'll create
another version of the library and install that (and the publisher policy file)
into the GAC so that the new version of the assembly is loaded by the runtime
without having to change the process configuration.
The first thing is to check that lib.cs has a version of 1.0.0.0 and then
compile the library and the process. Next install the library into the GAC and
delete the local copy. Ensure that the application does not have a configuration
file (delete it if there is one). Now run the process and confirm that Fusion
picks up the GAC copy of the library. Now edit the library code so that the
version is 1.1.0.0 and compile just the library. Add this version of
lib.dll to
the GAC and delete the assembly from the local folder.
You will now create the publisher policy file. This is an assembly with a resource file that has binding information. You cannot use the configuration file to create this file. Instead, you must write this file by hand (although there are some short cuts as I'll mention in a moment). You need a text file that has the following information, you will create this file in a moment.
|
<configuration> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="lib" publicKeyToken="ede6789fb0b13219"/> <bindingRedirect oldVersion="1.0.0.0" newVersion="1.1.0.0"/> </dependentAssembly> </assemblyBinding> </runtime> </configuration> |
Note that this has the same format as an application configuration file. Thus, the easiest way of creating this file is to use the
configuration tool to create the process configuration file and then rename the
file. Use the configuration tool to configure the lib library to redirect
version 1.0.0.0 to version 1.1.0.0. (see
Example 3.6) Close the configuration
tool and rename the process configuration file app.exe.config to
lib.config.
Next, you have to make a resource-only assembly with this file. To do this type the following at the command line:
/keyfile:key.snk /linkresource:lib.config
(¶ indicates a new line added for formatting in this document). This needs
more explanation. al.exe is the assembly linker tool. With these switches this
tool will create a library assembly with a strong name and it is important that
the key pair you use for the policy file is the same as the one that you use for
the library. The policy is contained in the configuration file that you have
already created, this must be linked to the policy assembly as a separate file,
it should not be embedded. The policy file is a library assembly with a name in
the form:
Here, <major> and <minor> refer to the versions that are redirected in the
policy file. Since we want to redirect 1.0.0.0 the policy file is named with a
value for <major>.<minor> of 1.0. It is odd that the file has to have a name in
this specific form, but you have no choice, if you don't follow this form Fusion
will not use your policy file. Finally, the policy file itself can be versioned
and Fusion will only use the latest version, here I version the policy file to
1.0.0.0, but note that this has nothing to do with the versions being
redirected.
Finally add policy.1.0.lib.dll to the GAC and delete the local copy of the
assembly (and lib.config) from the local folder. Run the process and confirm
that the new version of the assembly is loaded. Notice that although the application manifest says
that it will use version 1.0.0.0 and there is no process configuration file to
redirect this binding, the application uses version 1.1.0.0. Remove the policy
file (gacutil -u policy.1.0.lib) and run the process. This time the process will
use version 1.0.0.0 from the GAC.
The advantage of a publisher policy file is that an administrator only has to
install the policy file assembly and the new library into the GAC and does not
have to worry about any of the assemblies that use the library. If the library
changes again, all the publisher has to do is create a new version of the policy
file and deploy that file and the new library. Indeed, the publisher may not
even have to deploy the library because the configuration file can contain a
<codeBase>
element to indicate that the code should be downloaded from a web site on the
intranet or internet.
One final point about the last example. When the policy file is installed
into the GAC all of the assembly is installed. An assembly can be made up of
several files, in this case the assembly is two files, the PE file
policy.1.0.lib.dll and the resource file lib.config. Both of these files are
installed into the GAC.
If the application fails to work after an assembly has been updated you can
use the Fix an Application tool (but not for version 3.0/2.0 of the
runtime) described earlier. Note that the SafeMode option
will turn off the use of policy files, it does this by adding the following line
to the <dependentAssembly> node in the application
configuration file:
However, as I've noted earlier, publisher policy files are typically used for security fixes, so the opt out provided by this node allows the user to continue to run with the security problem. Since this is a security issue this opt out is controlled by a CAS permission, which is not enabled by default for partial-trust applications.
Before finishing this section clean up the files you have created. First,
remove the two versions of the library from the GAC either by using the explorer
namespace extension, or if you know that there are no other assemblies called
lib
you can use gacutil -u lib. Finally, if you have not done so
already, remove the policy file from the GAC using
explorer or gacutil -u policy.1.0.lib.
| I hope that you enjoy this tutorial and value the knowledge that you will gain from it. I am always pleased to hear from people who use this tutorial (contact me). If you find this tutorial useful then please also email your comments to mvpga@microsoft.com. |
Errata
If you see an error on this page, please contact me and I will fix the problem.