C: Windows 没有找到 HARDWARE\DEVICEMAP\SERIALCOMM 即使它可以使用 regedit 找到
C: Windows not finding HARDWARE\DEVICEMAP\SERIALCOMM even though it can be found using regedit
我想列出 COM 端口(就像在 'Device Manager' 中看到的那样),但是在运行时。
我厚颜无耻地复制了this site的代码(代码显示在post的末尾),我想我明白了。然而,程序在第 36 行失败,给我错误:
Failed to open key 'HARDWARE\DEVICEMAP\SERIALCOMM'
Windows reports error: (0x00000002): The system cannot find the file specified.
如果我打开注册表编辑器,我会清楚地看到该文件夹,当我单击它时,我会看到我已连接到我的计算机的设备。
我使用 MinGW 和命令 gcc filename.c
编译了代码
关于如何解决这个问题有什么想法吗?可能是权限问题? gcc 是否需要一些编译器标志才能让我使用它?
我运行的代码是这样的:
#define WIN32_LEAN_AND_MEAN // excludes stuff frokm windows.h that we won't need here.
#include <Windows.h>
#include <string.h>
#include <tchar.h>
#include <malloc.h>
void ShowErrorFromLStatus(LSTATUS lResult)
{
LPTSTR psz;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
lResult,
0,
(LPTSTR)&psz,
1024,
NULL);
_tprintf(_T("Windows reports error: (0x%08X): %s\n"), lResult, (psz) ? psz : _T("(null)"));
if (psz)
{
LocalFree(psz);
}
}
int main()
{
DWORD nValues, nMaxValueNameLen, nMaxValueLen;
HKEY hKey = NULL;
LPTSTR szDeviceName = NULL;
LPTSTR szFriendlyName = NULL;
DWORD dwType = 0;
DWORD nValueNameLen = 0;
DWORD nValueLen = 0;
DWORD dwIndex = 0;
LSTATUS lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"HARDWARE\DEVICEMAP\SERIALCOMM", 0, KEY_READ, &hKey);
if (ERROR_SUCCESS != lResult)
{
printf("Failed to open key \'HARDWARE\DEVICEMAP\SERIALCOMM\' \n");
ShowErrorFromLStatus(lResult);
return 1;
}
lResult = RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL,
&nValues, &nMaxValueNameLen, &nMaxValueLen, NULL, NULL);
if (ERROR_SUCCESS != lResult)
{
_tprintf(_T("Failed to RegQueryInfoKey()\n"));
ShowErrorFromLStatus(lResult);
RegCloseKey(hKey);
return 2;
}
szDeviceName = (LPTSTR)malloc(nMaxValueNameLen + sizeof(TCHAR));
if (!szDeviceName)
{
_tprintf(_T("malloc() fail\n"));
RegCloseKey(hKey);
return 3;
}
szFriendlyName = (LPTSTR)malloc(nMaxValueLen + sizeof(TCHAR));
if (!szFriendlyName)
{
free(szDeviceName);
_tprintf(_T("malloc() fail\n"));
RegCloseKey(hKey);
return 3;
}
_tprintf(_T("Found %d serial device(s) registered with PnP and active or available at the moment.\n"), nValues);
for (DWORD dwIndex = 0; dwIndex < nValues; ++dwIndex)
{
dwType = 0;
nValueNameLen = nMaxValueNameLen + sizeof(TCHAR);
nValueLen = nMaxValueLen + sizeof(TCHAR);
lResult = RegEnumValueW(hKey, dwIndex,
szDeviceName, &nValueNameLen,
NULL, &dwType,
(LPBYTE)szFriendlyName, &nValueLen);
if (ERROR_SUCCESS != lResult || REG_SZ != dwType)
{
_tprintf(_T("SerialPortEnumerator::Init() : can't process registry value, index: %d\n"), dwIndex);
ShowErrorFromLStatus(lResult);
continue;
}
_tprintf(_T("Found port \'%s\': Device name for CreateFile(): \'\.%s\'\n"), szFriendlyName, szDeviceName);
}
free(szDeviceName);
free(szFriendlyName);
RegCloseKey(hKey);
return 0;
}
编辑
我现在用 _T("HARDWARE\DEVICEMAP\SERIALCOMM")
调用 RegOpenKeyEx
,在第 81 行对 RegEnumValueW 的调用中,我将 szDeviceName
转换为 LPWSTR
。 gcc 不再给出任何错误或警告。但是,当运行程序出来的时候,都是
Found 1 serial device(s) registered with PnP and active or available at the moment.
Found port 'C': Device name for CreateFile(): '\.\'
而且我连接的端口(COM3)没有显示。
还有其他建议吗?
感谢Simon Mourier and Ian Abbott!
如编辑中所述,使用 _T("HARDWARE\DEVICEMAP\SERIALCOMM")
调用 RegOpenKeyEx
并将 szDeviceName
转换为 LPWSTR
修复了所有错误。
此外,在第 92 行对 _tprintf()
的调用中使用标识符 %ls
使名称打印正确。
最终的工作代码如下所示:
#define WIN32_LEAN_AND_MEAN // excludes stuff frokm windows.h that we won't need here.
#include <Windows.h>
#include <string.h>
#include <tchar.h>
#include <malloc.h>
#include <stdio.h>
void ShowErrorFromLStatus(LSTATUS lResult)
{
LPTSTR psz;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
lResult,
0,
(LPTSTR)&psz,
1024,
NULL);
_tprintf(_T("Windows reports error: (0x%08X): %s\n"), lResult, (psz) ? psz : _T("(null)"));
if (psz)
{
LocalFree(psz);
}
}
int main()
{
DWORD nValues, nMaxValueNameLen, nMaxValueLen;
HKEY hKey = NULL;
LPTSTR szDeviceName = NULL;
LPTSTR szFriendlyName = NULL;
DWORD dwType = 0;
DWORD nValueNameLen = 0;
DWORD nValueLen = 0;
DWORD dwIndex = 0;
LSTATUS lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("HARDWARE\DEVICEMAP\SERIALCOMM"), 0, KEY_READ, &hKey);
if (ERROR_SUCCESS != lResult)
{
printf("Failed to open key \'HARDWARE\DEVICEMAP\SERIALCOMM\' \n");
ShowErrorFromLStatus(lResult);
return 1;
}
lResult = RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL,
&nValues, &nMaxValueNameLen, &nMaxValueLen, NULL, NULL);
if (ERROR_SUCCESS != lResult)
{
_tprintf(_T("Failed to RegQueryInfoKey()\n"));
ShowErrorFromLStatus(lResult);
RegCloseKey(hKey);
return 2;
}
szDeviceName = (LPTSTR)malloc(nMaxValueNameLen + sizeof(TCHAR));
if (!szDeviceName)
{
_tprintf(_T("malloc() fail\n"));
RegCloseKey(hKey);
return 3;
}
szFriendlyName = (LPTSTR)malloc(nMaxValueLen + sizeof(TCHAR));
if (!szFriendlyName)
{
free(szDeviceName);
_tprintf(_T("malloc() fail\n"));
RegCloseKey(hKey);
return 3;
}
_tprintf(_T("Found %d serial device(s) registered with PnP and active or available at the moment.\n"), nValues);
for (DWORD dwIndex = 0; dwIndex < nValues; ++dwIndex)
{
dwType = 0;
nValueNameLen = nMaxValueNameLen + sizeof(TCHAR);
nValueLen = nMaxValueLen + sizeof(TCHAR);
lResult = RegEnumValueW(hKey, dwIndex,
(LPWSTR)szDeviceName, &nValueNameLen,
NULL, &dwType,
(LPBYTE)szFriendlyName, &nValueLen);
if (ERROR_SUCCESS != lResult || REG_SZ != dwType)
{
_tprintf(_T("SerialPortEnumerator::Init() : can't process registry value, index: %d\n"), dwIndex);
ShowErrorFromLStatus(lResult);
continue;
}
_tprintf(_T("Found port \'%ls\': Device name for CreateFile(): \'\.%ls\'\n"), szFriendlyName, szDeviceName);
}
free(szDeviceName);
free(szFriendlyName);
RegCloseKey(hKey);
return 0;
}
我想列出 COM 端口(就像在 'Device Manager' 中看到的那样),但是在运行时。
我厚颜无耻地复制了this site的代码(代码显示在post的末尾),我想我明白了。然而,程序在第 36 行失败,给我错误:
Failed to open key 'HARDWARE\DEVICEMAP\SERIALCOMM'
Windows reports error: (0x00000002): The system cannot find the file specified.
如果我打开注册表编辑器,我会清楚地看到该文件夹,当我单击它时,我会看到我已连接到我的计算机的设备。
我使用 MinGW 和命令 gcc filename.c
关于如何解决这个问题有什么想法吗?可能是权限问题? gcc 是否需要一些编译器标志才能让我使用它?
我运行的代码是这样的:
#define WIN32_LEAN_AND_MEAN // excludes stuff frokm windows.h that we won't need here.
#include <Windows.h>
#include <string.h>
#include <tchar.h>
#include <malloc.h>
void ShowErrorFromLStatus(LSTATUS lResult)
{
LPTSTR psz;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
lResult,
0,
(LPTSTR)&psz,
1024,
NULL);
_tprintf(_T("Windows reports error: (0x%08X): %s\n"), lResult, (psz) ? psz : _T("(null)"));
if (psz)
{
LocalFree(psz);
}
}
int main()
{
DWORD nValues, nMaxValueNameLen, nMaxValueLen;
HKEY hKey = NULL;
LPTSTR szDeviceName = NULL;
LPTSTR szFriendlyName = NULL;
DWORD dwType = 0;
DWORD nValueNameLen = 0;
DWORD nValueLen = 0;
DWORD dwIndex = 0;
LSTATUS lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"HARDWARE\DEVICEMAP\SERIALCOMM", 0, KEY_READ, &hKey);
if (ERROR_SUCCESS != lResult)
{
printf("Failed to open key \'HARDWARE\DEVICEMAP\SERIALCOMM\' \n");
ShowErrorFromLStatus(lResult);
return 1;
}
lResult = RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL,
&nValues, &nMaxValueNameLen, &nMaxValueLen, NULL, NULL);
if (ERROR_SUCCESS != lResult)
{
_tprintf(_T("Failed to RegQueryInfoKey()\n"));
ShowErrorFromLStatus(lResult);
RegCloseKey(hKey);
return 2;
}
szDeviceName = (LPTSTR)malloc(nMaxValueNameLen + sizeof(TCHAR));
if (!szDeviceName)
{
_tprintf(_T("malloc() fail\n"));
RegCloseKey(hKey);
return 3;
}
szFriendlyName = (LPTSTR)malloc(nMaxValueLen + sizeof(TCHAR));
if (!szFriendlyName)
{
free(szDeviceName);
_tprintf(_T("malloc() fail\n"));
RegCloseKey(hKey);
return 3;
}
_tprintf(_T("Found %d serial device(s) registered with PnP and active or available at the moment.\n"), nValues);
for (DWORD dwIndex = 0; dwIndex < nValues; ++dwIndex)
{
dwType = 0;
nValueNameLen = nMaxValueNameLen + sizeof(TCHAR);
nValueLen = nMaxValueLen + sizeof(TCHAR);
lResult = RegEnumValueW(hKey, dwIndex,
szDeviceName, &nValueNameLen,
NULL, &dwType,
(LPBYTE)szFriendlyName, &nValueLen);
if (ERROR_SUCCESS != lResult || REG_SZ != dwType)
{
_tprintf(_T("SerialPortEnumerator::Init() : can't process registry value, index: %d\n"), dwIndex);
ShowErrorFromLStatus(lResult);
continue;
}
_tprintf(_T("Found port \'%s\': Device name for CreateFile(): \'\.%s\'\n"), szFriendlyName, szDeviceName);
}
free(szDeviceName);
free(szFriendlyName);
RegCloseKey(hKey);
return 0;
}
编辑
我现在用 _T("HARDWARE\DEVICEMAP\SERIALCOMM")
调用 RegOpenKeyEx
,在第 81 行对 RegEnumValueW 的调用中,我将 szDeviceName
转换为 LPWSTR
。 gcc 不再给出任何错误或警告。但是,当运行程序出来的时候,都是
Found 1 serial device(s) registered with PnP and active or available at the moment.
Found port 'C': Device name for CreateFile(): '\.\'
而且我连接的端口(COM3)没有显示。
还有其他建议吗?
感谢Simon Mourier and Ian Abbott!
如编辑中所述,使用 _T("HARDWARE\DEVICEMAP\SERIALCOMM")
调用 RegOpenKeyEx
并将 szDeviceName
转换为 LPWSTR
修复了所有错误。
此外,在第 92 行对 _tprintf()
的调用中使用标识符 %ls
使名称打印正确。
最终的工作代码如下所示:
#define WIN32_LEAN_AND_MEAN // excludes stuff frokm windows.h that we won't need here.
#include <Windows.h>
#include <string.h>
#include <tchar.h>
#include <malloc.h>
#include <stdio.h>
void ShowErrorFromLStatus(LSTATUS lResult)
{
LPTSTR psz;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
lResult,
0,
(LPTSTR)&psz,
1024,
NULL);
_tprintf(_T("Windows reports error: (0x%08X): %s\n"), lResult, (psz) ? psz : _T("(null)"));
if (psz)
{
LocalFree(psz);
}
}
int main()
{
DWORD nValues, nMaxValueNameLen, nMaxValueLen;
HKEY hKey = NULL;
LPTSTR szDeviceName = NULL;
LPTSTR szFriendlyName = NULL;
DWORD dwType = 0;
DWORD nValueNameLen = 0;
DWORD nValueLen = 0;
DWORD dwIndex = 0;
LSTATUS lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("HARDWARE\DEVICEMAP\SERIALCOMM"), 0, KEY_READ, &hKey);
if (ERROR_SUCCESS != lResult)
{
printf("Failed to open key \'HARDWARE\DEVICEMAP\SERIALCOMM\' \n");
ShowErrorFromLStatus(lResult);
return 1;
}
lResult = RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL,
&nValues, &nMaxValueNameLen, &nMaxValueLen, NULL, NULL);
if (ERROR_SUCCESS != lResult)
{
_tprintf(_T("Failed to RegQueryInfoKey()\n"));
ShowErrorFromLStatus(lResult);
RegCloseKey(hKey);
return 2;
}
szDeviceName = (LPTSTR)malloc(nMaxValueNameLen + sizeof(TCHAR));
if (!szDeviceName)
{
_tprintf(_T("malloc() fail\n"));
RegCloseKey(hKey);
return 3;
}
szFriendlyName = (LPTSTR)malloc(nMaxValueLen + sizeof(TCHAR));
if (!szFriendlyName)
{
free(szDeviceName);
_tprintf(_T("malloc() fail\n"));
RegCloseKey(hKey);
return 3;
}
_tprintf(_T("Found %d serial device(s) registered with PnP and active or available at the moment.\n"), nValues);
for (DWORD dwIndex = 0; dwIndex < nValues; ++dwIndex)
{
dwType = 0;
nValueNameLen = nMaxValueNameLen + sizeof(TCHAR);
nValueLen = nMaxValueLen + sizeof(TCHAR);
lResult = RegEnumValueW(hKey, dwIndex,
(LPWSTR)szDeviceName, &nValueNameLen,
NULL, &dwType,
(LPBYTE)szFriendlyName, &nValueLen);
if (ERROR_SUCCESS != lResult || REG_SZ != dwType)
{
_tprintf(_T("SerialPortEnumerator::Init() : can't process registry value, index: %d\n"), dwIndex);
ShowErrorFromLStatus(lResult);
continue;
}
_tprintf(_T("Found port \'%ls\': Device name for CreateFile(): \'\.%ls\'\n"), szFriendlyName, szDeviceName);
}
free(szDeviceName);
free(szFriendlyName);
RegCloseKey(hKey);
return 0;
}