2009-08-20 141 views
1

我试图通过测试COM端口的'可打开性',然后启动一个对话窗口,允许用户做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返回E_ACCESSDENIED时,它只会在先前的CreateFile/CloseHandle调用后立即调用。

更糟糕的是,如果我在调试器中缓慢地逐步执行代码,它工作得很好。

看起来我需要在第一个closeHandle之后有一个Sleep(),但是这感觉像是一个黑客 - 我无法知道它必须持续多久。

+1

为什么不把手柄打开并传递给DoTheWork? – David 2009-08-20 16:19:18

+0

@大卫,我不想触摸系统的一个工作部分 - 但是,我现在没有选择;-) – Roddy 2009-08-20 16:28:54

回答

2

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

HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM 

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

+1

这表明我安装了哪些端口*,但它不会告诉我哪些是实际的可打开的(即,尚未由其他代码打开) – Roddy 2009-08-20 16:27:44

0

好了,经过更多的拖网,I found this,它涉及到Windows CE而不是Win32。

有一两秒钟的延迟后,该端口 被关闭,资源被释放之前 CloseHandle的调用。

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

+1

它可能与此相关 - 但是,在某些平台上,延迟的部分原因是缺少FlushFileBuffers()的可用性。 – sylvanaar 2009-08-20 17:27:01

1

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