当探测程序集时,为什么以管理员身份运行和普通用户身份运行时搜索的公钥令牌不同?

9
我正在按照2006年微软.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

当我在管理员提示符中运行我的可执行文件时,我得到了我所期望的输出 - 应用程序正常运行,并似乎从全局程序集缓存中正确加载了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()

注意在管理员下,实际上是在搜索正确的publicKeyToken。

怎么回事?为什么搜索到的publicKeyToken不同?我可能做错了什么?

编辑

我们被告知要使用的应用程序配置可能是罪魁祸首,我想知道是否必须成为管理员才能应用其中一些设置。删除它似乎会导致以管理员身份运行失败(尽管在这种情况下,publicKeyToken列为空)。这是我的应用程序配置:

<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>

你有签名程序集吗?我在你的CSC语句中没有看到密钥文件。 - user957902
@user957902 我按照 MS2349B 工作手册中的示例,在上方使用 #if STRONG 块对它们进行签名。 - Doug T.
1
“.snk”文件从哪里来?如果是自己创建的,那么您需要在配置文件中更改令牌值。 - Hans Passant
1
@HansPassant 在进行这个练习之前,我使用了 sn -k OrgVerKey.snk - Doug T.
2个回答

1

在您的磁盘中搜索AReverser.dll。可能您有一些额外的副本藏在某个地方。VS可以制作编译后dll的影子副本。

如果这没有帮助,请激活融合日志记录(使用fuslogvw.exe或将融合日志输出到磁盘),然后查看日志,找出问题dll的加载位置。 我认为加载了错误的dll。


0

你的解决方案中在哪里指定汇编程序?Visual Studio不使用全局程序集缓存(gac)来进行构建,因此如果您在引用目录中留下了一个不同版本的已签名程序集程序,客户端将构建失败并在运行时尝试加载时失败,因为gac首先被加载。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接