programing

파워셸 언로드 모듈...완전히.

i4 2023. 7. 25. 20:26
반응형

파워셸 언로드 모듈...완전히.

파워셸 프로젝트를 디버깅하는 중입니다.는 중용사를 합니다.Import-Module내 C# dll에서 PS 모듈을 로드하고 모든 것이 정상적으로 작동합니다.하기 르기Remove-ModuleDLL이 여전히 잠겨 있으므로 삭제할 수 없기 때문에 모듈을 완전히 언로드하지 않습니다.

하고 PSH를 사용하여 할 수 ?Import-ModulePSH 콘솔을 다시 시작하지 않고?


모듈을 별도의 AppDomain에 로드해도 일반 모듈처럼 작동합니까?예를 들어줄 수 있는 사람이 있습니까?

해결 방법이 있습니다.PowerShell의 다른 인스턴스를 엽니다.

PS > powershell
PS > [load DLL]
PS > [do work]
PS > exit

(PowerShell에서 PowerShell을 한 것으로 ).powershell호출(PowerShell의 내부 및 인스턴스).여러분은 일반적인 중 를 인에수있습다니전에 할 수 .powershell 또는할 수 . 예 파일 -파일을 사용합니다. 예:

PS > powershell -Command '[load DLL]; [do work]' # Executes a command and exits
PS > powershell -Command '.\myscript.ps1 param1 param2' # Executes the script and exits
PS > powershell -File .\myscript.ps1 param1 param2 # Executes a script and exits.

PowerShell이 종료되면 DLL의 잠금이 해제되어 작업을 계속할 수 있습니다.

이 모든 작업은 PowerShell 명령줄 인터페이스에서 수행되었습니다.당신이 던지면 어떻게 되는지 테스트해본 적이 없습니다.powershell스크립트 중간 또는 ISE 내에서 작동하는지 여부. (ISE 내에서 작동하는지 의심됩니다.)스크립트 내에서 작동하지 않는 경우에도 개발 중에는 유용합니다.

편집:

확인 좀 했습니다.이것은 스크립트 내에서나 ISE에서나 잘 작동하는 것처럼 보이지만, ISE 내에서는 경고가 있습니다.ISE에서는 별도의 PowerShell 프로세스 내에서 사용자의 입력을 읽을 수 없습니다.시도하면 스크립트 또는 명령이 중지되어 대기하지만 정상처럼 입력 상자가 표시되지 않으며, 물론 ISE의 출력 창에 직접 입력할 수 없습니다. 할 에는 입력을 해야 합니다.[do work]새 PowerShell 인스턴스를 시작하기 전에 프롬프트를 표시하고 이를 매개 변수로 작업에 전달합니다.일반 PowerShell 명령줄을 사용하는 경우 이러한 문제는 전혀 발생하지 않습니다.

아니요. PowerShell에서 사용하는 것처럼.그 아래에 있는 NET도 동일한 요구사항을 가지고 있습니다.에서 dll을 언로드할 수 없습니다.AppDomain 자체를 언로드하지 않고 NET AppDomain을 실행할 수 있습니다.PowerShell UI가 동일한 AppDomain에 있으므로 이 작업은 불가능합니다.

여기에 몇 가지 실행 가능한 답변이 있지만, 이것은 누군가에게 여전히 문제가 될 경우를 대비하여 제 것입니다(그리고 이것은 꽤 게으르고 좋은 답변입니다).

Enter-PSSession -localcomputername
[load dlls]
[execute script(s)]
Exit-PSSession

간단히 말해서 로컬 컴퓨터에 대한 PS 세션을 만들면 "로드된" 것으로 간주되는 것을 포함하여 다른 파워셸 세션이 생성되고 종료 시 정리됩니다.

Cmdlet 개발 및 DLL 언로드 문제와 관련하여 제가 사용하는 두 가지 접근 방식이 있습니다.

먼저 Visual Studio에서 개발하고 외부 프로그램(PowerShell)을 설정하여 Cmdlet을 로드합니다.이렇게 하면 디버깅을 시작할 때 모듈이 로드되고 디버깅을 중지할 때 모듈이 언로드됩니다.

둘째, 모듈을 로드하고 작업을 수행한 후 모듈이 언로드되었는지 확인하는 경우 PowerShell의 두 번째 인스턴스를 사용합니다.이것은 다른 답변에서 논의되었으며, 아래의 답변은 프로파일에 별칭이 있는 함수를 사용하여 이 워크플로우를 활성화하는 방법을 보여줍니다.프롬프트를 변경하여 "재귀적 PowerShell 창"에 있음을 시각적으로 알릴 수 있습니다.

프로파일에 PowerShell을 시작하는 스크립트 생성

function Start-DebugPowerShell
{
    PowerShell -NoProfile -NoExit -Command {
        function prompt {
            $newPrompt = "$pwd.Path [DEBUG]"
            Write-Host -NoNewline -ForegroundColor Yellow $newPrompt
            return '> '
        }
    }
}
Set-Alias -Name sdp -Value Start-DebugPowerShell

Cmdlet 프로젝트의 디버그 설정 편집

외부 프로그램 시작:

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe

명령줄 인수:

-NoProfile -NoExit -Command "Import-Module .\MyCoolCmdlet.dll"

모듈 디버그

이제 Visual Studio에서 에서 디버거를 시작하면 Cmdlet이 로드된 새 PowerShell 창이 열리며 원하는 대로 디버그할 수 있습니다.

PowerShell 창에서 'sdp' 별칭 사용

Start-Debug PowerShell이라는 .sdp필요할 때 언제든지 PowerShell의 두 번째 인스턴스를 시작할 수 있습니다.

PowerShell:.sk PowerShell에 합니다. NET에 입니다.AppDomain이 어블리로면에 AppDomain그것은 그것의 평생 동안 적재된 상태로 남아 있습니다.AppDomain.


다음은 스레드에서 거의 동일한 질문을 하고 모듈을 생성하여 새 AppDomain에 로드하는 몇 가지 방법을 보여주는 예입니다.

http://www.eggheadcafe.com/conversation.aspx?messageid=30789124&threadid=30766269

저는 같은 문제를 겪었고 결국 로드하고 싶은 DLL을 명령줄 exe 안에 포장했고 스크립트에서 호출했습니다.그런 식으로 저는 애플리케이션 내에서 DLL을 로드하는 것을 전혀 피했습니다.

저는 대상 DLL의 이름을 바꾸고 모듈로 로드하는 간단한 스크립트를 사용합니다.여기 두 개의 해킹이 있습니다.

  1. .net 어셈블리 개체에서 모듈을 로드할 때 "dynamic_code_module_FirstPowershellModule"이라는 이름의 모듈을 로드했습니다.
  2. 그래서 가져오기 전에 이 모듈을 언로드하고 이름이 바뀐 파일에서 새 모듈을 만듭니다.

이전 어셈블리가 도메인에서 사용되지 않은 상태로 유지됨

각 프로젝트 재구축 후 스크립트를 실행해야 합니다.

Get-Module -Name "*FirstPowershellModule*" | Remove-Module
$ii++
$destPath = "D:\Dev\FirstPowershellModule\FirstPowershellModule\bin\Debug\FirstPowershellModule" + $ii+ ".dll"
Copy-Item D:\Dev\FirstPowershellModule\FirstPowershellModule\bin\Debug\FirstPowershellModule.dll -Destination $destPath
$ass = [System.Reflection.Assembly]::LoadFile($destPath)
import-module -Assembly $ass

DLL의 복사본을 만들고 해당 복사본을 로드합니다.DLL을 다시 로드할 수 있습니다.

은 .입니다. 모듈은 . 어셈블리입니다Import-ModulePowerShell 호스트(애플리케이션)의 AppDomain에 로드합니다.Remove-Module현재 세션에서 모듈만 제거합니다.

msdn에 따르면, http://msdn.microsoft.com/en-us/library/ms173101(v=vs.80).aspx

개별 어셈블리를 포함하는 모든 응용 프로그램 도메인을 언로드하지 않고는 개별 어셈블리를 언로드할 수 없습니다.AppDomain에서 언로드 방법을 사용하여 애플리케이션 도메인을 언로드합니다.자세한 내용은 응용프로그램 도메인 언로드를 참조하십시오.

새 AppDomain에서 새 PowerShell 호스트를 시작하고 모듈을 호스트로 가져온 다음 PowerShell 작업을 수행할 수 있습니다.모듈은 이전 호스트에서 실행된 것과 동일하게 정상입니다.유일한 차이점은 다른 AppDomain에서 실행되는 호스트에 있다는 것입니다.

외부 모듈(ImportExcel)이 있어서 이렇게 업데이트하고 싶었지만 작동하지 않았습니다.이 경우(사용자 모듈 폴더에 있는 경우), 그렇지 않은 경우에는-Scope ... workedparam) 입니다.

(내부적으로 어떻게 관리했는지는 모르겠지만 현재 PS 세션을 유지하고 있습니다.)

언급URL : https://stackoverflow.com/questions/1337961/powershell-unload-module-completely

반응형