从NuGet包加载程序集

Tra*_*rks 14 powershell nuget-package powershell-4.0

有时在我的PowerShell脚本中,我需要使用访问特定的DLL Add-Type -AssemblyName.但是,我需要的DLL并不总是在机器上或GAC中.例如,我可能想要一个使用Dapper查询数据库的快速脚本.在这些情况下,我一直在将DLL与ps1文件一起复制.我想知道这是不是常见/一个好主意,是否有现有的扩展会加载NuGet包,然后存储在全局或本地文件夹中并Add-Type -AssemblyName自动调用.

它分别与使用npmpip在Node.js或Python中很相似.

更新

我做了一些研究,并没有内置到旧版本的PowerShell.我试图从头开始编写一个使用的nuget.exe

&"$(Get-Location)/nuget.exe" install $packageName -Version $version -OutputDirectory "$(Get-Location)/packages" -NoCache -NoInteractive
Run Code Online (Sandbox Code Playgroud)

这将下载当前文件夹中"packages"文件夹下的给定包/版本及其任何依赖项.但是,它看起来像下载每个框架版本,没有明显的方法来告诉您哪个用于您的给定环境.

否则,您可以循环遍历结果并调用Add-Type:

Get-ChildItem .\packages\ -Recurse -Filter "*.dll" | % {
    try
    {
        Add-Type -Path $_.FullName
    }
    catch [System.Exception]
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

我尝试使用restore命令使用project.json文件来查看我是否可以控制框架版本而没有运气.这对我来说太过于苛刻了.

我将查看@ crownedjitter关于使用PowerShell 5的建议.

更新

使用@ crownedjitter的建议,我最终能够使用NuGet注册PackageManagement模块(请参阅下面的评论).使用以下命令,我能够重现Nuget.exe上面的命令正在执行的操作:

Install-Package Dapper -Destination packages
Run Code Online (Sandbox Code Playgroud)

显然,这要短得多.问题是它有同样的局限性; 它降低了包的每个框架版本.如果这包括.NET核心,它会带来很多.NET核心框架!似乎没有办法指定目标框架(又名.NET 4.5.1或更低版本).

Install-Package抓取所有.NET框架的依赖关系

我想知道是否有办法根据PowerShell的当前$PSVersionTable.CLRVersion字段确定从哪个NuGet包文件夹加载DLL .

mkl*_*nt0 20

在GitHub上看到这个建议,通过扩展可以更容易地在PowerShell中使用NuGet包PackageManagement.

crownedjitter的有用答案是一个很好的起点,Travis本人在评论中提供了额外的指示,但让我尝试总结一下Windows PowerShell v5.1:

  • 如上所述,PowerShell v5 +(包括PowerShell Core)附带的Find-PackageProvider模块是元包管理器,可通过提供程序访问多个存储库; 在v3和v4中可以按需安装此模块(此下载标记为"2016年3月预览",这是我能找到的最新版本).

    • Get-PackageProvider列出所有可用的提供商
    • nuget列出已安装的.
  • 它是通过Install-Package提供Nuget包安装nuget的提供商,有两个潜在的障碍:

    • Find-Package供应商可能无法安装.

    • 它可能安装了错误的API URL,导致nuget无法返回结果.

测试是否Get-PackageSource安装了提供程序:

# If this fails, the provider isn't installed
Get-PackageProvider nuget
Run Code Online (Sandbox Code Playgroud)

如果安装:验证包源URI是否正确:

  • 打开提升的 PowerShell会话.
  • 运行Nugettest:
    • 如果找到Unregister-PackageSource Nugettest源,请将其删除:
      • Location
    • 如果nuget.org源列https://api.nuget.org/v3/index.json显示ttps://www.nuget.org/api/v2(或其他内容Set-PackageSource nuget.org -NewLocation https://www.nuget.org/api/v2 -Trusted),请更新它:

如果安装:从头开始安装提供程序:

  • 打开提升的 PowerShell会话.
  • 运行以下命令:

    Install-PackageProvider nuget
    Register-PackageSource -ProviderName nuget -name nuget.org -Location https://www.nuget.org/api/v2 -Trusted
    
    Run Code Online (Sandbox Code Playgroud)

在完成上述步骤之后,NuGet包的发现(例如Install-Package Dapper)和安装(例如Install-Package)应该成功.

默认情况下,AllUsers安装到-Scope CurrentUser范围,这需要提升,但您可以选择仅在当前用户的上下文中安装Add-Type.


使用下载的NuGet包:

  • 如问题所示,您需要手动将软件包的程序集加载到PowerShell会话中Add-Type -Path <assembly-file-path> ; 但是,在.NET Core时代,软件包可能具有适用于不同.NET环境的DLL,因此您无法盲目加载软件包文件夹中的所有 *.dll文件.

  • 查看完整的DLL路径应该告诉您哪些DLL是适合您的环境加载的DLL; 使用Dapper包的示例:

    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
    
    Run Code Online (Sandbox Code Playgroud)

据我所知,从Windows PowerShell v5.1/PowerShell Core v6.0.2开始,没有更简单的方法 - 请告诉我们是否存在.


小智 6

你在使用Powershell 5吗?因为如果你是,它有一个包管理模块:

Powershell 5中的PackageManagement模块

它似乎是开源的:https://github.com/OneGet

  • 有点疯狂,但NuGet位置错了.我不得不取消注册提供者`Unregister-PackageSource nuget.org`然后重新注册它`Register-PackageSource -Name nuget.org -Location http://www.nuget.org/api/v2 -Force -Trusted`. (3认同)