PowerShell:.NET 程序集的导入模块还是添加类型? [英] PowerShell: Import-Module or Add-Type for .NET assemblies?

查看:25
本文介绍了PowerShell:.NET 程序集的导入模块还是添加类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是 PowerShell 5.1、Windows 10 x64.

我应该使用这 2 个 cmdlet 中的哪一个来将 .NET 程序集(特别是 .NET Framework 4+ 程序集)加载到 PowerShell 中?它们之间的核心区别是什么?我想加载用于访问类型、创建对象、调用方法等的程序集.

我在文档中没有找到任何明确的陈述.这些 cmdlet 被描述为完全不同的东西.Import-Module 的 MSDN 文档甚至不包含 .dll 程序集加载的示例——只有 PowerShell 模块.但是 Import-Module 可与 .NET Framework 程序集一起使用(不过,仅适用于 .dll):我可以完美地处理来自导入程序集的类型,解析并加载它们引用的程序集也.这是为什么?

换句话说,根据我的经验,我还没有发现这两种程序集导入方法之间的任何区别(至少对于 .NET Framework 4 .dll 程序集).

这篇旧博文:使用 .NETWindows PowerShell 中的框架程序集 甚至使用 Reflection.Assembly.LoadWithPartialName!我相信这是因为他们从 GAC 加载了一个程序集并且不想指定它的完整路径(不过我可能错了).

对于我的程序集,我知道它们的完整路径,因此我可以在 Import-ModuleAdd-Type 中指定它.同样,有什么区别,我应该使用什么?

谢谢!

解决方案

Powershell 有三种主要的方法来导入类,不包括像 reflection.assembly 这样的 .net 方法.一般来说,它们都可以很好地满足您的需求,但具有额外的功能:

导入模块

具有迄今为止最大的灵活性,可以导入基本模块(通常是 .psd1 或 .psm1 文件)及其所需的程序集、CIM 模块(带有 CDXML 文件)、[Assembly] 类型的对象、通过 .dll 文件的程序集、通过 .dll 文件的 cmdlet 等等.导入 PS 模块有更多功能,但除了加载整个内容"之外的其他类没有.

添加类型

有一堆额外的功能,可以在您需要时有效地添加类.例如,它可以将 C#/VB/JScript 类型定义作为字符串直接加载.我个人只在需要时使用它,或者如果 import-module 无法正确导入 dll 文件,但帮助中列出了更多功能.它不像其他选项那样导入模块.

使用

相对较新,仅在 v5.1+ 中.它将从模块导入类定义,与 Import-Module#requires 语句不同.否则,它的行为与 ipmo 非常相似,但我喜欢它的可读性,并且更喜欢 using namespace 而不是 .net 版本:

使用模块 ModuleName# 或者使用程序集 'C:\path\to\assembly.name.subassembly.whatever.dll'使用命名空间 assembly.name.subassembly.whatever.additional.namespace[NiceAndShort]::Foo


<块引用>

他们引用的程序集也被解析和加载.这是为什么?

不幸的是,powershell 只是将每个程序集(及其依赖项,以及 powershell 自己的依赖项)加载到同一上下文中.在处理冲突的依赖版本时,这可能会导致一些麻烦.解决 PowerShell 模块程序集依赖冲突.

I'm using PowerShell 5.1, Windows 10 x64.

Which of these 2 cmdlets should I use to load .NET assemblies (in particular .NET Framework 4+ assemblies) into PowerShell? What's the core difference between them? I want to load assemblies for accessing types, creating objects, calling methods, etc.

I haven't found any explicit statements in the documentation. These cmdlets are described like they are completely different things. MSDN documentation for Import-Module doesn't even contain examples for .dll assemblies loading -- only PowerShell modules. However Import-Module works with .NET Framework assemblies (.dll only, though): I can perfectly work with types from the imported assemblies, their referenced assemblies are resolved and loaded too. Why is that?

In other words, from my experience I haven't yet found any differences between these 2 assemblies importing methods (at least for .NET Framework 4 .dll assemblies).

This old blog post: Using .NET Framework Assemblies in Windows PowerShell even uses Reflection.Assembly.LoadWithPartialName! I believe this is because they load an assembly from the GAC and do not want to specify full path to it (I may be wrong, though).

For my assemblies I know full path to them, so I can specify it in both Import-Module and Add-Type. Again, what's the difference and what should I use?

Thanks!

解决方案

Powershell has three main ways to import classes, not counting .net methods like reflection.assembly. In general, all of them will do what you need just fine, but have extra features:

Import-Module

has by far the most flexibility, and can import basic Modules (usually .psd1 or .psm1 files) and their required assemblies, CIM Modules (with CDXML files), [Assembly]-type objects, assemblies via .dll files, cmdlets via .dll files, and probably more. There's more features for importing PS Modules, but not for classes other than "load the whole thing".

Add-Type

has a bunch of extra functionality for adding classes efficiently if you need it. For example, it can take C#/VB/JScript type definitions as string and load them directly. I personally only use it when I need that, or if a dll file can't be imported correctly by import-module, but there are many more features listed on the help. It doesn't import modules like the other options.

Using

Relatively new and only in v5.1+. It will import class definitions from a module, unlike Import-Module or the #requires statement. Otherwise, it behaves very similarly to ipmo, but I like it for its readability and much prefer using namespace to the .net version:

using module ModuleName
# or
using assembly 'C:\path\to\assembly.name.subassembly.whatever.dll'
using namespace assembly.name.subassembly.whatever.additional.namespace

[NiceAndShort]::Foo


their referenced assemblies are resolved and loaded too. Why is that?

Unfortunately, powershell takes the path of simply loading every assembly (and their dependencies, and powershell's own dependencies) into the same context. This can cause some headaches when dealing with conflicting dependency versions. It's better covered in Resolving PowerShell module assembly dependency conflicts.

这篇关于PowerShell:.NET 程序集的导入模块还是添加类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆