如何在PowerShell中加载程序集?
以下PowerShell代码
#Get a server object which corresponds to the default instance $srv = New-Object -TypeName Microsoft.SqlServer.Management.SMO.Server ... rest of the script ...
给出以下错误信息:
New-Object : Cannot find type [Microsoft.SqlServer.Management.SMO.Server]: make sure the assembly containing this type is loaded. At C:\Users\sortelyn\ ... \tools\sql_express_backup\backup.ps1:6 char:8 + $srv = New-Object -TypeName Microsoft.SqlServer.Management.SMO.Server + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidType: (:) [New-Object], PSArgumentException + FullyQualifiedErrorId : TypeNotFound,Microsoft.PowerShell.Commands.NewObjectCommand
在互联网上的每一个答案写道,我必须加载程序集 – 以及确保我可以从错误信息中读取:-) – 问题是:
你如何加载程序集并使脚本工作?
LoadWithPartialName
已被弃用。 推荐的PowerShell V3解决scheme是使用Add-Type
cmdlet,例如:
Add-Type -Path 'C:\Program Files\Microsoft SQL Server\110\SDK\Assemblies\Microsoft.SqlServer.Smo.dll'
有多个不同的版本,你可能想select一个特定的版本。 🙂
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo")
现在大多数人都知道System.Reflection.Assembly.LoadWithPartialName
已被弃用,但事实certificateAdd-Type -AssemblyName Microsoft.VisualBasic
行为不如LoadWithPartialName
:
[Add-Type]查看静态内部表,将“部分名称”转换为“全名”,而不是尝试在系统上下文中parsing请求。
如果您的“部分名称”没有出现在他们的表中,您的脚本将失败。
如果您的计算机上安装了多个版本的程序集,则没有智能algorithm可供select。 你会得到任何一个出现在他们的表,可能是旧的,过时的。
如果您安装的版本比表中的旧版本更新,则脚本将失败。
Add-Type没有像“
.LoadWithPartialNames
”这样的“部分名称”智能parsing器。
微软说你实际上应该做的是这样的:
Add-Type -AssemblyName 'Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
或者,如果你知道path,就像这样:
Add-Type -Path 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.VisualBasic\v4.0_10.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualBasic.dll'
这个长长的名字被称为强名 ,这个名字对于版本和程序集来说都是独一无二的,有时也被称为全名。
但是这留下了一些未解答的问题:
-
我如何确定使用给定的部分名称在系统上实际加载的强名称?
[System.Reflection.Assembly]::LoadWithPartialName($TypeName).Location;
[System.Reflection.Assembly]::LoadWithPartialName($TypeName).FullName;
-
如果我希望我的脚本始终使用.dll的特定版本,但是我无法确定它的安装位置,我如何确定.dll的强名称?
[System.Reflection.AssemblyName]::GetAssemblyName($Path).FullName;
-
如果我知道强名,我该如何确定.dllpath?
[Reflection.Assembly]::Load('Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a').Location;
-
而且,以类似的方式,如果我知道我使用的是什么types的名称,我怎么知道它是从哪里来的?
[Reflection.Assembly]::GetAssembly([Type]).Location
-
我如何查看可用的组件?
我build议使用GAC PowerShell模块 。 Get-GacAssembly -Name 'Microsoft.SqlServer.Smo*' | Select Name, Version, FullName
Get-GacAssembly -Name 'Microsoft.SqlServer.Smo*' | Select Name, Version, FullName
工作得很好。
- 我怎样才能看到
Add-Type
使用的列表?
这有点复杂。 我没有在网上看到任何logging的清单,但我可以描述如何使用.Netreflection器访问它。
首先,找出哪个库的Add-Type
来自:
Get-Command -Name Add-Type | Select-Object -Property DLL
用你的reflection器打开产生的DLL。 我为此使用了ILSpy ,因为是FLOSS,但是任何C#reflection器都可以工作。 打开该库,然后查看Microsoft.Powershell.Commands.Utility
。 在Microsoft.Powershell.Commands
,应该有AddTypeCommand
。 在代码清单中,有一个私有类, InitializeStrongNameDictionary()
。 列出了将短名称映射到强名称的字典。 我看过的图书馆里有近750个参赛作品。
以下是一些博客文章,介绍了在PowerShell v1,v2和v3中加载程序集的方法示例。
方法包括:
- dynamic地从一个源文件
- dynamic从一个程序集
- 使用其他代码types,即F#
v1.0 如何在PowerShell会话中加载.NET程序集
v2.0 在PowerShell脚本2.0中使用CSharp(C#)代码
v3.0 在Windows PowerShell中使用.NET Framework程序集
如果要在PowerShell会话期间加载程序集而不locking它 ,请使用以下命令:
$bytes = [System.IO.File]::ReadAllBytes($storageAssemblyPath) [System.Reflection.Assembly]::Load($bytes)
其中$storageAssemblyPath
是您的程序集的文件path。
如果您需要清理会话中的资源,这尤其有用。 例如在部署脚本中。
您可以加载整个* .dll程序集
$Assembly = [System.Reflection.Assembly]::LoadFrom("C:\folder\file.dll");
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo")
为我工作。
你可以使用LoadWithPartialName
。 但是,正如他们所说,这已经被废弃了。
您确实可以使用Add-Type
,除了其他答案之外,如果您不想指定.dll文件的完整path,则只需执行以下操作:
Add-Type -AssemblyName "Microsoft.SqlServer.Management.SMO"
对我来说,这返回了一个错误,因为我没有安装SQL Server(我猜),但是,与此相同的想法,我能够加载Windows窗体大会:
Add-Type -AssemblyName "System.Windows.Forms"
您可以在MSDN站点上find属于特定类的精确程序集名称:
没有答案帮助我,所以我发布的解决scheme,为我工作,我所要做的就是导入SQLPS模块,我意识到这一点,当我意外地运行了Restore-SqlDatabase命令,并开始工作,这意味着该组件以某种方式在该模块中被引用。
赶紧跑:
Import-module SQLPS
在顶部添加程序集引用。
加载所需的组件SMO和SmoExtended。
[System.Reflection.Assembly] :: LoadWithPartialName(“Microsoft.SqlServer.SMO”)| Out-Null [System.Reflection.Assembly] :: LoadWithPartialName(“Microsoft.SqlServer.SmoExtended”)| 外空
确保您具有以下function按顺序安装
1 – 用于SQL Server的Microsoft系统CLRtypes
2-Microsoft SQL Server共享pipe理对象
3个Microsoft Windows PowerShell扩展
你也可能需要加载
Add-Type -Path“C:\ Program Files \ Microsoft SQL Server \ 110 \ SDK \ Assemblies \ Microsoft.SqlServer.Smo.dll”
Add-Type -Path“C:\ Program Files \ Microsoft SQL Server \ 110 \ SDK \ Assemblies \ Microsoft.SqlServer.SqlWmiManagement.dll”