11

我在 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 位进程运行。Image Path Name 列显示在 Start Action 中指定的相同可执行文件。
  • 如果我在 Visual Studio 中选择“调试”→“全部中断”,我会收到一条消息“无法中断执行。此进程当前未执行您选择调试的代码类型。”

问题 2:当我按 Ctrl+F5 时意外启动为 32 位进程(调试 → 不调试启动)

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

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

4

7 回答 7

6

问题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(通过运行构建后事件,请参阅http://msdn.microsoft.com/en-us/library/ms714644%28v=vs.85%29.aspx)。现在,程序应该在断点处停止。

于 2010-07-27T15:01:51.937 回答
2

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

于 2010-07-25T22:24:59.367 回答
2

我知道这个帖子在这一点上已经有一年了,但无论如何它可能会帮助其他人在这个问题上挣扎。

我发现以下方案适用于 PowerShell 2.0。我还在 Windows 7 64 位上使用 VS2010 SP1。

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

md (Join-Path (Split-Path $profile) 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

对我来说,这会击中我所有的断点,并且还会在异常时停止。所有这些都无需附加到进程等。

于 2011-08-28T00:49:18.413 回答
1

问题 1:powershell.exe 实际上不是托管可执行文件。它托管 CLR 本身,因此您需要在托管的同时启用本​​机代码调试才能使其正常工作。

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

于 2010-07-25T22:06:46.260 回答
0

我能够通过创建文件夹C:\dev\PowerShell\x64并将所有内容复制C:\Windows\System32\WindowsPowerShell\v1.0到其中来解决问题 #2。我创建了一个类似的文件夹C:\dev\PowerShell\x86。当我指定这些路径时,PowerShell 的预期版本总是会启动,因此现在开​​始调试的最短方法是 Start without Debugging,然后是 Attach To Process。

于 2010-07-26T13:31:00.073 回答
0

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

于 2011-10-21T17:50:43.123 回答
0

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

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

于 2010-08-20T19:34:17.757 回答