PowerShellスクリプトで、Add-Type -AssemblyName
を使用して特定のDLLにアクセスする必要がある場合があります。ただし、必要なDLLが常にマシンまたはGACにあるとは限りません。たとえば、Dapperを使用してデータベースにクエリを実行する簡単なスクリプトが必要な場合があります。これらの場合、私は文字通りps1
ファイルと一緒にDLLをコピーしています。これが一般的/良いアイデアであるかどうか、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
コマンドを使用して、運が悪ければフレームワークのバージョンを制御できるかどうかを確認しました。これは私にはあまりにもハッキーです。
PowerShell5の使用に関する@crownedjitterの提案を確認します。
@crownedjitterの提案を使用して、最終的にPackageManagementモジュールをNuGetに登録することができました(以下のコメントを参照)。次のコマンドを使用して、上記のNuget.exe
コマンドが実行していたことを再現することができました。
Install-Package Dapper -Destination packages
明らかに、これははるかに短いです。問題は、同じ制限があることです。パッケージのすべてのフレームワークバージョンをダウンさせます。これに.NETコアが含まれていると、.NETコアフレームワークのかなりの部分がダウンします。ターゲットフレームワーク(別名、.NET 4.5.1以下)を指定する方法はないようです。
PowerShellの現在の$PSVersionTable.CLRVersion
フィールドに基づいて、DLLをロードするNuGetパッケージフォルダーを決定する方法があるかどうか疑問に思っています。
crownedjitterの役立つ回答 は良い出発点であり、Travis自身がコメントで追加のポインターを提供していますが、Windows PowerShellv5.1の時点で要約:
前述のように、PowerShell v5 +(PowerShell Core を含む)には、プロバイダーを介して複数のリポジトリへのアクセスを提供するメタパッケージマネージャーであるPackageManagement
モジュールが付属しています。 ;このモジュールのオンデマンドインストールは may v3およびv4で可能です( このダウンロード 「2016年3月のプレビュー」というラベルが付いており、最新のものです。私は見つけることができました)。
Find-PackageProvider
は、すべての available プロバイダーを一覧表示します。Get-PackageProvider
はインストール済みのものをリストします。Install-Package
を介したNugetパッケージのインストールを有効にするのはnuget
プロバイダーであり、2つの潜在的なハードルがあります。
nuget
プロバイダーがインストールされていない可能性があります。
Find-Package
が結果を返すのを妨げる誤ったAPIURLでインストールされている可能性があります。
nuget
プロバイダーがインストールされているかどうかをテストします:
# If this fails, the provider isn't installed
Get-PackageProvider nuget
is がインストールされている場合:パッケージのソースURIが正しいことを確認します:
Get-PackageSource
:[.____を実行します。]Nugettest
ソースを見つけた場合は、それを削除します:Unregister-PackageSource Nugettest
nuget.org
のLocation
列に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
インストールされていないの場合:プロバイダーを最初からインストールします:
次のコマンドを実行します。
Install-PackageProvider nuget
Register-PackageSource -ProviderName nuget -name nuget.org -Location https://www.nuget.org/api/v2 -Trusted
上記の手順を完了すると、NuGetパッケージの検出(例:Find-Package Dapper
)とインストール(例:Install-Package Dapper
)が成功するはずです。
デフォルトでは、Install-Package
はAllUsers
スコープにインストールされます。これには昇格が必要ですが、現在のユーザーのコンテキストでのインストールは-Scope CurrentUser
でのみ選択できます。
ダウンロードしたNuGetパッケージを使用:
注:Add-Type
を拡張してPowerShellでNuGetパッケージを簡単に使用するには、 GitHubに関するこの提案 を参照してください。これにより、PowerShell Core6.2.0以降も必要な後続のすべての手順が不要になります。
質問で示されているように、パッケージのアセンブリをAdd-Type -Path <Assembly-file-path>
を使用してPowerShellセッションに手動でロードする必要があります;ただし、.NET Coreの時代には、パッケージにさまざまな.NET環境用のDLLが含まれている可能性があるため、パッケージフォルダ内の all *.dll
ファイルを常に盲目的にロードできるとは限りません =:
ダウンロードしたパッケージのファイルシステムの場所を見つけるには、.Source
によって返される関連オブジェクトのGet-Package
プロパティをクエリします。
(Get-Package Dapper).Source
パッケージ内のすべてのDLLのフルパスを表示するには、次のコマンドを実行します。
(Get-ChildItem -Filter *.dll -Recurse (Split-Path (Get-Package Dapper).Source)).FullName
完全な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
。NETStandard DLLが all .NETプラットフォームで実行されている場合、プログラムで検索できます。 (最新の)そのような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 }
上記は、利用可能な最高の.NET標準バージョンDLLを探します。 特定のバージョンをターゲットにする場合、コマンドは簡単になります。例:.NET標準の場合2.0
:
Get-ChildItem -Recurse -Filter *.dll -LiteralPath (Join-Path (Split-Path (Get-Package Dapper).Source) lib/netstandard2.0) |
ForEach-Object { Add-Type -LiteralPath $_.FullName }
[〜#〜] bacon [〜#〜] は、パッケージにロードする必要のある依存関係がある場合、上記では不十分である:
欠落している1つの(それほど重要ではない)ステップは、インストールされている可能性のある依存関係もロードすることです。 Dependenciesプロパティに十分な情報が含まれていない であるため、Sourceディレクトリの
.nuspec
ファイルから.nupkg
ファイルを抽出し、適切なフレームワークの<group>
を読み取り、それらのパッケージのアセンブリをロードする必要があるようです。 。