为什么写入文件返回 false 且句柄无效



我随机遇到返回false的WriteFile(...(方法。当我调用 GetLastError(( 时,返回的值是 6。有谁知道导致此问题的原因?这是我的一些代码:

[DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool WriteFile(IntPtr hFile, byte[] lpBuffer,
    uint nNumberOfBytesToWrite, out uint lpNumberOfBytesWritten,
    IntPtr lpOverlapped);
public void Connect()
{
    IntPtr m_WriteHandleToUsbDevice = CreateFile(m_DevicePathName,
        GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING,
        0, IntPtr.Zero).DangerousGetHandle();
}
public void SendCommand()
{
    if (!WriteFile(m_WriteHandleToUsbDevice, command, bytesToWrite, out bytesToWrite, IntPtr.Zero))
    {
        uint lastError = GetLastError(); // lastError = 6
    }
}

我可以成功发送许多命令,但最终会在某个时候失败。我已经尝试了许多不同的 WriteFile 方法签名,但似乎没有一个可以解决这个问题(大多数只是将最后一个参数交换为 System.Threading.NativeOverlapped 结构(。许多类似的问题是由未初始化 NativeOverlapped 结构的事件属性引起的,但我尝试过但没有成功。以下是我尝试过的替代签名和逻辑之一:

[DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool WriteFile(IntPtr hFile, byte[] lpBuffer,
    uint nNumberOfBytesToWrite, out uint lpNumberOfBytesWritten,
    [In] ref NativeOverlapped lpOverlapped);
public void SendCommand()
{
    var ewh = new EventWaitHandle(false, EventResetMode.AutoReset);
    var unusedOutVariable = new NativeOverlapped {EventHandle = ewh.SafeWaitHandle.DangerousGetHandle()};
    if (!WriteFile(m_WriteHandleToUsbDevice, command, bytesToWrite, out bytesToWrite, IntPtr.Zero))
    {
        uint lastError = GetLastError(); // lastError = 6
    }
}

使用 DangerousGetHandle() 不会使文件保持打开状态。 在下一次垃圾回收器传递期间,SafeHandle对象将被检测为无法访问,并且将计划其终结器。 终结器将关闭句柄。 然后你的其他代码开始失败。 为什么您认为函数名称中有Dangerous一词?

SafeHandle实例保存在类成员数据中,而不是IntPtr 中。

最新更新