如何让PowerShell在加载程序集后添加类型

3

我使用Add-Type加载了一个程序集:

 $Typename = '\\crtwfaadvlkv0.d2dbfg.com\PRODUCTION\Vision\Apps\VisionPipeline\Oracle.ManagedDataAccess.dll'
 Add-Type -LiteralPath $TypeName

并确认它已被加载

> [appdomain]::CurrentDomain.GetAssemblies() |
>> Sort-Object -Property FullName |
>> Select-Object -Property FullName;

(partial results)

Oracle.ManagedDataAccess, Version=4.122.19.1, Culture=neutral, PublicKeyToken=89b483f429c47342

下一步,我希望能够加载程序集中定义的类,以便使用它们,但是这会导致错误:
> $oracletpe = Add-Type -AssemblyName 'Oracle.ManagedDataAccess' -PassThru
Add-Type : Cannot add type. The assembly 'Oracle.ManagedDataAccess' could not be found.
At line:1 char:14
+ ... oracletpe = Add-Type -AssemblyName 'Oracle.ManagedDataAccess' -PassTh ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (Oracle.ManagedDataAccess:String) [Add-Type], Exception
    + FullyQualifiedErrorId : ASSEMBLY_NOT_FOUND,Microsoft.PowerShell.Commands.AddTypeCommand

Add-Type : Cannot add type. One or more required assemblies are missing.
At line:1 char:14
+ ... oracletpe = Add-Type -AssemblyName 'Oracle.ManagedDataAccess' -PassTh ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Add-Type], InvalidOperationException
    + FullyQualifiedErrorId : ASSEMBLY_LOAD_ERRORS,Microsoft.PowerShell.Commands.AddTypeCommand

看起来PowerShell找不到刚刚加载的程序集。我做错了什么吗?


为什么要通过路径和名称两次加载程序集?只需在第一个 Add-Type 命令(带有 LiteralPath)中添加“-PassThru”参数,并将结果分配给变量即可。 - swbbl
我不想加载两次。我觉得我没有理解它的操作方式。我正在尝试加载dll,然后在第二次调用中将类型加载到命名空间中。我很困惑为什么Posh找不到程序集,因为它刚刚加载了它。 - user1443098
2个回答

1
如果您不想重复添加它,则不需要第二次加载。
如我在评论中提到的那样,只需将“-PassThru”参数添加到第一个“Add-Type”命令中即可。
$assemblyFilePath = '\\crtwfaadvlkv0.d2dbfg.com\PRODUCTION\Vision\Apps\VisionPipeline\Oracle.ManagedDataAccess.dll'
$assembly = Add-Type -LiteralPath $assemblyFilePath -PassThru

$assembly

但是如果你想重新加载它,请使用程序集限定名称:

Add-Type -AssemblyName 'Oracle.ManagedDataAccess, Version=4.122.19.1, Culture=neutral, PublicKeyToken=89b483f429c47342' -PassThru

一般情况下,只有全局程序集缓存 (GAC) 中的程序集和应用程序文件夹 (递归) 中的程序集才允许使用部分名称。但是,也有一些特殊扩展,比如 SQL Server 的 "host assembly store" 等。
但不要将“应用程序文件夹”与脚本所在的文件夹混淆。这是 PowerShell 应用程序文件夹:%WinDir%\System32\WindowsPowerShell\v1.0\ 如果您想测试它,只需将 DLL 放入该文件夹并启动新的 PowerShell 控制台即可。
有关程序集加载的更多信息(尤其是关于部分名称的),请参阅 https://learn.microsoft.com/en-us/dotnet/framework/deployment/best-practices-for-assembly-loading#avoid-binding-on-partial-assembly-names

0

这很有帮助,谢谢...我正在使用它来引用一个NuGet包,其中包含我正在填充的WPF表单的图标。很高兴知道我可以保留我的后端PowerShell。

为了让我的工作正常运行,我最终所做的就是将添加的NuGet引用路径放入VS解决方案中的变量中,然后在调用WPF对象函数之后调用它。

$assemblyFilePath = "$ScriptRoot\QATool\packages\FontAwesome.Sharp.6.1.1\lib\net40\FontAwesome.Sharp.dll"

然后在将所有WPF元素组合成一个对象的函数和调用下面...我添加了这行代码...

Add-Type -LiteralPath $assemblyFilePath -PassThru

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