我正在使用Visual Studio 2015在C#中编写PowerShell Cmdlet。调试它工作正常,但在关闭PowerShell窗口之前我无法重建DLL。 DLL似乎正在使用中,因此无法删除(不在命令行上,也不能使用资源管理器)。我试过删除模块。这成功删除了我的Cmdlet,但我仍然无法删除/覆盖它。
关闭PowerShell,重建DLL然后重新打开一个新的PowerShell,cd到DLL路径(通常是深层嵌套),再次重新导入它,启动命令调试等等,这是非常不方便的。调试会话......
卸载DLL有没有更好的解决方案?
答案 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)
要添加到@ 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类进行交互工作时以及与模块的未导出成员一起工作时,以下内容将非常有用:
$host.ExitNestedPrompt(); $Module = ipmo .\DependencyTree.psd1 -Force -PassThru; & $Module {$host.EnterNestedPrompt()}
& $Module { ... }
技巧在模块范围内运行该脚本块。对向导非常有用;-)