Powershell 加载什么版本的 dll 文件?

jya*_*yao 2 dll powershell

当我在 Windows 10 中启动 PowerShell ISE 时,我可以运行以下代码

$dt = new-object "system.data.DataTable";
Run Code Online (Sandbox Code Playgroud)

我知道这只是可行的,因为 System.Data.dll 已加载,否则,将会出现错误,因为DataTable类来自 System.Data.dll

在我的计算机上,我安装了多个版本的.Net Framework,例如 v4.6.x、v4.7.x

所以我的问题是,一旦我的 PowerShell 启动

  1. 我如何知道加载了哪些 DLL 文件?
  2. 他们的版本是什么?

在此先感谢您的时间 !

Ste*_*enP 6

如果您只关心当前加载的程序集,您可以使用

[System.AppDomain]::CurrentDomain.GetAssemblies()
GAC    Version        Location
---    -------        --------
True   v4.0.30319     C:\Windows\Microsoft.NET\Framework64\v4.0.30319\mscorlib.dll
True   v4.0.30319     C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.PowerSh
True   v4.0.30319     C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0
True   v4.0.30319     C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Core\v4.0_
Run Code Online (Sandbox Code Playgroud)

如果您关心引用的程序集,事情就会变得复杂。

$loaded = [System.AppDomain]::CurrentDomain.GetAssemblies()
$referenced = $loaded.GetReferencedAssemblies() | select-object -Unique
Run Code Online (Sandbox Code Playgroud)

这将获取所有加载的程序集和所有引用的程序集。问题是引用的程序集并未全部加载,因此这只能获取 AssemblyName 对象。

$referenced
Version        Name
-------        ----
4.0.0.0        mscorlib
4.0.0.0        System
3.0.0.0        System.Management.Automation
4.0.0.0        System.Core
4.0.0.0        System.Xml
4.0.0.0        System.Configuration
Run Code Online (Sandbox Code Playgroud)

要获取其余详细信息,您可以使用反射。

$referenced = $loaded.GetReferencedAssemblies() | select-object -Unique | ForEach-Object {
    [System.Reflection.Assembly]::ReflectionOnlyLoad($_)
}
$referenced
GAC    Version        Location
---    -------        --------
True   v4.0.30319     C:\Windows\Microsoft.NET\Framework64\v4.0.30319\mscorlib.dll
True   v4.0.30319     C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0
True   v4.0.30319     C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Management
True   v4.0.30319     C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Core\v4.0_
True   v4.0.30319     C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Xml\v4.0_4
True   v4.0.30319     C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Configurat
True   v4.0.30319     C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Numerics\v
True   v4.0.30319     C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Security\v
True   v4.0.30319     C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.DirectoryS
Run Code Online (Sandbox Code Playgroud)

请注意,其中许多可能已经加载,因此您需要获取已加载的程序集并将它们从引用列表中删除。

$referenced = $loaded.GetReferencedAssemblies() | select-object -Unique | `
    ForEach-Object {
        [System.Reflection.Assembly]::ReflectionOnlyLoad($_)
    } | Where-Object {
            $loaded.FullName -notcontains $_.FullName
    }
Run Code Online (Sandbox Code Playgroud)

现在引用列表仅是未加载的引用程序集。

$referenced
GAC    Version        Location
---    -------        --------
True   v4.0.30319     C:\WINDOWS\Microsoft.Net\assembly\GAC_64\Microsoft.Manag
True   v4.0.30319     C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.JSc
True   v4.0.30319     C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Servic
True   v4.0.30319     C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Web.Re
True   v4.0.30319     C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Design
True   v4.0.30319     C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.Bui
Run Code Online (Sandbox Code Playgroud)

但请注意,这些可能引用了未加载的程序集。因此,如果您想深入挖掘,则需要构建一个递归函数来迭代它们,重复上述方法。