问题 调试PowerShell cmdlet时出现问题


我在Windows 7 64位专业版上使用Visual Studio 2010。我在调试自定义PowerShell cmdlet时遇到问题。

组态

  • 语言:C#,面向.NET Framework 3.5 SP1。
  • 平台目标:任何CPU
  • 开始行动: C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe
  • 命令行参数: -noexit -command Add-PSSnapIn MyCustomSnapIn

问题1: 按F5时无法连接(调试→开始调试)

  • PowerShell打开,任务管理器指示powershell.exe作为64位进程运行。 “映像路径名称”列显示“开始操作”中指定的相同可执行文件。
  • 如果我在Visual Studio中选择Debug→Break All,我会收到一条消息“无法中断执行。此过程当前没有执行您选择调试的代码类型。”

问题2: 按Ctrl + F5时,意外启动为32位进程(Debug→Start Without Debugging)

  • PowerShell打开。任务管理器指示powershell.exe作为32位进程运行 - 这次映像路径名称显示SysWOW64重定向。

现在调试的烦人方法: 我发现调试cmdlet的唯一方法是按F5,然后选择Debug→Detach All,然后选择Debug→Attach To Process并重新附加Visual Studio。


6656
2017-07-25 17:50


起源

我想你可能想用 Image Path Name 任务管理器中的列,如果要查看 实际 涉及OS重定向时的EXE路径。 - Keith Hill
@Keith Hill:谢谢,我编辑说明#1没有重定向,但#2有重定向。 - Sam Harwell
@SamHarwell:你在VS 2017上解决了这个问题吗?我对VS 15.7.5有这个问题,但是说“烦人的方式”至少解决了我的问题,但有没有办法实际上不做“烦人的方式”? - Raniel Quirante


答案:


问题1:

在我看来像VS2010中的一个错误: https://connect.microsoft.com/VisualStudio/feedback/details/539389/debugging-powershell-cmdlet-from-vs-2010-does-not-stop-at-breakpoints?wa=wsignin1.0

使用VS2008应该有所帮助。

更新: 我发现 调试PowerShell cmdlet的更方便的方法。在解决方案资源管理器中,右键单击解决方案节点 - >添加 - >新建项目 - >选择powershell.exe文件(C:\ Windows \ SysWOW64 \ WindowsPowerShell \ v1.0 \ powershell.exe)。将新添加的项目设置为启动项目(右键单击并选择“设置为启动项目”)。然后转到项目属性(右键单击项目节点并选择“属性”)并将“调试器类型”属性设置为“托管(v2.0,v1.1,v1.0)”。不要忘记注册您的Provider或CmdLet(通过运行post build事件,请参阅 http://msdn.microsoft.com/en-us/library/ms714644%28v=vs.85%29.aspx)。现在,程序应该在断点处停止。


6
2017-07-27 15:01



+1 - 这确实是问题,谢谢你把它挖出来;不幸的是,现在似乎没有人感到有责任,因为他们无法理解最初的错误报告(以及随后的评论)。也许在微软有直接联系的人可能再碰到这个? - Steffen Opel
我添加了评论,澄清了repro案例。看来我的问题应该真正消除在MS上测试它的人和遇到它的人之间的混淆。 - Sam Harwell


问题#2,因为Visual Studio是在WOW64上运行的32位进程,所以路径 C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe 被重定向到 C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe。这是32位版本的PowerShell所在的位置。


2
2017-07-25 22:24



正如我所提到的,启动的实际路径已由任务管理器验证 system32, 不 下 SysWOW64。 - Sam Harwell
@ 280z28我认为你错过了一个微妙的观点,即启动路径是system32但是windows(不是powershell或vs)将请求重定向到syswo64,无声且透明。 - x0n
@ 280Z28 - 您正在查看“命令行”列或“图像路径名称”列吗?当我在VS 2010中尝试这个实验时,Ctrl + F5会激活命令行 C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe 但图像路径名称说 C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe。 - Keith Hill


我知道这个帖子大约有一年的时间了,但它可能会帮助其他人在这方面苦苦挣扎。

我发现以下场景适用于PowerShell 2.0。我也在Windows 7 64位上使用VS2010 SP1。

用PS 2.0你 不再 必须使用安装cmdlet installutil。相反,你可以使用 Import-Module 相反(确实如此)  需要管理员权限)。我不会详细介绍如何完成这项工作,因为网络搜索会显示大部分细节,但简而言之,您需要创建一个文件夹(如果它尚不存在):

md (Join-Path (Split-Path $profile) modules)

在modules文件夹下,创建另一个与cmdlet DLL同名的文件夹(减去“.DLL”)。此文件夹将包含您的二进制文件和描述您的DLL的psd1文件(请参阅 模块清单)。为方便起见,我创建了这个文件夹作为项目的bin \ debug文件夹的文件夹符号链接。

您仍然需要从Visual Studio运行PowerShell(或PowerShell ISE),如项目属性的“调试”选项卡的“开始操作”部分中的其他地方所述。

设置断点然后去。 PowerShell启动后,键入:

Import-Module <ModuleName>

然后运行cmdlet。


样品

C:\Users\<me>\Documents\WindowsPowerShell\modules\MyCmdlet\MyCmdlet.dll 
C:\Users\<me>\Documents\WindowsPowerShell\modules\MyCmdlet\MyCmdlet.pdb
C:\Users\<me>\Documents\WindowsPowerShell\modules\MyCmdlet\MyCmdlet.psd1
C:\Users\<me>\Documents\WindowsPowerShell\modules\MyCmdlet\MyCmdlet.Types.ps1xml (etc.)

在PowerShell类型中(也可以放在您的个人资料中):

Import-Module MyCmdlet

对我来说,这会触及我的所有断点,也会停止异常。所有这些都无需附加到流程等


2
2017-08-28 00:49





问题1:powershell.exe实际上不是托管可执行文件。它托管CLR本身,因此您需要启用本机代码调试以及托管服务才能工作。

至于问题2,我不确定这一点。显然VS本身是一个32位进程,所以它可能会干扰这里。


1
2017-07-25 22:06



关于#1:Visual Studio(devenv.exe)也不是托管可执行文件,但您不必为调试器启用本机代码调试以正确使用托管代码加载项。关于#2:Visual Studio调试其他64位二进制文​​件没有问题。这是我遇到的第一个问题。 - Sam Harwell
@ 280z28,是的但这些64位二进制文​​件是%systemroot%吗? - x0n
尝试使用特殊的%windir%\ sysnative路径启动powershell,例如启动%windir%\ sysnative \ windowspowershell \ 1.0 \ powershell.exe的路径以查看是否会抑制重定向。 - x0n
您不能在Visual Studio的“启动操作”中使用sysnative特殊文件夹。它给出一条消息,表明系统找不到指定的路径。 - Sam Harwell
@ 280z28真可惜。 - x0n


我能够通过创建文件夹来解决问题#2 C:\dev\PowerShell\x64 并复制一切 C:\Windows\System32\WindowsPowerShell\v1.0 进去。我创建了一个类似的文件夹 C:\dev\PowerShell\x86。当我指定这些路径时,PowerShell的预期版本总是启动,因此开始调试的最短方法是现在启动无调试,然后是附加到进程。


0
2017-07-26 13:31



所以你现在明白这是一个windows system32重定向,而不是一些powershell怪癖,对吧? - x0n
@ x0n:是的,但它仍然不允许我通过直接启动来调试代码。我必须使用Attach To Process。 - Sam Harwell
您还可以将脚本作为调试主机提升到对等项目中的system.management.automation中。像这样创建运行空间和测试cmdlet比修改完整的shell要容易得多。我在博客上写下了你需要的内容: nivot.org/2010/05/03/... - x0n


在调用Add-PSSnapin以使其在调试会话中可用之前,您没有提到如何安装插件。

确保使用安装插件 C:\Windows\Microsoft.NET\Framework64\v2.0.50727\InstallUtil.exe,而不是... \ Framework中的那个... - 这让我困扰了几天。


0
2017-08-20 19:34





我在VS2010上遇到了这个问题,但在安装SP1后它就消失了。


0
2017-10-21 17:50