【发布时间】:2021-03-10 15:29:42
【问题描述】:
LoadFile() 功能真的让我很难受。
我有两个程序集,Asm1.dll 和 Asm2.dll,它们正在 GAC 中安装。
稍后,使用LoadFile() 加载这些程序集以创建匹配的类型库。
这一切都适用于Asm1.dll(在 PowerShell 中测试):
[System.Reflection.Assembly]::LoadFile("D:\MyTools\Asm1.dll")
GAC Version Location
True v4.0.30319 C:\Windows\Microsoft.Net\assembly\GAC_64\Asm1\v4.0_4.0.30000.0__abcdef123456\Asm1.dll
但它不适用于Asm2.dll
[System.Reflection.Assembly]::LoadFile("D:\MyTools\Asm2.dll")
Exception calling "LoadFile" with "1" argument(s): "Could not load file or assembly 'Asm2.dll'
or one of its dependencies. The specified module could not be found."
但是,这两个程序集确实存在于我的工作文件夹以及 GAC 中:
gci C:\Windows\Microsoft.Net\assembly\GAC_64\Asm2\v4.0_2.3.30000.0__abcdef123456\Asm2.dll
gci C:\Windows\Microsoft.Net\assembly\GAC_64\Asm1\v4.0_4.0.30000.0__abcdef123456\Asm1.dll
Mode LastWriteTime Length Name
-a---- 10 Mar 2021 15:37 1494528 Asm2.dll
-a---- 10 Mar 2021 12:47 6749184 Asm1.dll
gci D:\MyTools\Asm1.dll
gci D:\MyTools\Asm2.dll
Mode LastWriteTime Length Name
-a---- 10 Mar 2021 12:47 6749184 Asm1.dll
-a---- 10 Mar 2021 14:00 1494528 Asm2.dll
我还尝试使用完整的 GAC 路径 LoadFile() - 两个程序集的结果相同。
从过去我知道,在重建我的工具之前,从我的组件的所有痕迹中清除 HKCU 注册表和 GAC 后,问题就消失了。但在我更新了 Visual Studio 并在没有先清理所有东西的情况下重建了我的工具之后,它确实在今天早上重新出现。
LoadFile() 函数就像一个黑匣子,准确地零告诉我出了什么问题。打个比方,我不想再通过“在我只是在寻找熔断的保险丝时拆除我的整个建筑物”来解决这个问题。
那么我该如何追踪这个失败的根本原因呢?
编辑
@Efie 谢谢。 $error[0] 仅指向 LoadFile() 函数作为错误源。那里没有其他见解。
@Ian Kemp、@Jeroen Mostert 感谢您推荐融合日志查看器。
它确实提供了一些信息,但仍未指出实际原因。相反 - 日志表明程序集绑定成功,而错误消息仍然出现在 PowerShell 控制台中。
The operation was successful.
=== Pre-bind state information ===
LOG: DisplayName = Asm2, Version=2.3.30000.0, Culture=neutral,
PublicKeyToken=abcdef123456
(Fully-specified)
LOG: Appbase = file:///C:/Windows/system32/WindowsPowerShell/v1.0/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = PowerShell_ISE.exe
Calling assembly : (Unknown).
===
LOG: This bind starts in default load context.
LOG: Using application configuration file:
C:\Windows\system32\WindowsPowerShell\v1.0\PowerShell_ISE.exe.Config
LOG: Using host configuration file:
LOG: Using machine configuration file from
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config.
LOG: Binding succeeds. Returns assembly from C:\Windows\Microsoft.Net\assembly\GAC_64\Asm2\v4.0_2.3.30000.0__abcdef123456\Asm2.dll.
LOG: Assembly is loaded in default load context.
两个程序集 Asm1 和 Asm2 的日志文件是相同的,除了名称、版本以及融合日志明确报告它在 GAC 中找到 Asm1 而它没有不要为Asm2 这样做:
LOG: Post-policy reference: Asm1, Version=4.0.30000.0, Culture=neutral, PublicKeyToken=abcdef123456
LOG: Found assembly by looking in the GAC.
如果我在对LoadFile() 的两个调用中指定完整的 GAC 路径,则两个程序集 Asm1 和 Asm2 的日志文件除了名称和版本之外是相同的;包括Post-policy-line。
【问题讨论】:
-
错误对象内可能有其他信息。只有消息被打印到屏幕上。您可以通过检查
$error变量来检查最近的错误,例如$error[0]。有时那里隐藏着其他信息。$error[0] | Get-Member将为您提供可以进一步挖掘的属性列表。 -
那个黑匣子确实有记录功能。 See also.
-
我呼吁那些反对这个问题的人提出解决方案!与此同时,我运行了dependency walker。它检测到 Asm1.dll 对
OLE32.DLL的依赖(不出所料)。但它也检测到c:\windows\system32\OLE32.DLL和c:\program files\powershell\7\API-MS-WIN-CORE-COM-L1-1-0.DLL之间的循环依赖关系,我认为这是 PowerShell 中的一个错误。但是,临时重命名 PowerShell 文件夹删除了循环依赖,但并没有解决原始问题。还有什么想法吗?
标签: c# powershell fusion-log-viewer