Bax*_*ter 145 powershell powershell-3.0
以下PowerShell代码
#Get a server object which corresponds to the default instance
$srv = New-Object -TypeName Microsoft.SqlServer.Management.SMO.Server
... rest of the script ...
Run Code Online (Sandbox Code Playgroud)
给出以下错误消息:
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
Run Code Online (Sandbox Code Playgroud)
互联网上的每个答案都写道我必须加载程序集 - 确保我可以从错误信息中读取:-) - 问题是:
如何加载程序集并使脚本工作?
Kei*_*ill 172
LoadWithPartialName已被弃用.PowerShell V3的推荐解决方案是使用Add-Typecmdlet,例如:
Add-Type -Path 'C:\Program Files\Microsoft SQL Server\110\SDK\Assemblies\Microsoft.SqlServer.Smo.dll'
Run Code Online (Sandbox Code Playgroud)
有多个不同的版本,您可能想要选择特定版本.:-)
Sha*_*evy 71
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo")
Run Code Online (Sandbox Code Playgroud)
Bac*_*its 41
大多数人现在System.Reflection.Assembly.LoadWithPartialName都知道已经弃用了,但事实证明它的Add-Type -AssemblyName Microsoft.VisualBasic 表现并不比LoadWithPartialName以下更好:
而不是尝试在系统上下文中解析您的请求,[Add-Type]查看静态内部表以将"部分名称"转换为"全名".
如果您的"部分名称"没有出现在他们的表中,您的脚本将失败.
如果您的计算机上安装了多个版本的程序集,则无法在它们之间进行选择.你将会得到他们的桌子中出现的任何一个,可能是旧的,过时的.
如果您安装的版本都比表中过时的版本新,那么您的脚本将失败.
Add-Type没有"部分名称"的智能解析器
.LoadWithPartialNames.
微软说你实际应该做的是这样的:
Add-Type -AssemblyName 'Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
Run Code Online (Sandbox Code Playgroud)
或者,如果您知道路径,可以这样:
Add-Type -Path 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.VisualBasic\v4.0_10.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualBasic.dll'
Run Code Online (Sandbox Code Playgroud)
为程序集指定的长名称称为强名称,它对于版本和程序集都是唯一的,有时也称为全名.
但这留下了几个未回答的问题:
如何确定具有给定部分名称的系统上实际加载内容的强名称?
[System.Reflection.Assembly]::LoadWithPartialName($TypeName).Location;
[System.Reflection.Assembly]::LoadWithPartialName($TypeName).FullName;
如果我希望我的脚本始终使用.dll的特定版本,但我无法确定它的安装位置,我如何确定.dll的强名称是什么?
[System.Reflection.AssemblyName]::GetAssemblyName($Path).FullName;
如果我知道强名称,我该如何确定.dll路径?
[Reflection.Assembly]::Load('Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a').Location;
而且,在类似的情况下,如果我知道我正在使用的类型名称,我怎么知道它来自哪个组件?
[Reflection.Assembly]::GetAssembly([Type]).Location
[Reflection.Assembly]::GetAssembly([Type]).FullName
如何查看可用的组件?
我建议使用GAC PowerShell模块. Get-GacAssembly -Name 'Microsoft.SqlServer.Smo*' | Select Name, Version, FullName效果很好.
Add-Type使用的列表?这有点复杂.我可以描述如何使用.Net反射器访问任何版本的PowerShell(请参阅下面的PowerShell Core 6.0更新).
首先,找出哪个库Add-Type来自:
Add-Type -AssemblyName $TypeName -PassThru | Select-Object -ExpandProperty Assembly | Select-Object -ExpandProperty FullName -Unique
Run Code Online (Sandbox Code Playgroud)
用反射器打开生成的DLL.我已经使用了ILSpy,因为它是FLOSS,但任何C#反射器都应该有效.打开那个库,然后查看Microsoft.Powershell.Commands.Utility.在Microsoft.Powershell.Commands,应该有AddTypeCommand.
在代码清单中,有一个私有类,InitializeStrongNameDictionary().这列出了将短名称映射到强名称的字典.在我看过的库中有近750个条目.
更新:现在PowerShell Core 6.0是开源的.对于该版本,您可以跳过上述步骤,并在其GitHub存储库中直接在线查看代码.但是,我不能保证该代码与任何其他版本的PowerShell匹配.
Mar*_*ndl 21
如果要在PowerShell会话期间加载程序集而不锁定它,请使用以下命令:
$bytes = [System.IO.File]::ReadAllBytes($storageAssemblyPath)
[System.Reflection.Assembly]::Load($bytes)
Run Code Online (Sandbox Code Playgroud)
$storageAssemblyPath程序集的文件路径在哪里.
如果您需要清理会话中的资源,这尤其有用.例如,在部署脚本中.
Ral*_*oss 15
以下是一些博客文章,其中包含许多在PowerShell v1,v2和v3中加载程序集的方法示例.
方法包括:
v1.0 如何在PowerShell Session
v2.0中加载.NET 程序集在PowerShell脚本2.0
v3.0中使用CSharp(C#)代码在Windows PowerShell中使用.NET Framework程序集
小智 8
您可以加载整个*.dll程序集
$Assembly = [System.Reflection.Assembly]::LoadFrom("C:\folder\file.dll");
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
240063 次 |
| 最近记录: |