问题
The CreateFile function is useful for opening files or devices for read/write access, providing a handle.
The third parameter, dwShareMode, specifies if the file/device can later be accessed by others. An example, with files:
void* pFileHandle1 = ::CreateFileA("C:\\test.txt", GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
DWORD lastError = GetLastError(); // 0, ERROR_SUCCESS
void* pFileHandle2 = ::CreateFileA("C:\\test.txt", GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
lastError = GetLastError(); // 0, ERROR_SUCCESS
All good here: we have 2 different handles that can read/write a single file.
But in my case, I want to use a COM port:
void* pComHandle1 = ::CreateFileA("\\\\.\\COM3", GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
lastError = GetLastError(); // 0, ERROR_SUCCESS
void* pComHandle2 = ::CreateFileA("\\\\.\\COM3", GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
lastError = GetLastError(); // 5, ERROR_ACCESS_DENIED Oops!
The first handle is valid and can be used, but the second one is INVALID_HANDLE_VALUE.
What's up with that? Can't you share COM ports that way?
回答1:
Quoting the documentation for CreateFile:
The
CreateFile
function can create a handle to a communications resource, such as the serial portCOM1
. For communications resources, thedwCreationDisposition
parameter must beOPEN_EXISTING
, thedwShareMode
parameter must be zero (exclusive access), and thehTemplateFile
parameter must beNULL
. Read, write, or read/write access can be specified, and the handle can be opened for overlapped I/O.
The implication from the documentation here is that communication objects cannot be shared like ordinary files. The Windows API leaves it to whoever opened the port to decide how/if they want to share access to that resource, and leaves them to manage the consequences of that decision.
To share the port, you can use DuplicateHandle
and pass that to whoever you want to grant access to the port after you've opened it. For further reading, check out this ancient article from MSDN
That said, if you want to share a COM port across multiple processes, you're better off opening it in only one of them, and using some form of IPC to transfer data. Let one process handle servicing the port.
来源:https://stackoverflow.com/questions/50215937/createfile-not-able-to-share-serial-com-port