NuGet 패키지에서 어셈블리 로드
을 사용하여 특정 DLL에.Add-Type -AssemblyName그러나 필요한 DLL이 항상 기계나 GAC에 있는 것은 아닙니다.예를 들어 Dapper를 사용하여 데이터베이스를 쿼리하는 빠른 스크립트가 필요할 수 있습니다.경우에, 는 문자 DLL을 .ps1인지, 패키지를 로드한 하고 일파에 전화할 수 . 이것이 일반적인지/좋은 아이디어인지, 그리고 NuGet 패키지를 로드하고 글로벌 또는 로컬 폴더에 저장하고 호출할 수 있는 기존 확장자가 있는지 궁금합니다.Add-Type -AssemblyName자동으로.
사용하는 것과 비슷합니다.npm또는pip각각 Node.js 또는 Python에 있습니다.
갱신하다
몇 가지 조사를 해봤는데 이전 버전의 PowerShell에는 기본 제공되는 기능이 없습니다.저는 처음부터 처음부터 하나를 쓰려고 노력하면서 약간의 진전을 이루었습니다.nuget.exe
&"$(Get-Location)/nuget.exe" install $packageName -Version $version -OutputDirectory "$(Get-Location)/packages" -NoCache -NoInteractive
지정된 패키지/버전을 현재 폴더의 "패키지" 폴더 아래에 해당 종속성과 함께 다운로드합니다.그러나 주어진 환경에 어떤 것을 사용할지 명확하게 알 수 있는 방법이 없이 모든 프레임워크 버전을 다운로드하는 것처럼 보입니다.
그렇지 않으면 결과를 반복하여 Add-Type을 호출할 수 있습니다.
Get-ChildItem .\packages\ -Recurse -Filter "*.dll" | % {
try
{
Add-Type -Path $_.FullName
}
catch [System.Exception]
{
}
}
는 사해보았다니습용▁the를 사용해 보았습니다.restore을 project.json프레임워크 버전을 제어할 수 있는지 확인하는 파일입니다.이건 저한테 너무 촌스러워요.
PowerShell 5를 사용하자는 @crownjitter의 제안을 확인해 보겠습니다.
갱신하다
@crownedjitter의 제안으로, 저는 결국 패키지 관리 모듈을 NuGet에 등록할 수 있었습니다(아래 주석 참조).다음 명령으로, 나는 무엇을 재현할 수 있었습니다.Nuget.exe위의 명령은 다음을 수행했습니다.
Install-Package Dapper -Destination packages
분명히, 이것은 훨씬 더 짧습니다.문제는 동일한 제한이 있다는 것입니다. 패키지의 모든 프레임워크 버전을 다운시킵니다.이에 포함되는 경우.NET 코어, 그것은 많은 것을 무너뜨립니다.NET 핵심 프레임워크를 포함합니다!대상 프레임워크(예: k.a, )를 지정할 수 있는 방법이 없는 것 같습니다.NET 4.5.1 이하).
PowerShell을 하는 방법이 .$PSVersionTable.CLRVersion밭.밭.
crownjitter의 유용한 답변은 좋은 출발점이며, Travis 자신이 코멘트에 추가 포인터를 제공했지만 Windows PowerShell v5.1 / PowerShell (Core) 7.3.2를 기준으로 요약해 보겠습니다.
업데이트: 이후 섹션에 재인쇄된 원본 답변에는 몇 가지 유용한 일반적인 포인터와 더불어 NuGet 패키지를 통합하기 위한 GitHub의 기능 제안 링크가 포함되어 있지만 BACON이 지적하는 것처럼 패키지의 종속성을 고려하지 않기 때문에 표시되는 기반 방법은 궁극적으로 부족합니다.
누락된 한 가지 단계는 설치되었을 수 있는 종속성도 로드하는 것입니다.Dependencies 속성에 충분한 정보가 포함되어 있지 않기 때문에 다음 정보를 추출해야 합니다.
.nuspec의 파일입니다..nupkg디렉토리에 로, "" " " " 를 .<group>적절한 프레임워크를 위해 패키지 어셈블리를 로드합니다.
다음 접근 방식은 이 문제를 해결하지만 먼저 의 다운로드 및 설치가 필요합니다.CLI를 사용한 NET SDK:
패키지를 추가할 보조 프로젝트의 폴더를 만들고 변경합니다. 예:
Set-Location (New-Item -Type Directory assemblies)
해당 폴더에서 더미 라이브러리 프로젝트를 생성합니다.
- PowerShell(Core)의 경우 최신 설치를 대상으로 합니다.기본적으로 NET(Core) SDK:
dotnet new classlib
- 윈도우즈 PowerShell의 경우 또는 대상을 지정합니다.NET 5+ OS별 프레임워크:
- 가장 높은 곳을 목표로 합니다.여전히 존재하는 NET 표준.NET Framework 호환:
dotnet new classlib -f netstandard2.0
- 특정 대상을 지정합니다.NET Framework 버전만 또는 a.NET 5+ OS별 프레임워크:
- 생성된 항목을 수동으로 편집해야 합니다.
.csproj합니다.<TargetFramework>요소; 예: 최신 버전과 마지막 버전을 대상으로 하려면 4.8을 사용합니다.<TargetFramework>net48</TargetFramework>Windows 사용하는 6에서는 API를 사용합니다. NET 6.0,<TargetFramework>net6.0-windows</TargetFramework>
- 생성된 항목을 수동으로 편집해야 합니다.
- 타겟팅.NET Framework에서 먼저 개발자 팩을 다운로드해야 할 수 있습니다.
- 가장 높은 곳을 목표로 합니다.여전히 존재하는 NET 표준.NET Framework 호환:
- PowerShell(Core)의 경우 최신 설치를 대상으로 합니다.기본적으로 NET(Core) SDK:
관심 패키지에 참조를 추가합니다. 예:
dotnet add package Dapper버전을 하려면 특정버을참려면다추다가니합음을조를 추가합니다.
-v <version>
종속성을 포함하여 필요한 모든 DLL을 게시 폴더에 복사하는 더미 프로젝트를 게시합니다.
dotnet publish -c Release- 중요:의 정확한 대소문자(소문자 대 대문자)
-c인수는 해당 출력 폴더의 정확한 대소문자를 결정합니다. 코드가 대소문자를 구분하는 파일 시스템에서도 작동하는지, 특히 Linux에서는 출력 이진 파일을 참조하는 파일 경로에서 동일한 대소문자를 사용하는지 확인하십시오.
패키지의 주 어셈블리가 로드될 수 있는지 테스트합니다. 예:
Add-Type -Path bin/Release/*/publish/Dapper.dll패키지 유형을 사용할 수 있는지 확인합니다. 예:
[Dapper.DbString]::new()
프로젝트에서 "" "" DLL"을할 수 있습니다.bin/Release/*/publish/*.dll파일을 선택한 폴더로 이동하고 여기서 참조합니다.
다음 샘플 스크립트는 터미널을 다운로드하는 스크립트를 보여줍니다.필요 시 GUI 패키지를 사용하여 보조 프로젝트를 생성합니다.assemblies스크립트 위치를 기준으로 하는 하위 폴더입니다.
$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
주의사항:
일부 패키지는 네이티브 라이브러리에 종속되어 있습니다.
dotnet publish의소장에 있는runtimes폴더의 , 를 들어runtimes\win-x64\native.윈도우즈 PowerShell에서
Add-Type -LiteralPath(및 그 기초가 됩니다.NET API 메서드, )는 플랫폼에 적합한 네이티브 라이브러리를 찾지만 이상하게도 PowerShell(Core) 7.2.0-preview.9에서 작동하지 않습니다. 적어도 NuGet 패키지 버전 5.0.9에서 확인할 수 있습니다.해결 방법은 플랫폼에 적합한 네이티브 라이브러리를
runtimes하위 폴더 트리를 게시 폴더에 직접 복사합니다.주문형 설치Add-NuGetType이 답변에서 설명하는 도우미 기능은 이 프로세스를 자동화합니다.
원답
앞서 설명한 바와 같이 PowerShell Core를 포함한 PowerShell v5+에는
PackageManagement공급자를 통해 여러 저장소에 대한 액세스를 제공하는 메타 패키지 관리자인 모듈. 이 모듈의 주문형 설치는 v3 및 v4에서 가능할 수 있습니다(이 다운로드는 "2016년 3월 미리 보기"로 레이블 지정되어 있으며 가장 최근에 찾을 수 있었습니다).Find-PackageProvider사용 가능한 모든 공급자가 나열됩니다.Get-PackageProvider에는 설치된 항목이 나열되어 있습니다.
바로 그것입니다.
nuget를 통해 Nuget 패키지를 설치할 수 있도록 지원하는 공급자로, 다음과 같은 두 가지 잠재적 장애물이 장애물은 다음과 같습니다.그
nuget공급자가 설치되지 않았을 수 있습니다.API 되어 "API URL"을 차단할 수 있습니다.
Find-Package결과를 반환합니다.
공급자가 설치되어 있는지 테스트:
# If this fails, the provider isn't installed
Get-PackageProvider nuget
설치된 경우:패키지 소스 URI가 올바른지 확인합니다.
- 상승된 PowerShell 세션을 엽니다.
- 려달을 합니다.
Get-PackageSource:- 만약 당신이 찾는다면
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- 주의: 이로 인해 Visual Studio에서 NuGet 패키지를 검색하는 기능이 손상될 수 있습니다. https://github.com/PowerShell/PowerShellGet/issues/107 을 참조하십시오.
- 만약 당신이 찾는다면
설치되지 않은 경우: 공급자를 처음부터 설치합니다.
상승된 PowerShell 세션을 엽니다.
다음 명령을 실행합니다.
Install-PackageProvider nuget Register-PackageSource -ProviderName nuget -name nuget.org -Location https://www.nuget.org/api/v2 -Trusted
단계를 한 후 위단계완예후한검색료를의예검:(▁(색후▁discovery▁aftere한,료)Find-Package Dapper및 ) 및치예설예(표시:Install-Package Dapper의 NuGet 패키지가 성공해야 합니다.
기적으로본,Install-Package에 AllUsers 권한 할 수 있습니다.-Scope CurrentUser.
다운로드한 NuGet 패키지 사용:
참고: GitHub 문제 #6724를 참조하십시오. 이 문제는 확장을 통해 PowerShell에서 NuGet 패키지를 보다 쉽게 사용할 수 있도록 하는 것을 제안합니다.Add-Type이를 통해 PowerShell Core 7.3.2 이후에도 필요한 모든 후속 단계가 필요하지 않습니다.
질문에서 설명한 것처럼 패키지 어셈블리를 수동으로 PowerShell 세션에 로드해야 합니다. 단, 의 경우.NET Core, 패키지에 서로 다른 DLL이 있을 수 있습니다.NET 환경에서 패키지 폴더의 모든 파일을 항상 맹목적으로 로드할 수는 없습니다.
패키지의 시스템 위치를 .
.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그런 점에서.NET 표준 DLL은 모두에서 실행됩니다.그러나 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 Standard 버전 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 }
파워셸 5를 사용하고 있습니까?이 경우 패키지 관리 모듈이 포함되어 있기 때문입니다.
오픈 소스인 것 같습니다. https://github.com/OneGet
언급URL : https://stackoverflow.com/questions/39257572/loading-assemblies-from-nuget-packages
'codememo' 카테고리의 다른 글
| 그루비와 함께 @값 스프링 주석 사용 (0) | 2023.09.05 |
|---|---|
| 드라이브 루트의 Set-Acl이 "객체"의 소유권을 설정하려고 하는 이유는 무엇입니까? (0) | 2023.09.05 |
| 플렉스 항목이 늘어나지 않도록 방지 (0) | 2023.08.31 |
| Swift를 사용하여 로케일을 프로그래밍 방식으로 변경하는 방법 (0) | 2023.08.31 |
| SELECT 문은 mariadb 10.0에서는 작동하지 않지만 mariadb 5.5에서는 작동합니다. (0) | 2023.08.31 |

