我有一些代码,使用P/Invoke启动进程并捕获标准输出。 (为什么要使用P/Invoke而不是
然而,今天早上我运行测试时,它们失败了。我无法确定上次运行测试的确切时间(5/15/2014),但我认为是4/24/2014。当时测试通过了,但今天早上测试失败了。我收到了“PInvokeStackImbalance”错误消息,因此我进行了一些研究,最终意识到
我很高兴找到了解决方法,但我对部署感到担忧。为什么结构体的签名会发生变化呢?我没有升级我的操作系统或其他任何东西 - 我在4/24上运行的是Windows 7 x64,现在仍然在运行。 (部署环境是Windows Server 2012。)自那以后,我安装(和卸载)了一些轻量级的第三方工具,而不是Microsoft或系统组件。我认为Windows更新的热补丁应该是原因,但我无法确定是哪一个。
明确地说,在我的代码中,我仅更改了这个:
System.Diagnostics.Process
的故事很长而且复杂;可以说这是一个要求。)它在生产环境下高负载下运行了将近一年,并且测试始终通过。然而,今天早上我运行测试时,它们失败了。我无法确定上次运行测试的确切时间(5/15/2014),但我认为是4/24/2014。当时测试通过了,但今天早上测试失败了。我收到了“PInvokeStackImbalance”错误消息,因此我进行了一些研究,最终意识到
extern
方法(在这种情况下是CreatePipe
)使用的某个结构体的签名不正确。我更改了它,然后测试又开始通过了。我很高兴找到了解决方法,但我对部署感到担忧。为什么结构体的签名会发生变化呢?我没有升级我的操作系统或其他任何东西 - 我在4/24上运行的是Windows 7 x64,现在仍然在运行。 (部署环境是Windows Server 2012。)自那以后,我安装(和卸载)了一些轻量级的第三方工具,而不是Microsoft或系统组件。我认为Windows更新的热补丁应该是原因,但我无法确定是哪一个。
明确地说,在我的代码中,我仅更改了这个:
[StructLayout(LayoutKind.Sequential)]
public struct SECURITY_ATTRIBUTES
{
public UInt32 nLength;
public IntPtr lpSecurityDescriptor;
public bool bInheritHandle;
}
转换为:
[StructLayout(LayoutKind.Sequential)]
internal class SECURITY_ATTRIBUTES
{
public int nLength = 12;
public IntPtr lpSecurityDescriptor = IntPtr.Zero;
public bool bInheritHandle;
}
我需要确保我在本地机器上使代码工作的更改不会在部署到生产环境时导致应用程序出现故障。有人知道如何确定什么需要这种更改以及如何确定生产环境是否需要它吗?
编辑:
以下是打开标准输出管道的代码:
private PipeInfo CreatePipe()
{
PipeInfo pipeInfo = new PipeInfo();
SafeFileHandle safeFileHandle = null;
try
{
Native.SECURITY_ATTRIBUTES pipeAttributes = new Native.SECURITY_ATTRIBUTES();
pipeAttributes.bInheritHandle = true;
if (!Native.CreatePipe(out safeFileHandle, out pipeInfo.ChildHandle, pipeAttributes, 0) || safeFileHandle.IsInvalid || pipeInfo.ChildHandle.IsInvalid)
{
throw new Win32Exception();
}
if (!Native.DuplicateHandle(new HandleRef(this, Native.GetCurrentProcess()), safeFileHandle, new HandleRef(this, Native.GetCurrentProcess()), out pipeInfo.ParentHandle, 0, false, 2))
{
throw new Win32Exception();
}
}
finally
{
if (safeFileHandle != null && !safeFileHandle.IsInvalid)
{
safeFileHandle.Close();
}
}
return pipeInfo;
}
这段代码并非完全由我编写,我主要是从.NET Reference Source中借鉴的。
时间线如下:
- 2013年5月 - 编写了
CreatePipe
代码,第一个版本的SECURITY_ATTRIBUTES
- 2013年6月 - 部署;代码从那时起一直成功运行
- 2014年4月 - 没有进行任何更改,代码开始抛出堆栈不平衡错误
- 2014年5月 - 我更改为第二个版本的
SECURITY_ATTRIBUTES
,错误消失了
Marshal.SizeOf
。我猜你在代码中改变了其他东西。请查看您的修订控制历史记录以找出原因。 - David HeffernanSizeOf
。) - nateirvinnLength
不再设置为默认值,因此我必须在我的代码中执行它,这可能更好。 - nateirvin