Powershell加载哪个版本的dll文件?

时间:2018-10-15 23:30:49

标签: powershell dll

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

$dt = new-object "system.data.DataTable";

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

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

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

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

提前感谢您的时间!

2 个答案:

答案 0 :(得分:3)

使用以下命令,并与运行PowerShell v5.1的Windows 10计算机的示例输出一起显示:

PS> (Get-Item ([System.Data.DataTable].Assembly.Location)).VersionInfo | Format-List    

OriginalFilename  : system.data.dll
FileDescription   : .NET Framework
ProductName       : Microsoft® .NET Framework
Comments          : Flavor=Retail
CompanyName       : Microsoft Corporation
FileName          : C:\WINDOWS\Microsoft.Net\assembly\GAC_64\System.Data\v4.0_4.0.0.0__b77a5c561934e089\System.Data.dll
FileVersion       : 4.7.3160.0 built by: NET472REL1LAST_C
ProductVersion    : 4.7.3160.0
IsDebug           : False
IsPatched         : False
IsPreRelease      : False
IsPrivateBuild    : True
IsSpecialBuild    : False
Language          : English (United States)
LegalCopyright    : © Microsoft Corporation.  All rights reserved.
LegalTrademarks   :
PrivateBuild      : DDBLD202B
SpecialBuild      :
FileVersionRaw    : 4.7.3160.0
ProductVersionRaw : 4.0.30319.0
  • [System.Data.DataTable]是类型文字(表示全名的对象)

  • .Assembly返回表示包含该类型的程序集的对象。

  • .Location返回该程序集的文件路径。

  • 将该文件路径传递到Get-Item会输出一个代表程序集文件的[System.IO.FileInfo]对象。

  • [System.IO.FileInfo]对象具有一个.VersionInfo属性,该属性返回版本信息的详细信息。

  • Format-List的管道将以列表形式显示版本信息的详细信息,每个属性都打印在自己的行上。

请注意,有 两个版本号

  • CLR (公共语言运行时)版本号,反映在Version.ProductVersionRaw4.0.30319.0)中(但似乎也间接地)在文件路径v4.0_4.0.0.0__b77a5c561934e089

  • 框架版本号,反映在VersionInfo.ProductVersion4.7.3160.0

通常,多个成功的 framework 版本是基于 CLR 版本构建的;例如,两个框架v4.6.x和v4.7.x都是基于CLR v4.x构建的。

请注意,并非所有System.*类型都必须报告完全相同的框架版本,但是根据定义,它们报告的 CLR 版本是相同的。


通过直接访问[version] version-info属性,使用以下内容仅提取 framework 版本号作为ProductVersion对象:

[version] (Get-Item ([System.Data.DataTable].Assembly.Location)).VersionInfo.ProductVersion

例如,将产生:

Major  Minor  Build  Revision
-----  -----  -----  --------
4      7      3160   0       

答案 1 :(得分:1)

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

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

如果您关心引用的程序集,它将变得很复杂。

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

这将获取所有已加载的程序集和所有引用的程序集。问题是引用的程序集并未全部加载,因此只能获取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

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

$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

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

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

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

$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

请注意,尽管它们可能具有未同时加载的引用程序集。因此,如果您想深入研究一下,则需要构建一个递归函数来迭代它们,并重复上述方法。