使用Windows API配置串行端口:CreateFile失败,错误2(ERROR_FILE_NOT_FOUND)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Windows API配置串行端口:CreateFile失败,错误2(ERROR_FILE_NOT_FOUND)相关的知识,希望对你有一定的参考价值。

我正在尝试创建一个C ++程序,以便在Windows 7的Visual Studio社区2017中使用Windows API与串行端口设备进行通信。从MSDN运行this示例,只需更改一次 - 使用此代码:

const wchar_t *pcCommPort = TEXT("\.COM16"); //  Most systems have a COM1 port

而不是这个(否则它不会编译):

TCHAR *pcCommPort = TEXT("COM1"); //  Most systems have a COM1 port

我得到一个CreateFile错误2(ERROR_FILE_NOT_FOUND)。我很不知道这里出了什么问题。

这是代码:

#include "stdafx.h"

void PrintCommState(DCB dcb)
{
    //  Print some of the DCB structure values
    _tprintf(TEXT("
BaudRate = %d, ByteSize = %d, Parity = %d, StopBits = %d
"),
        dcb.BaudRate,
        dcb.ByteSize,
        dcb.Parity,
        dcb.StopBits);
}


int _tmain(int argc, TCHAR *argv[])
{
    DCB dcb;
    HANDLE hCom;
    BOOL fSuccess;
    const wchar_t *pcCommPort = TEXT("\.COM16"); //  Most systems have a COM1 port

                                      //  Open a handle to the specified com port.
    hCom = CreateFile(pcCommPort,
        GENERIC_READ | GENERIC_WRITE,
        0,      //  must be opened with exclusive-access
        NULL,   //  default security attributes
        OPEN_EXISTING, //  must use OPEN_EXISTING
        0,      //  not overlapped I/O
        NULL); //  hTemplate must be NULL for comm devices

    if (hCom == INVALID_HANDLE_VALUE)
    {
        //  Handle the error.
        printf("CreateFile failed with error %d.
", GetLastError());
        system("PAUSE");
        return (1);
    }

    //  Initialize the DCB structure.
    SecureZeroMemory(&dcb, sizeof(DCB));
    dcb.DCBlength = sizeof(DCB);

    //  Build on the current configuration by first retrieving all current
    //  settings.
    fSuccess = GetCommState(hCom, &dcb);

    if (!fSuccess)
    {
        //  Handle the error.
        printf("GetCommState failed with error %d.
", GetLastError());
        return (2);
    }

    PrintCommState(dcb);       //  Output to console

                               //  Fill in some DCB values and set the com state: 
                               //  57,600 bps, 8 data bits, no parity, and 1 stop bit.
    dcb.BaudRate = CBR_9600;     //  baud rate
    dcb.ByteSize = 8;             //  data size, xmit and rcv
    dcb.Parity = NOPARITY;      //  parity bit
    dcb.StopBits = ONESTOPBIT;    //  stop bit

    fSuccess = SetCommState(hCom, &dcb);

    if (!fSuccess)
    {
        //  Handle the error.
        printf("SetCommState failed with error %d.
", GetLastError());
        return (3);
    }

    //  Get the comm config again.
    fSuccess = GetCommState(hCom, &dcb);

    if (!fSuccess)
    {
        //  Handle the error.
        printf("GetCommState failed with error %d.
", GetLastError());
        return (2);
    }

    PrintCommState(dcb);       //  Output to console

    _tprintf(TEXT("Serial port %s successfully reconfigured.
"), pcCommPort);
    return (0);
}
答案

two different defines控制ANSI / Unicode字符的东西:

#define UNICODE控制Windows SDK API(LPTSTRTEXT

#define _UNICODE控制C运行时间(TCHAR_TEXT_T

您通常不会定义任何一个或两个,如果不这样做,则必须使用正确的组合:

const TCHAR* cstr = _T("Hello");
LPCTSTR winstr = TEXT("World");

您的代码的另一个问题是您使用的是TCHAR*而不是const TCHAR*。根据您的编译器版本和开关,文字字符串可能位于二进制文件的只读数据部分中,因此请确保该类型是指向常量字符串的指针。

如果您仍然不确定尺寸,可以这样做:

LPCTSTR x;
printf("TEXT=%d LPCTSTR=%d _T=%d TCHAR=%d
", sizeof(TEXT("")), sizeof(*x), sizeof(_T("")), sizeof(TCHAR));

我刚刚在带有COM端口的虚拟机上进行了测试,并且普通名称工作正常:

LPCTSTR pcCommPort = TEXT("COM1"); 
HANDLE hCom = CreateFile(pcCommPort,
        GENERIC_READ | GENERIC_WRITE,
        0,      //  must be opened with exclusive-access
        NULL,   //  default security attributes
        OPEN_EXISTING, //  must use OPEN_EXISTING
        0,      //  not overlapped I/O
        NULL); //  hTemplate must be NULL for comm devices

如果你想使用COM port above 9,你必须使用Win32 device path语法:

LPCTSTR pcCommPortWin32DevicePath = TEXT("\\.\COM16"); 
HANDLE hCom = CreateFile(pcCommPortWin32DevicePath, ...);

(MSDN描述了它应该在内存中查找的字符串,而不是代码中的字符串。您对此的线索是示例字符串中的单斜杠。这意味着您必须将所有反斜杠加倍才能获得正确的C字符串。)

另一答案

你需要在字符串文字中转义反斜杠,例如

const TCHAR *pcCommPort = TEXT("\\.\COM16");

以上是关于使用Windows API配置串行端口:CreateFile失败,错误2(ERROR_FILE_NOT_FOUND)的主要内容,如果未能解决你的问题,请参考以下文章

如何正确使用 COMMTIMEOUTS 和从串行端口读取的 OVERLAPPED IO 模式

Windows Server 2008 上的串行端口问题

在 Windows 批处理中获取串行 com 端口描述

具有多个事件的连续串行端口读取

在 C 中获取 Windows 串行端口的输入缓冲区长度

在Windows批处理中获取串行com端口描述