我在技术支持方面的背景可能导致我在这篇文章中提供了太多信息,导致没有人有兴趣阅读它,但恕我直言,更多信息总比更少信息好。
我缺少关于程序集绑定和重定向的一些非常基本和基本的东西。我正在尝试创建一个策略 DLL,以将针对我的程序集的旧版本编译的应用程序重定向到最新版本。我所做的一切似乎都不起作用。我在下面概述了我采取的步骤。我没有使用 Visual Studio,而只是使用了 .NET Framework 和 Windows SDK 中包含的命令行工具。谁能告诉我为什么在第十一步中,当我运行针对我的程序集的 v1.0.0 版本编译的应用程序时,该应用程序没有重定向到在 GAC 中注册的 v2.0.0 程序集?
当您按照我的操作进行操作时,您经常需要注意我在其中执行命令的目录。
如果您愿意指出我应该阅读的 TFM,我会对 RTFM 的答案感到非常满意。
提前致谢, 注册
第一步:创建一个密钥对来强命名我的程序集。
c:\stackexchangetest> sn -k stackTest.snk
Microsoft (R) .NET Framework Strong Name Utility Version 3.5.30729.1
Copyright (c) Microsoft Corporation. All rights reserved.
Key pair written to stackTest.snk
c:\stackexchangetest> sn -p stackTest.snk publicStackTest.snk
Microsoft (R) .NET Framework Strong Name Utility Version 3.5.30729.1
Copyright (c) Microsoft Corporation. All rights reserved.
Public key written to publicStackTest.snk
c:\stackexchangetest> sn -tp publicStackTest.snk
Microsoft (R) .NET Framework Strong Name Utility Version 3.5.30729.1
Copyright (c) Microsoft Corporation. All rights reserved.
Public key is
002400000480000094000000060200000024000052534131000400000100010079ba0ab991ceda
d7ba4a767d55889a6cd0eafc9bc15c394620b61c02f4c1112dd9e348cbb4826775c72164ac8552
f9b751b1a1dd71874c04b24221f00f4ee8c2971f3ac8b6b381b26d39cbd3347e773bf08e9af838
6d7f317592951a4985e2c187288d037d5af2f62cce2e4dc700d0d00feb4c095df5d12c9a0908dc
8606cdad
Public key token is 6dfd37060fccec62
第二步:创建一个版本为 v1.0.0 的程序集
c:\stackexchangetest\1.0.0> type StackTest.cs
using System;
namespace stack.exchange.rdomarat
{
public class stackTest
{
public static String getVersion()
{
return( "1.0.0" );
}
}
}
c:\stackexchangetest\1.0.0> type AssemblyInfo.cs
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("stack.exchange.rdomarat")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("StackExchange")]
[assembly: AssemblyProduct("rdomarat")]
[assembly: AssemblyCopyright("Copyright 2012")]
[assembly: AssemblyTrademark("rdomarat")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: Guid("a3d17815-97f5-4e56-803c-06f652a23369")]
[assembly: AssemblyVersion( "1.0.0" )]
c:\stackexchangetest\1.0.0> csc /out:stack.exchange.rdomarat.dll /keyfile:../stackTest.snk /debug /w:4 /t:library AssemblyInfo.cs StackTest.cs
Microsoft (R) Visual C# 2008 Compiler version 3.5.30729.5420
for Microsoft (R) .NET Framework version 3.5
Copyright (C) Microsoft Corporation. All rights reserved.
第三步:为 v1.0.0 程序集创建策略 DLL
c:\stackexchangetest\1.0.0> type stack.exchange.rdomarat.config
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="stack.exchange.rdomarat"
publicKeyToken="6dfd37060fccec62"
culture=neutral
/>
<bindingRedirect oldVersion="1.0.0-1.0.0"
newVersion="1.0.0"
/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
c:\stackexchangetest\1.0.0> al.exe /version:1.0.0 /link:stack.exchange.rdomarat.config /out:policy.1.0.stack.exchange.rdomarat.dll /keyfile:../stackTest.snk /description:"Policy file" /title:"Policy file" /company:"StackExchange" /copyright:"Copyright 2012" /trademark:"rdomarat" /product:"rdomarat"
Microsoft (R) Assembly Linker version 9.0.30729.1
Copyright (C) Microsoft Corporation. All rights reserved.
第四步:将这两个程序集注册到 GAC
c:\stackexchangetest\1.0.0> gacutil -u stack.exchange.rdomarat
Microsoft (R) .NET Global Assembly Cache Utility. Version 3.5.30729.1
Copyright (c) Microsoft Corporation. All rights reserved.
No assemblies found matching: stack.exchange.rdomarat
Number of assemblies uninstalled = 0
Number of failures = 0
c:\stackexchangetest\1.0.0> gacutil -u policy.1.0.stack.exchange.rdomarat
Microsoft (R) .NET Global Assembly Cache Utility. Version 3.5.30729.1
Copyright (c) Microsoft Corporation. All rights reserved.
No assemblies found matching: policy.1.0.stack.exchange.rdomarat
Number of assemblies uninstalled = 0
Number of failures = 0
c:\stackexchangetest\1.0.0> gacutil -i stack.exchange.rdomarat.dll
Microsoft (R) .NET Global Assembly Cache Utility. Version 3.5.30729.1
Copyright (c) Microsoft Corporation. All rights reserved.
Assembly successfully added to the cache
c:\stackexchangetest\1.0.0> gacutil -i policy.1.0.stack.exchange.rdomarat.dll
Microsoft (R) .NET Global Assembly Cache Utility. Version 3.5.30729.1
Copyright (c) Microsoft Corporation. All rights reserved.
Assembly successfully added to the cache
第五步:创建一个使用新的 v1.0.0 程序集的应用程序
c:\stackexchangetest\stackapp\1.0.0> type stackApp.cs
using System;
using stack.exchange.rdomarat;
public class StackApp
{
public static void Main()
{
String s1;
s1 = stackTest.getVersion();
Console.WriteLine("Hello " + s1);
}
}
c:\stackexchangetest\stackapp\1.0.0> csc /out:StackApp.exe /target:exe /reference:..\..\1.0.0\stack.exchange.rdomarat.dll StackApp.cs
Microsoft (R) Visual C# 2008 Compiler version 3.5.30729.5420
for Microsoft (R) .NET Framework version 3.5
Copyright (C) Microsoft Corporation. All rights reserved.
c:\stackexchangetest\stackapp\1.0.0> stackapp
Hello 1.0.0
第六步:创建 v2.0.0 stack.exchange.rdomarat.dll 程序集
c:\stackexchangetest\2.0.0> type StackTest.cs
using System;
namespace stack.exchange.rdomarat
{
public class stackTest
{
public static String getVersion()
{
return( "2.0.0" );
}
}
}
c:\stackexchangetest\2.0.0> type AssemblyInfo.cs
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("stack.exchange.rdomarat")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("StackExchange")]
[assembly: AssemblyProduct("rdomarat")]
[assembly: AssemblyCopyright("Copyright 2012")]
[assembly: AssemblyTrademark("rdomarat")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: Guid("a3d17815-97f5-4e56-803c-06f652a23369")]
[assembly: AssemblyVersion( "2.0.0" )]
c:\stackexchangetest\2.0.0> csc /out:stack.exchange.rdomarat.dll /keyfile:../stackTest.snk /debug /w:4 /t:library AssemblyInfo.cs StackTest.cs
Microsoft (R) Visual C# 2008 Compiler version 3.5.30729.5420
for Microsoft (R) .NET Framework version 3.5
Copyright (C) Microsoft Corporation. All rights reserved.
第七步:为 v2.0.0 程序集创建策略 DLL
c:\stackexchangetest\2.0.0> type stack.exchange.rdomarat.config
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="stack.exchange.rdomarat"
publicKeyToken="6dfd37060fccec62"
culture=neutral
/>
<bindingRedirect oldVersion="1.0.0-2.0.0"
newVersion="2.0.0"
/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
c:\stackexchangetest\2.0.0> al.exe /version:2.0.0 /link:stack.exchange.rdomarat.config /out:policy.2.0.stack.exchange.rdomarat.dll /keyfile:../stackTest.snk /description:"Policy file" /title:"Policy file" /company:"StackExchange" /copyright:"Copyright 2012" /trademark:"rdomarat" /product:"rdomarat"
Microsoft (R) Assembly Linker version 9.0.30729.1
Copyright (C) Microsoft Corporation. All rights reserved.
第八步:将两个 v2.0.0 程序集注册到 GAC
c:\stackexchangetest\2.0.0> gacutil -u policy.2.0.stack.exchange.rdomarat
Microsoft (R) .NET Global Assembly Cache Utility. Version 3.5.30729.1
Copyright (c) Microsoft Corporation. All rights reserved.
No assemblies found matching: policy.2.0.stack.exchange.rdomarat
Number of assemblies uninstalled = 0
Number of failures = 0
c:\stackexchangetest\2.0.0> gacutil -i stack.exchange.rdomarat.dll
Microsoft (R) .NET Global Assembly Cache Utility. Version 3.5.30729.1
Copyright (c) Microsoft Corporation. All rights reserved.
Assembly successfully added to the cache
c:\stackexchangetest\2.0.0> gacutil -i policy.2.0.stack.exchange.rdomarat.dll
Microsoft (R) .NET Global Assembly Cache Utility. Version 3.5.30729.1
Copyright (c) Microsoft Corporation. All rights reserved.
Assembly successfully added to the cache
第九步:创建一个使用新的 v2.0.0 程序集的应用程序
c:\stackexchangetest\stackapp\2.0.0> type stackApp.cs
using System;
using stack.exchange.rdomarat;
public class StackApp
{
public static void Main()
{
String s1;
s1 = stackTest.getVersion();
Console.WriteLine("Hello " + s1);
}
}
c:\stackexchangetest\stackapp\2.0.0> csc /out:StackApp.exe /target:exe /reference:..\..\2.0.0\stack.exchange.rdomarat.dll StackApp.cs
Microsoft (R) Visual C# 2008 Compiler version 3.5.30729.5420
for Microsoft (R) .NET Framework version 3.5
Copyright (C) Microsoft Corporation. All rights reserved.
c:\stackexchangetest\stackapp\2.0.0> StackApp.exe
Hello 2.0.0
第 10 步:从 GAC 注销所有内容,并确认这两个应用程序都无法正常工作
c:\stackexchangetest\stackapp\2.0.0> gacutil -u policy.2.0.stack.exchange.rdomarat
Microsoft (R) .NET Global Assembly Cache Utility. Version 3.5.30729.1
Copyright (c) Microsoft Corporation. All rights reserved.
Assembly: policy.2.0.stack.exchange.rdomarat, Version=2.0.0.0, Culture=neutral,PublicKeyToken=6dfd37060fccec62, processorArchitecture=MSIL
Uninstalled: policy.2.0.stack.exchange.rdomarat, Version=2.0.0.0, Culture=neutral, PublicKeyToken=6dfd37060fccec62, processorArchitecture=MSIL
Number of assemblies uninstalled = 1
Number of failures = 0
c:\stackexchangetest\stackapp\2.0.0> gacutil -u policy.1.0.stack.exchange.rdomarat
Microsoft (R) .NET Global Assembly Cache Utility. Version 3.5.30729.1
Copyright (c) Microsoft Corporation. All rights reserved.
Assembly: policy.1.0.stack.exchange.rdomarat, Version=1.0.0.0, Culture=neutral,PublicKeyToken=6dfd37060fccec62, processorArchitecture=MSIL
Uninstalled: policy.1.0.stack.exchange.rdomarat, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6dfd37060fccec62, processorArchitecture=MSIL
Number of assemblies uninstalled = 1
Number of failures = 0
c:\stackexchangetest\stackapp\2.0.0> gacutil -u stack.exchange.rdomarat
Microsoft (R) .NET Global Assembly Cache Utility. Version 3.5.30729.1
Copyright (c) Microsoft Corporation. All rights reserved.
Assembly: stack.exchange.rdomarat, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6dfd37060fccec62, processorArchitecture=MSIL
Uninstalled: stack.exchange.rdomarat, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6dfd37060fccec62, processorArchitecture=MSIL
Assembly: stack.exchange.rdomarat, Version=2.0.0.0, Culture=neutral, PublicKeyToken=6dfd37060fccec62, processorArchitecture=MSIL
Uninstalled: stack.exchange.rdomarat, Version=2.0.0.0, Culture=neutral, PublicKeyToken=6dfd37060fccec62, processorArchitecture=MSIL
Number of assemblies uninstalled = 2
Number of failures = 0
c:\stackexchangetest\stackapp\1.0.0> StackApp.exe
Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'stack.exchange.rdomarat, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6dfd37060fccec62' or one of its dependencies. The system cannot find the file specified.
File name: 'stack.exchange.rdomarat, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6dfd37060fccec62' at StackApp.Main()
Assembly manager loaded from: C:\Windows\Microsoft.NET\Framework64\v2.0.50727\mscorwks.dll
Running under executable c:\StackExchangeTest\StackApp\1.0.0\StackApp.exe
--- A detailed error log follows.
=== Pre-bind state information ===
LOG: User = SYBASE\rdomarat
LOG: DisplayName = stack.exchange.rdomarat, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6dfd37060fccec62 (Fully-specified)
LOG: Appbase = file:///C:/Users/rdomarat/Documents/Issues/111205_mlclient_policy/StackExchangeTest/StackApp/1.0.0/
LOG: Initial PrivatePath = NULL
Calling assembly : StackApp, Version=0.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\Framework64\v2.0.50727\config\machine.config.
LOG: Post-policy reference: stack.exchange.rdomarat, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6dfd37060fccec62
LOG: The same bind was seen before, and was failed with hr = 0x80070002.
c:\stackexchangetest\stackapp\2.0.0> StackApp.exe
Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'stack.exchange.rdomarat, Version=2.0.0.0, Culture=neutral, PublicKeyToken=6dfd37060fccec62' or one of its dependencies. The system cannot find the file specified.
File name: 'stack.exchange.rdomarat, Version=2.0.0.0, Culture=neutral, PublicKeyToken=6dfd37060fccec62' at StackApp.Main()
Assembly manager loaded from: C:\Windows\Microsoft.NET\Framework64\v2.0.50727\mscorwks.dll
Running under executable c:\StackExchangeTest\StackApp\2.0.0\StackApp.exe
--- A detailed error log follows.
=== Pre-bind state information ===
LOG: User = SYBASE\rdomarat
LOG: DisplayName = stack.exchange.rdomarat, Version=2.0.0.0, Culture=neutral, PublicKeyToken=6dfd37060fccec62 (Fully-specified)
LOG: Appbase = file:///C:/Users/rdomarat/Documents/Issues/111205_mlclient_policy/StackExchangeTest/StackApp/2.0.0/
LOG: Initial PrivatePath = NULL
Calling assembly : StackApp, Version=0.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\Framework64\v2.0.50727\config\machine.config.
LOG: Post-policy reference: stack.exchange.rdomarat, Version=2.0.0.0, Culture=neutral, PublicKeyToken=6dfd37060fccec62
LOG: The same bind was seen before, and was failed with hr = 0x80070002.
第十一步:重新注册 v2.0.0 程序集,这两个应用程序现在应该可以工作了
c:\stackexchangetest\2.0.0> gacutil -i stack.exchange.rdomarat.dll
Microsoft (R) .NET Global Assembly Cache Utility. Version 3.5.30729.1
Copyright (c) Microsoft Corporation. All rights reserved.
Assembly successfully added to the cache
c:\stackexchangetest\2.0.0> gacutil -i policy.2.0.stack.exchange.rdomarat.dll
Microsoft (R) .NET Global Assembly Cache Utility. Version 3.5.30729.1
Copyright (c) Microsoft Corporation. All rights reserved.
Assembly successfully added to the cache
c:\stackexchangetest\stackapp\2.0.0> StackApp.exe
Hello 2.0.0
c:\stackexchangetest\stackapp\1.0.0> StackApp.exe
Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'stack.exchange.rdomarat, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6dfd37060fccec62' or one of its dependencies. The system cannot find the file specified.
File name: 'stack.exchange.rdomarat, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6dfd37060fccec62' at StackApp.Main()
Assembly manager loaded from: C:\Windows\Microsoft.NET\Framework64\v2.0.50727\mscorwks.dll
Running under executable c:\StackExchangeTest\StackApp\1.0.0\StackApp.exe
--- A detailed error log follows.
=== Pre-bind state information ===
LOG: User = SYBASE\rdomarat
LOG: DisplayName = stack.exchange.rdomarat, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6dfd37060fccec62 (Fully-specified)
LOG: Appbase = file:///C:/Users/rdomarat/Documents/Issues/111205_mlclient_policy/StackExchangeTest/StackApp/1.0.0/
LOG: Initial PrivatePath = NULL
Calling assembly : StackApp, Version=0.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\Framework64\v2.0.50727\config\machine.config.
LOG: Post-policy reference: stack.exchange.rdomarat, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6dfd37060fccec62
LOG: The same bind was seen before, and was failed with hr = 0x80070002.