关闭并立即重新打开 COM 端口失败:为什么?

发布于 2024-08-02 15:08:47 字数 820 浏览 5 评论 0原文

我试图通过在启动允许用户执行 com-porty 操作的对话框窗口之前测试 COM 端口的“可打开性”来进行“飞行前检查”。

下面是代码序列的概述:

handle = CreateFile("\\\\.\\COM4:", GENERIC_READ | GENERIC_WRITE, 0,NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED,NULL);

if (handle != INVALID_HANDLE_VALUE)
{
  CloseHandle(handle);
  DoTheWork("\\\\.\\COM4:");
}
else
{ 
  ShowMessage("I'm sorry Dave, I can't do that"); 
} 

...

void DoTheWork(char * port)
{
  handle = CreateFile(port, GENERIC_READ | GENERIC_WRITE, 0,NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED,NULL);
  /// do lots of stuff
  CloseHandle(port);
}

问题是:“DoTheWork”是一个经过尝试和测试的函数,并且它自己可以正确执行。仅当在先前的 CreateFile/CloseHandle 调用之后立即调用且第二个 CreateFile 返回 E_ACCESSDENIED 时,它才会失败。

更糟糕的是,如果我在调试器中慢慢地单步执行代码,它就可以正常工作。

似乎我在第一个 closeHandle 之后需要一个 Sleep() ,但这感觉就像一个黑客 - 我无法知道它必须有多长。

I'm trying to do 'pre-flight checks' by testing a COM port's 'openability' before launching a dialog window which allows the user to do com-porty things.

Here's the code sequence, in outline:

handle = CreateFile("\\\\.\\COM4:", GENERIC_READ | GENERIC_WRITE, 0,NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED,NULL);

if (handle != INVALID_HANDLE_VALUE)
{
  CloseHandle(handle);
  DoTheWork("\\\\.\\COM4:");
}
else
{ 
  ShowMessage("I'm sorry Dave, I can't do that"); 
} 

...

void DoTheWork(char * port)
{
  handle = CreateFile(port, GENERIC_READ | GENERIC_WRITE, 0,NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED,NULL);
  /// do lots of stuff
  CloseHandle(port);
}

Here's the problem: "DoTheWork" is a tried and tested function, and performs correctly on it's own. It only fails when called immediately after the earlier CreateFile/CloseHandle calls, when the second CreateFile returns E_ACCESSDENIED.

Worse yet, if I step through the code slowly in the debugger, It works just fine.

It seems like I need a Sleep() after the first closeHandle, but that feels like a hack - and i have no way of knowing how long it must be.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

生寂 2024-08-09 15:08:47

系统需要一些时间来关闭资源。可能有一些神秘的方法来测试它是否已被释放,但我不知道那是什么。我所知道的是,如果您检查注册表项:

HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM

您将看到哪些串行端口可用,而无需打开它们,这应该可以解决您的问题。

The system takes a bit of time to close the resource. There's probably some arcane way to test whether it's been freed, but I don't know what that is. What I do know is that if you check the registry key:

HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM

You'll see which serial ports are available without having to open them, which should solve your problem.

风追烟花雨 2024-08-09 15:08:47

在关闭句柄之前尝试调用 PurgeComm() 或 FlushFileBuffers()。

Try calling PurgeComm() or FlushFileBuffers() on the handle before closing it.

前事休说 2024-08-09 15:08:47

好吧,经过更多的搜寻,我发现了这个,它涉及 Windows CE 而不是 Win32。

之后有两秒的延迟
CloseHandle 在端口之前调用
已关闭并释放资源。

我想这同样适用于 Win32,但我还没有找到任何记录证明。

Well, after more trawling, I found this, which relates to Windows CE rather than Win32.

There is a two-second delay after
CloseHandle is called before the port
is closed and resource are freed.

I guess the same applies to Win32, but I haven't found any documented proof.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文