Powershell 从NuGet包加载程序集
有时在我的PowerShell脚本中,我需要使用Powershell 从NuGet包加载程序集,powershell,nuget-package,powershell-4.0,Powershell,Nuget Package,Powershell 4.0,有时在我的PowerShell脚本中,我需要使用Add Type-AssemblyName访问特定的DLL。然而,我需要的DLL并不总是在机器上或GAC中。例如,我可能需要一个使用Dapper查询数据库的快速脚本。在这些情况下,我一直在复制DLL以及ps1文件。我想知道这是否常见/是个好主意,是否有一个现有的扩展可以加载NuGet包,然后存储在全局或本地文件夹中,并自动调用Add Type-AssemblyName 这与在Node.js或Python中分别使用npm或pip非常相似 更新 我做了
Add Type-AssemblyName
访问特定的DLL。然而,我需要的DLL并不总是在机器上或GAC中。例如,我可能需要一个使用Dapper查询数据库的快速脚本。在这些情况下,我一直在复制DLL以及ps1
文件。我想知道这是否常见/是个好主意,是否有一个现有的扩展可以加载NuGet包,然后存储在全局或本地文件夹中,并自动调用Add Type-AssemblyName
这与在Node.js或Python中分别使用npm
或pip
非常相似
更新
我做了一些研究,但是旧版本的PowerShell没有内置任何东西。我使用nuget.exe
&"$(Get-Location)/nuget.exe" install $packageName -Version $version -OutputDirectory "$(Get-Location)/packages" -NoCache -NoInteractive
这将下载当前文件夹中“packages”文件夹下的给定包/版本及其任何依赖项。然而,它似乎下载了每个框架版本,没有明显的方法来告诉您的给定环境使用哪一个
否则,您可以循环遍历结果并调用Add Type:
Get-ChildItem .\packages\ -Recurse -Filter "*.dll" | % {
try
{
Add-Type -Path $_.FullName
}
catch [System.Exception]
{
}
}
我尝试使用project.json
文件使用restore
命令,看看是否可以控制框架版本。这对我来说太难了
我将查看@crownedjitter关于使用PowerShell 5的建议
更新
使用@crownedjitter的建议,我最终能够向NuGet注册PackageManagement模块(参见下面的注释)。使用以下命令,我能够重现上面的Nuget.exe
命令所做的操作:
Install-Package Dapper -Destination packages
显然,这要短得多。问题是它有同样的局限性;它会降低包的每个框架版本。如果这包括了.NETCore,那么它会带来大量的.NETCore框架!似乎没有办法指定目标框架(又称.NET 4.5.1或更低版本)
我想知道是否有办法根据PowerShell当前的
$PSVersionTable.CLRVersion
字段确定要从哪个NuGet软件包文件夹加载DLL。是否使用PowerShell 5?因为如果是,它有一个包管理模块:
它似乎是开源的:是一个很好的起点,Travis本人在评论中提供了额外的提示,但让我尝试总结一下自Windows PowerShell v5.1以来的情况
# If this fails, the provider isn't installed
Get-PackageProvider nuget
更新:下面的原始答案包含一些有用的常规指针,以及指向的链接,但是它显示的基于安装包
的方法最终会出现缺陷,因为它不考虑包的依赖关系,如
指出:
缺少的一个(不是那么简单)步骤是加载可能已经安装的任何依赖项。因为,这似乎需要从源目录中的.nupkg
文件中提取.nuspec
文件,读取相应框架的
,并加载这些包的程序集
以下方法解决了这一问题,但请注意,它首先需要下载并安装带有dotnet
CLI的:
# If this fails, the provider isn't installed
Get-PackageProvider nuget
- 为辅助项目创建文件夹,将向其中添加包并对其进行更改;e、 g:
设置位置(新项目类型目录组件)
- 在该文件夹中,创建一个虚拟库项目:
dotnet新类库
- 添加对感兴趣的文件包的引用;e、 g:
dotnet添加程序包Dapper
- 要引用特定版本,请添加
-v
- 发布虚拟项目,该项目将所有必需的DLL(包括依赖项)复制到发布文件夹中:
dotnet发布-c版
- 重要:
参数的确切大小写(小写与大写)决定了相应输出文件夹的确切大小写;为了确保代码也能在区分大小写的文件系统上工作,特别是在Linux上,请确保在引用输出二进制文件的文件路径中使用完全相同的大小写-c
- 测试包装的主组件是否可以加载;e、 g:
添加类型-路径bin/Release/*/publish/Dapper.dll
- 验证包的类型是否可以使用;e、 g.:
[Dapper.DbString]::new()
bin/Release/*/publish/*.DLL
文件复制到您选择的文件夹中,并从那里引用它
以下示例脚本显示了一个脚本,该脚本根据需要下载包,并在程序集
子文件夹中相对于脚本位置创建辅助项目
$packageName = 'Terminal.Gui'
$assembly = "$packageName.dll"
# Set to @() to get the latest stable version.
$packageVersionArgs = '-v', '1.0.0-pre.4'
$projectFolder = 'assemblies' # Subfolder for the aux. project
$assemblyPath = "$PSScriptRoot/$projectFolder/bin/Release/*/publish/$assembly"
$literalAssemblyPath = Convert-Path -ErrorAction Ignore $assemblyPath
if ($literalAssemblyPath) {
Write-Verbose -vb "Package '$packageName' already installed. Loading main assembly: $literalAssemblyPath"
Add-Type -ErrorAction Stop -LiteralPath $literalAssemblyPath
}
else {
Write-Verbose -vb "Installing package '$packageName'..."
$null = Get-Command -ErrorAction Stop -CommandType Application dotnet
Push-Location (New-Item -ErrorAction Stop -Type Directory "$PSScriptRoot/$projectFolder")
$null = dotnet new classlib
$null = dotnet add package $packageName @packageVersionArgs
$null = dotnet publish -c Release
Pop-Location
Write-Verbose -vb "Loading main assembly: $assemblyPath"
Add-Type -ErrorAction Stop -Path $assemblyPath
}
# Instantiate a type from the package to verify that it was loaded.
"Listing property names of a [Terminal.Gui.Button] instance:"
[Terminal.Gui.Button]::new().psobject.Properties.Name
原始答案
- 如上所述,PowerShell v5+(包括PowerShell Core)附带了
模块,该模块是一个元包管理器,通过提供程序提供对多个存储库的访问;在v3和v4中可以按需安装此模块(标记为“2016年3月预览”,这是我能找到的最新版本)PackageManagement
列出所有可用的提供程序查找PackageProvider
列出已安装的程序包Get PackageProvider
- 正是
提供商通过nuget
Install Package
# If this fails, the provider isn't installed
Get-PackageProvider nuget
pnuget
(Get-ChildItem -Filter *.dll -Recurse (Split-Path (Get-Package Dapper).Source)).FullName
C:\Program Files\PackageManagement\NuGet\Packages\Dapper.1.50.4\lib\net451\Dapper.dll C:\Program Files\PackageManagement\NuGet\Packages\Dapper.1.50.4\lib\netstandard1.3\Dapper.dll C:\Program Files\PackageManagement\NuGet\Packages\Dapper.1.50.4\lib\netstandard2.0\Dapper.dll
(Get-Item (Join-Path (Split-Path (Get-Package Dapper).Source) lib/netstandard*) | Sort-Object { [version] ($_.Name -replace '^netstandard') })[-1] | Get-ChildItem -Filter *.dll -Recurse | ForEach-Object { Add-Type -LiteralPath $_.FullName }
Get-ChildItem -Recurse -Filter *.dll -LiteralPath (Join-Path (Split-Path (Get-Package Dapper).Source) lib/netstandard2.0) | ForEach-Object { Add-Type -LiteralPath $_.FullName }