调试/卸载PowerShell Cmdlet

时间:2016-03-10 13:20:18

标签: c# visual-studio powershell

我正在使用Visual Studio 2015在C#中编写PowerShell Cmdlet。调试它工作正常,但在关闭PowerShell窗口之前我无法重建DLL。 DLL似乎正在使用中,因此无法删除(不在命令行上,也不能使用资源管理器)。我试过删除模块。这成功删除了我的Cmdlet,但我仍然无法删除/覆盖它。

关闭PowerShell,重建DLL然后重新打开一个新的PowerShell,cd到DLL路径(通常是深层嵌套),再次重新导入它,启动命令调试等等,这是非常不方便的。调试会话......

卸载DLL有没有更好的解决方案?

4 个答案:

答案 0 :(得分:6)

任何时候我都会看到这样的事情:

  

关闭powershell,重建dll然后重新打开一个新的PowerShell,cd到dll路径(通常是深层嵌套),再次重新导入它,启动命令首次亮相等等,这是非常不方便的。单个调试会话......

我立刻想到,“我应该为我创建一个脚本来完成这些任务”。

有解决方案。您可以启动第二个PowerShell(如建议的另一个答案)。另一种解决方案是使用脚本为您完成一些工作,最重要的是,您可以将其添加到VS项目中。

在个人资料中创建一个脚本以启动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,使用 F5 启动调试器,你有一个新的PowerShell窗口加载了你的Cmdlet,你可以随意调试它。

使用任何PowerShell窗口中的“sdp”别名

由于Start-DebugPowerShell函数位于我们的配置文件中,并且我们为其指定了别名sdp,因此您可以随时使用它来启动PowerShell的第二个实例。

答案 1 :(得分:1)

据我所知,恐怕你对这种行为无能为力。一个技巧是在加载DLL之前立即在现有会话中启动新的PowerShell会话。然后你可以退出第二个,你有一个全新的没有加载DLL。只需记住在再次加载之前启动一个新的“辅助”会话,以防您需要再次卸载它。

答案 2 :(得分:1)

我使用了helper powershell script来替我完成大部分任务。

    $module = 'AccessLogParser'
    Push-Location $PSScriptroot

    dotnet build -o $PSScriptRoot\output\$module\bin
    Import-Module "$PSScriptRoot\Output\$module\bin\$module.dll"
    $VerbosePreference = $DebugPreference="continue"
    Write-Debug "$pid - $($PSVersionTable.PSVersion)"

在启动配置中有两个选项,帮助程序输出当前正在运行终端进程(vscode的底部)的进程ID,启动调试器时,我可以在下拉列表中选择该PID。当您想为旧的v5 powershell和v7(pwsh.exe)版本开发某些东西时很有帮助。

 {
            "name": ".NET Framework Attach",
            "type": "clr",
            "request": "attach",
            "processId": "${command:pickProcess}"
        },
        {
            "name": ".NET Core Attach",
            "type": "coreclr",
            "request": "attach",
            "processId": "${command:pickProcess}"
        }

答案 3 :(得分:0)

https://docs.microsoft.com/en-us/powershell/scripting/dev-cross-plat/vscode/using-vscode-for-debugging-compiled-cmdlets上完全针对pwsh和powershell.exe进行了文档-此文档讨论了DLL锁定问题/ edit>

要添加到@ kory-gill的答案中,这是我的launch.json:

{
    "name": ".NET Core Launch (console)",
    "type": "coreclr",
    "request": "launch",
    "preLaunchTask": "build",
    "cwd": "${workspaceFolder}",
    "program": "pwsh",
    "args": [
        "-NoExit",
        "-NoProfile",
        "-Command",
        "ipmo ${workspaceFolder}/DependencyTree/bin/Debug/netstandard2.0/DependencyTree.dll",
    ],
    "console": "integratedTerminal",
    "stopAtEntry": false
}

我的项目称为DependencyTree。替换您自己的项目名称。

-NoProfile对我来说很重要,因为我的个人资料很大并且破坏了调试器。

更一般地说,我设置了PSReadline,您也应该,以在终端会话中保留历史记录。因此,我可以Ctrl-R并召唤我输入的很长一段时间的任何命令。通过配置,在与编译类或Powershell类进行交互工作时以及与模块的未导出成员一起工作时,以下内容将非常有用:

  1. 使用键盘快捷键创建和删除终端。在VS Code中,端子应视为一次性使用。
  2. $host.ExitNestedPrompt(); $Module = ipmo .\DependencyTree.psd1 -Force -PassThru; & $Module {$host.EnterNestedPrompt()}

& $Module { ... }技巧在模块范围内运行该脚本块。对向导非常有用;-)