在探测程序集时,为什么在以管理员身份和普通用户身份运行时搜索到的publicKeyToken会有所不同?

时间:2011-10-01 01:02:19

标签: c# .net assemblies gac

我正在按照2006年Microsoft .Net课程练习册的说明进行其中一项练习。 (具体来说,本课程是MS2349B,我正在进行第4单元练习2)。这些练习似乎是为Vista之前的每个人都拥有完全管理员权限而构建的。 (我正在使用.net 4.0。)

本练习涉及构建强名称程序集,将其安装在GAC中,针对强名称程序集构建本地可执行文件,验证可执行文件是否运行。

根据教程,我使用#if块来签署我的程序集:

#if STRONG
[assembly: System.Reflection.AssemblyVersion("2.0.0.0")]
[assembly: System.Reflection.AssemblyKeyFile("OrgVerKey.snk")]
#endif

我以本地用户身份构建我的可执行文件:

C:\path\to\lab>csc /define:STRONG /target:library 
 /out:AReverser_v2.0.0.0\AReverser.dll AReverser_v2.0.0.0\AReverser.cs
C:\path\to\lab>csc /reference:MyStringer\Stringer.dll     
 /reference:AReverser_v2.0.0.0\AReverser.dll Client.cs

我通过以管理员身份运行的visual studio命令提示符将其安装到GAC中:

C:\path\to\lab>gacutil /i AReverser_v2.0.0.0\AReverser.dll

当我在管理员提示符下运行我的exe时,我得到了我期望的输出 - 应用程序运行正常并且似乎正确地从gac加载dll。当我在非管理员命令提示符下运行时,我收到以下错误

Unhandled Exception: System.IO.FileLoadException: Could not load file or assembl
y 'AReverser, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b5fcbdcff229fabb'
 or one of its dependencies. The located assembly's manifest definition does not
 match the assembly reference. (Exception from HRESULT: 0x80131040)
   at MainApp.Main()

对我来说奇怪的是publicKeyToken与GAC中的内容不同:

AReverser, Version=2.0.0.0, Culture=neutral, PublicKeyToken=f0548c0027634b66

但是如果我从GAC卸载AReverser并尝试运行我的exe作为管理员提示我得到以下错误,表明它正在寻找预期的公钥令牌f0548c0027634b66:

C:\path\to\lab>gacutil /u "AReverser,Version=2.0.0.0,Culture=neutral,
PublicKeyToken=f0548c0027634b66"
Microsoft (R) .NET Global Assembly Cache Utility.  Version 4.0.30319.1
Copyright (c) Microsoft Corporation.  All rights reserved.


Assembly: AReverser, Version=2.0.0.0, Culture=neutral, PublicKeyToken=f0548c0027
634b66
Uninstalled: AReverser, Version=2.0.0.0, Culture=neutral, PublicKeyToken=f0548c0
027634b66
Number of assemblies uninstalled = 1
Number of failures = 0

C:\path\to\lab>Client.exe

Unhandled Exception: System.IO.FileLoadException: Could not load file or assembl
y 'AReverser, Version=2.0.0.0, Culture=neutral, PublicKeyToken=f0548c0027634b66'
 or one of its dependencies. The located assembly's manifest definition does not
 match the assembly reference. (Exception from HRESULT: 0x80131040)
   at MainApp.Main()

在Admin下注意,它实际上是在搜索正确的publicKeyToken。

是什么给出的?为什么搜索的publickKeyTokens会有所不同?我怎么可能做错了?

修改

我们被告知要使用的应用配置可能是罪魁祸首,我想知道您是否必须是管理员才能应用其中一些设置。摆脱它似乎导致作为管理员运行失败(尽管在那种情况下,publicKeyToken被列为NULL)。这是我的app config

<configuration>   
    <runtime>
        <assemblyBinding
            xmlns="urn:schemas-microsoft-com:asm.v1">
            <probing privatePath="MyStringer"/>
            <publisherPolicy apply="no"/>
            <dependentAssembly>
                <assemblyIdentity name="AReverser" 
                    publicKeyToken="f0548c0027634b66" 
                    culture=""/>
                <publisherPolicy apply="no"/>
                <bindingRedirect oldVersion="2.0.0.0" 
                    newVersion="2.0.0.0"/>
            </dependentAssembly>
        </assemblyBinding>
    </runtime>
</configuration>

2 个答案:

答案 0 :(得分:1)

在磁盘中搜索AReverser.dll。您可能在某处隐藏了一些额外的副本。 VS可以制作已编译dll的卷影副本。

如果这无助于激活融合日志记录(使用fuslogvw.exe或假脱机融合日志到磁盘),然后查看加载有问题的dll的日志。 IMO它是加载的错误的DLL。

答案 1 :(得分:0)

你的解决方案在哪里说装配? Visual Studio不使用gac来构建,所以如果在引用目录中留下不同版本的已签名程序集程序集,则客户端将针对该构建器进行构建,并在尝试在运行时加载时失败,因为首先加载了gac 。