Pu
Большой босс
Offline
78
|
|
« : 23-06-2004 07:52 » |
|
Подскажите как определить, какие СОМы есть на машине, тк в реестре они в разных системах сидят под разными ключами. Пользовался функцией QueryDosDevice но как оказалось под 98/ME/XP она отрабатывает не так как надо , или вообще не отрабатывает. Может есть еще что нибудь в этом роде?
|
|
|
Записан
|
Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать. (с) Артур Джонс
|
|
|
MOPO3
Ай да дэдушка! Вах...
Команда клуба
Offline
Пол:
Холадна аднака!
|
|
« Ответ #1 : 23-06-2004 08:21 » |
|
Я делаю это так : String comm_port; for(int i = 1; i < 255; i++) { comm_port = "COM" + IntToStr(i);
hComm_test = CreateFile(comm_port.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); if(hComm_test != INVALID_HANDLE_VALUE) { ComPort->Items->Add("COM" + IntToStr(i)); CloseHandle(hComm_test); } }
Решение наверно так себе, но прекрасно работает под всеми виндами
|
|
« Последнее редактирование: 28-11-2007 18:40 от Алексей1153++ »
|
Записан
|
MCP, MCAD, MCTS:Win, MCTS:Web
|
|
|
Pu
Большой босс
Offline
78
|
|
« Ответ #2 : 23-06-2004 08:52 » |
|
MOPO3, я думал что есть какие либо решения которые показывают то , что прописано в режистри. Если порт открыт, соответственно получим INVALID_HANDLE_VALUE, а хотелось бы и его увидеть в списке
|
|
|
Записан
|
Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать. (с) Артур Джонс
|
|
|
MOPO3
Ай да дэдушка! Вах...
Команда клуба
Offline
Пол:
Холадна аднака!
|
|
« Ответ #3 : 23-06-2004 08:55 » |
|
MOPO3, я думал что есть какие либо решения которые показывают то , что прописано в режистри. С режистри много возни будет, потому как в разных ветках и по разному лежат эти записи в вынь98 и 2000. Если порт открыт, соответственно получим INVALID_HANDLE_VALUE, а хотелось бы и его увидеть в списке Подожди, что то я не понял, ты имееш ввиду что порт в это время уже открыт другим приложением ?
|
|
|
Записан
|
MCP, MCAD, MCTS:Win, MCTS:Web
|
|
|
MOPO3
Ай да дэдушка! Вах...
Команда клуба
Offline
Пол:
Холадна аднака!
|
|
« Ответ #4 : 23-06-2004 08:59 » |
|
Вот, нашол в инете : listports.h#ifndef LISTPORTS_H #define LISTPORTS_H
#define VERSION_LISTPORTS 0x00010000
#ifdef __cplusplus extern "C"{ #endif
#include <windows.h>
typedef struct { LPCTSTR lpPortName; /* "COM1", etc. */ LPCTSTR lpFriendlyName; /* Suitable to describe the port, as for */ /* instance "Infrared serial port (COM4)" */ "LISTPORTS_PORTINFO;
typedef BOOL (CALLBACK* LISTPORTS_CALLBACK)(LPVOID lpCallbackValue, LISTPORTS_PORTINFO* lpPortInfo); /* User provided callback funtion that receives the information on each * serial port available. * The strings provided on the LISTPORTS_INFO are not to be referenced after * the callback returns; instead make copies of them for later use. * If the callback returns FALSE, port enumeration is aborted. */
BOOL ListPorts(LISTPORTS_CALLBACK lpCallback,LPVOID lpCallbackValue); /* Lists serial ports available on the system, passing the information on * each port on succesive calls to lpCallback. * lpCallbackValue, treated opaquely by ListPorts(), is intended to carry * information internal to the callback routine. * Returns TRUE if succesful, otherwise error code can be retrieved via * GetLastError(). */
#ifdef __cplusplus } #endif
#elif VERSION_LISTPORTS!=0x00010000 #error You have included two LISTPORTS.H with different version numbers #endif
listports.c#include "listports.h" #include <tchar.h> #include <stdlib.h> #include <string.h>
static BOOL Win9xListPorts(LISTPORTS_CALLBACK lpCbk,LPVOID lpCbkValue); static BOOL WinNT40ListPorts(LISTPORTS_CALLBACK lpCbk,LPVOID lpCbkValue); static BOOL Win2000ListPorts(LISTPORTS_CALLBACK lpCbk,LPVOID lpCbkValue); static BOOL ScanEnumTree(LPCTSTR lpEnumPath,LISTPORTS_CALLBACK lpCbk,LPVOID lpCbkValue); static LONG OpenSubKeyByIndex(HKEY hKey,DWORD dwIndex,REGSAM samDesired,PHKEY phkResult); static LONG QueryStringValue(HKEY hKey,LPCTSTR lpValueName, LPTSTR* lppStringValue);
BOOL ListPorts(LISTPORTS_CALLBACK lpCbk,LPVOID lpCbkValue) { OSVERSIONINFO osvinfo;
/* check parameters */
if(!lpCbk){ SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
/* determine which platform we're running on and forward * to the appropriate routine */
ZeroMemory(&osvinfo,sizeof(osvinfo)); osvinfo.dwOSVersionInfoSize=sizeof(osvinfo);
GetVersionEx(&osvinfo);
switch(osvinfo.dwPlatformId){ case VER_PLATFORM_WIN32_WINDOWS: return Win9xListPorts(lpCbk,lpCbkValue); break; case VER_PLATFORM_WIN32_NT: if(osvinfo.dwMajorVersion<4){ SetLastError(ERROR_OLD_WIN_VERSION); return FALSE; } else if(osvinfo.dwMajorVersion==4){ return WinNT40ListPorts(lpCbk,lpCbkValue); } else{ return Win2000ListPorts(lpCbk,lpCbkValue); /* hopefully it'll also work for XP */ } break; default: SetLastError(ERROR_OLD_WIN_VERSION); return FALSE; break; } }
BOOL Win9xListPorts(LISTPORTS_CALLBACK lpCbk,LPVOID lpCbkValue) { return ScanEnumTree(TEXT("ENUM"),lpCbk,lpCbkValue); }
static BOOL WinNT40ListPorts(LISTPORTS_CALLBACK lpCbk,LPVOID lpCbkValue) { DWORD dwError=0; HKEY hKey=NULL; DWORD dwIndex; LPTSTR lpValueName=NULL; LPTSTR lpPortName=NULL;
if(dwError=RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("HARDWARE\\DEVICEMAP\\SERIALCOMM"), 0,KEY_READ,&hKey)){ /* it is really strange that this key does not exist, but could happen in theory */ if(dwError==ERROR_FILE_NOT_FOUND)dwError=0; goto end; }
for(dwIndex=0;;++dwIndex){ DWORD cbValueName=32*sizeof(TCHAR); DWORD cbPortName=32*sizeof(TCHAR); LISTPORTS_PORTINFO portinfo;
/* loop asking for the value data til we allocated enough memory */
for(;;){ free(lpValueName); if(!(lpValueName=(LPTSTR)malloc(cbValueName))){ dwError=ERROR_NOT_ENOUGH_MEMORY; goto end; } free(lpPortName); if(!(lpPortName=(LPTSTR)malloc(cbPortName))){ dwError=ERROR_NOT_ENOUGH_MEMORY; goto end; } if(!(dwError=RegEnumValue(hKey,dwIndex,lpValueName,&cbValueName, NULL,NULL,(LPBYTE)lpPortName,&cbPortName))){ break; /* we did it */ } else if(dwError==ERROR_MORE_DATA)| /* not enough space */ dwError=0; /* no indication of space required, we try doubling */ cbValueName=(cbValueName+sizeof(TCHAR))*2; } else goto end; }
portinfo.lpPortName=lpPortName; portinfo.lpFriendlyName=lpPortName; /* no friendly name in NT 4.0 */ if(!lpCbk(lpCbkValue,&portinfo)){ goto end; /* listing aborted by callback */ } }
end: free(lpValueName); free(lpPortName); if(hKey!=NULL)RegCloseKey(hKey); if(dwError!=0){ SetLastError(dwError); return FALSE; } else return TRUE; }
BOOL Win2000ListPorts(LISTPORTS_CALLBACK lpCbk,LPVOID lpCbkValue) { return ScanEnumTree(TEXT("SYSTEM\\CURRENTCONTROLSET\\ENUM"),lpCbk,lpCbkValue); }
BOOL ScanEnumTree(LPCTSTR lpEnumPath,LISTPORTS_CALLBACK lpCbk,LPVOID lpCbkValue) { static const TCHAR lpstrPortsClass[]= TEXT("PORTS"); static const TCHAR lpstrPortsClassGUID[]=TEXT("|4D36E978-E325-11CE-BFC1-08002BE10318"");
DWORD dwError=0; HKEY hkEnum=NULL; DWORD dwIndex1; HKEY hkLevel1=NULL; DWORD dwIndex2; HKEY hkLevel2=NULL; DWORD dwIndex3; HKEY hkLevel3=NULL; HKEY hkDeviceParameters=NULL; TCHAR lpClass[sizeof(lpstrPortsClass)/sizeof(lpstrPortsClass[0])]; DWORD cbClass; TCHAR lpClassGUID[sizeof(lpstrPortsClassGUID)/sizeof(lpstrPortsClassGUID[0])]; DWORD cbClassGUID; LPTSTR lpPortName=NULL; LPTSTR lpFriendlyName=NULL;
if(dwError=RegOpenKeyEx(HKEY_LOCAL_MACHINE,lpEnumPath,0,KEY_ENUMERATE_SUB_KEYS,&hkEnum)){ goto end; }
for(dwIndex1=0;;++dwIndex1){ if(hkLevel1!=NULL){ RegCloseKey(hkLevel1); hkLevel1=NULL; } if(dwError=OpenSubKeyByIndex(hkEnum,dwIndex1,KEY_ENUMERATE_SUB_KEYS,&hkLevel1)){ if(dwError==ERROR_NO_MORE_ITEMS){ dwError=0; break; } else goto end; }
for(dwIndex2=0;;++dwIndex2){ if(hkLevel2!=NULL){ RegCloseKey(hkLevel2); hkLevel2=NULL; } if(dwError=OpenSubKeyByIndex(hkLevel1,dwIndex2,KEY_ENUMERATE_SUB_KEYS,&hkLevel2)){ if(dwError==ERROR_NO_MORE_ITEMS){ dwError=0; break; } else goto end; }
for(dwIndex3=0;;++dwIndex3){ BOOL bFriendlyNameNotFound=FALSE; LISTPORTS_PORTINFO portinfo;
if(hkLevel3!=NULL){ RegCloseKey(hkLevel3); hkLevel3=NULL; } if(dwError=OpenSubKeyByIndex(hkLevel2,dwIndex3,KEY_READ,&hkLevel3)){ if(dwError==ERROR_NO_MORE_ITEMS){ dwError=0; break; } else goto end; }
/* Look if the driver class is the one we're looking for. * We accept either "CLASS" or "CLASSGUID" as identifiers. * No need to dynamically arrange for space to retrieve the values, * they must have the same length as the strings they're compared to * if the comparison is to be succesful. */
cbClass=sizeof(lpClass); if(RegQueryValueEx(hkLevel3,TEXT("CLASS"),NULL,NULL, (LPBYTE)lpClass,&cbClass)==ERROR_SUCCESS&& _tcsicmp(lpClass,lpstrPortsClass)==0){ /* ok */ } else{ cbClassGUID=sizeof(lpClassGUID); if(RegQueryValueEx(hkLevel3,TEXT("CLASSGUID"),NULL,NULL, (LPBYTE)lpClassGUID,&cbClassGUID)==ERROR_SUCCESS&& _tcsicmp(lpClassGUID,lpstrPortsClassGUID)==0){ /* ok */ } else continue; }
/* get "PORTNAME" */
dwError=QueryStringValue(hkLevel3,TEXT("PORTNAME"),&lpPortName); if(dwError==ERROR_FILE_NOT_FOUND){ /* In Win200, "PORTNAME" is located under the subkey "DEVICE PARAMETERS". * Try and look there. */
if(hkDeviceParameters!=NULL){ RegCloseKey(hkDeviceParameters); hkDeviceParameters=NULL; } if(RegOpenKeyEx(hkLevel3,TEXT("DEVICE PARAMETERS"),0,KEY_READ, &hkDeviceParameters)==ERROR_SUCCESS){ dwError=QueryStringValue(hkDeviceParameters,TEXT("PORTNAME"),&lpPortName); } } if(dwError){ if(dwError==ERROR_FILE_NOT_FOUND)| /* boy that was strange, we better skip this device */ dwError=0; continue; } else goto end; }
/* check if it is a serial port (instead of, say, a parallel port) */
if(_tcsncicmp(lpPortName,TEXT("COM"),3)!=0)continue;
/* now go for "FRIENDLYNAME" */
if(dwError=QueryStringValue(hkLevel3,TEXT("FRIENDLYNAME"),&lpFriendlyName)){ if(dwError==ERROR_FILE_NOT_FOUND){ bFriendlyNameNotFound=TRUE; dwError=0; } else goto end; } /* Assemble the information and pass it on to the callback. * In the unlikely case there's no friendly name available, * use port name instead. */ portinfo.lpPortName=lpPortName; portinfo.lpFriendlyName=bFriendlyNameNotFound?lpPortName:lpFriendlyName; if(!lpCbk(lpCbkValue,&portinfo)){ goto end; /* listing aborted by callback */ } } } }
end: free(lpFriendlyName); free(lpPortName); if(hkDeviceParameters!=NULL)RegCloseKey(hkDeviceParameters); if(hkLevel3!=NULL) RegCloseKey(hkLevel3); if(hkLevel2!=NULL) RegCloseKey(hkLevel2); if(hkLevel1!=NULL) RegCloseKey(hkLevel1); if(hkEnum!=NULL) RegCloseKey(hkEnum); if(dwError!=0){ SetLastError(dwError); return FALSE; } else return TRUE; }
LONG OpenSubKeyByIndex(HKEY hKey,DWORD dwIndex,REGSAM samDesired,PHKEY phkResult) { DWORD dwError=0; LPTSTR lpSubkeyName=NULL; DWORD cbSubkeyName=128*sizeof(TCHAR); /* an initial guess */ FILETIME filetime;
/* loop asking for the subkey name til we allocated enough memory */
for(;;){ free(lpSubkeyName); if(!(lpSubkeyName=(LPTSTR)malloc(cbSubkeyName))){ dwError=ERROR_NOT_ENOUGH_MEMORY; goto end; } if(!(dwError=RegEnumKeyEx(hKey,dwIndex,lpSubkeyName,&cbSubkeyName, 0,NULL,NULL,&filetime))){ break; /* we did it */ } else if(dwError==ERROR_MORE_DATA)| /* not enough space */ dwError=0; /* no indication of space required, we try doubling */ cbSubkeyName=(cbSubkeyName+sizeof(TCHAR))*2; } else goto end; }
dwError=RegOpenKeyEx(hKey,lpSubkeyName,0,samDesired,phkResult);
end: free(lpSubkeyName); return dwError; }
LONG QueryStringValue(HKEY hKey,LPCTSTR lpValueName,LPTSTR* lppStringValue) { DWORD cbStringValue=128*sizeof(TCHAR); /* an initial guess */
for(;;){ DWORD dwError;
free(*lppStringValue); if(!(*lppStringValue=(LPTSTR)malloc(cbStringValue))){ return ERROR_NOT_ENOUGH_MEMORY; } if(!(dwError=RegQueryValueEx(hKey,lpValueName,NULL,NULL, (LPBYTE)*lppStringValue,&cbStringValue))){ return ERROR_SUCCESS; } else if(dwError==ERROR_MORE_DATA){ /* not enough space, keep looping */ } else return dwError; } }
Это работает под всеми виндами, и считывает из режистри.
|
|
« Последнее редактирование: 28-11-2007 18:44 от Алексей1153++ »
|
Записан
|
MCP, MCAD, MCTS:Win, MCTS:Web
|
|
|
Pu
Большой босс
Offline
78
|
|
« Ответ #5 : 23-06-2004 09:06 » |
|
MOPO3, БОЛШОЕ СПАСИБО! Сейчас буду пробовать. Правда громоздко. Но ничего.
|
|
|
Записан
|
Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать. (с) Артур Джонс
|
|
|
MOPO3
Ай да дэдушка! Вах...
Команда клуба
Offline
Пол:
Холадна аднака!
|
|
« Ответ #6 : 23-06-2004 09:09 » |
|
MOPO3, БОЛШОЕ СПАСИБО! Сейчас буду пробовать. Правда громоздко. Но ничего. Сорри, забыл сам вызов запостит Вот он : main.c#include "listports.h" #include <tchar.h> #include <stdio.h> #include <conio.h>
static BOOL CALLBACK callback(LPVOID lpCallbackValue,LISTPORTS_PORTINFO* lpPortInfo) { _tprintf(TEXT("\"%s\" \"%s\"\n"),lpPortInfo->lpPortName,lpPortInfo->lpFriendlyName); return TRUE; }
#ifdef UNICODE int wmain(void) #else int main(void) #endif { ListPorts(callback,NULL); _tprintf(TEXT("Any key to finish\n")); _getch(); return 0; }
Програмулина консольная.
|
|
« Последнее редактирование: 28-11-2007 18:44 от Алексей1153++ »
|
Записан
|
MCP, MCAD, MCTS:Win, MCTS:Web
|
|
|
Pu
Большой босс
Offline
78
|
|
« Ответ #7 : 23-06-2004 09:15 » |
|
MOPO3, мне самое важное вот эти вещички static BOOL Win9xListPorts(LISTPORTS_CALLBACK lpCbk,LPVOID lpCbkValue); static BOOL WinNT40ListPorts(LISTPORTS_CALLBACK lpCbk,LPVOID lpCbkValue); static BOOL Win2000ListPorts(LISTPORTS_CALLBACK lpCbk,LPVOID lpCbkValue); static BOOL ScanEnumTree(LPCTSTR lpEnumPath,LISTPORTS_CALLBACK lpCbk,LPVOID lpCbkValue); static LONG OpenSubKeyByIndex(HKEY hKey,DWORD dwIndex,REGSAM samDesired,PHKEY phkResult); static LONG QueryStringValue(HKEY hKey,LPCTSTR lpValueName, LPTSTR* lppStringValue); в принципе здесь все есть. еще раз сенк ю!
|
|
|
Записан
|
Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать. (с) Артур Джонс
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #8 : 23-06-2004 09:59 » |
|
Я делаю это так : String comm_port; for(int i = 1; i < 255; i++) { comm_port = "COM" + IntToStr(i);
hComm_test = CreateFile(comm_port.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); if(hComm_test != INVALID_HANDLE_VALUE) { ComPort->Items->Add("COM" + IntToStr(i)); CloseHandle(hComm_test); } }
Решение наверно так себе, но прекрасно работает под всеми виндами Ага я тоже так делаю, только маленькое замечание, на будущее. Текстовые константы в SDK определены для СОМ только до СОМ9. Я обжёгся на этом когда притащили карту с 24 СОМ портами. Тогда начиная с СОМ10 он думает, что это СОМ1 и тд. Поэтому надо определять имя порта полностью в формате : \\\\.\\COMn hComm_test = CreateFile("\\\\.\\COM12" ....
|
|
« Последнее редактирование: 28-11-2007 18:47 от Алексей1153++ »
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Pu
Большой босс
Offline
78
|
|
« Ответ #9 : 23-06-2004 10:11 » |
|
Джон, а в эмэсдээне про это есть? и где если не секрет?
|
|
|
Записан
|
Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать. (с) Артур Джонс
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #10 : 23-06-2004 10:28 » |
|
Pu, Именно там и нашёл...
Platform SDK: Storage Naming a File
The following reserved device names cannot be used as the name of a file: CON, PRN, AUX, CLOCK$, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9. Also avoid these names followed by an extension (for example, NUL.tx7).
А решение тоже где-то там находил, ща посмотрю...
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
MOPO3
Ай да дэдушка! Вах...
Команда клуба
Offline
Пол:
Холадна аднака!
|
|
« Ответ #11 : 23-06-2004 10:41 » |
|
Джон, благодарю за поправку. Мне это как раз и нужно, потому что драйвер мой умеет создавать до 255 виртуальных комов.
|
|
|
Записан
|
MCP, MCAD, MCTS:Win, MCTS:Web
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #12 : 23-06-2004 10:43 » |
|
Неа не получается сразу, я это давно находил ещё в MSDN для 6ой версии. А теперь у меня .NETная стоит. Там только нечто похожее для DeviceIoControl: Remarks To retrieve a handle to the device, you must call the CreateFile function with either the name of a device or the name of the driver associated with a device. To specify a device name, use the following format: \\.\DeviceName Но где-то было именно для СОМ порта ... Если найду скажу. Ааааа блин, ну и ещё, конечно, формат в начале именно \\.\, а я просто выдрал из форматной строки поэтому и \\\\.\\ :oops:
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Pu
Большой босс
Offline
78
|
|
« Ответ #13 : 23-06-2004 10:50 » |
|
Джон, и на этом спасибо, я под винды дальше сом4 еще не забирался, а тут как бы собрались мультиплексор на 32 порта моховский брать, но я надеюсь что там это поддержано на их драйверах и мне в это углубляться не придется.
|
|
|
Записан
|
Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать. (с) Артур Джонс
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #14 : 23-06-2004 11:03 » |
|
НЕВЕРОЯТНО НО ФАКТ!!! (а то я уже думал - крыша поехала, и ведь это толко в середине рабочего дня). Короче поставил я "старую" MSDN - октябрь 2001 (ИМХО это последняя для 6ой версии) и там сразу нашёл. Не знаю, есть ли у кого ещё такие проблемы, поэтому приведу полностью HOWTO: Specify Serial Ports Larger than COM9
Q115831
-------------------------------------------------------------------------------- The information in this article applies to:
Microsoft Win32 Application Programming Interface (API), used with: Microsoft Windows NT Server versions 3.5, 3.51, 4.0 Microsoft Windows NT Workstation versions 3.5, 3.51, 4.0 Microsoft Windows 95 the operating system: Microsoft Windows 2000
--------------------------------------------------------------------------------
SUMMARY CreateFile() can be used to get a handle to a serial port. The "Win32 Programmer's Reference" entry for "CreateFile()" mentions that the share mode must be 0, the create parameter must be OPEN_EXISTING, and the template must be NULL.
CreateFile() is successful when you use "COM1" through "COM9" for the name of the file; however, the message
INVALID_HANDLE_VALUE is returned if you use "COM10" or greater.
If the name of the port is \\.\COM10, the correct way to specify the serial port in a call to CreateFile() is as follows:
CreateFile( "\\\\.\\COM10", // address of name of the communications device fdwAccess, // access (read-write) mode 0, // share mode NULL, // address of security descriptor OPEN_EXISTING, // how to create 0, // file attributes NULL // handle of file with attributes to copy ); NOTES: This syntax also works for ports COM1 through COM9. Certain boards will let you choose the port names yourself. This syntax works for those names as well.
Additional query words: 3.10 3.50
Keywords : kbAPI kbCommPort kbKernBase kbOSWin2000 kbDSupport kbGrpDSKernBase kbSerial Issue type : kbhowto Technology : kbAudDeveloper kbWin32sSearch kbWin32API
Last Reviewed: December 16, 2000
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #15 : 23-06-2004 11:08 » |
|
теперь она и в новой нашлась, то же самое - PSS ID Number: 115831
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Pu
Большой босс
Offline
78
|
|
« Ответ #16 : 24-06-2004 06:17 » |
|
MOPO3, все работает , уже внедрил в прожект, еще раз респект!!!
|
|
|
Записан
|
Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать. (с) Артур Джонс
|
|
|
MOPO3
Ай да дэдушка! Вах...
Команда клуба
Offline
Пол:
Холадна аднака!
|
|
« Ответ #17 : 25-06-2004 07:01 » |
|
Pu, да незашто У меня вот не выходит пока под билдер енто впихнуть :oops:
|
|
|
Записан
|
MCP, MCAD, MCTS:Win, MCTS:Web
|
|
|
Pu
Большой босс
Offline
78
|
|
« Ответ #18 : 25-06-2004 07:39 » |
|
MOPO3, а в чем грабли? Подозреваю, что в пространстве имен определенных MS. типа всякие LPVOID, LPCTSTR и тп., стараюсь как можно меньше их использовать.
|
|
|
Записан
|
Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать. (с) Артур Джонс
|
|
|
Pu
Большой босс
Offline
78
|
|
« Ответ #19 : 25-06-2004 07:49 » |
|
MOPO3, а так просто у себя в классе диалога определил функцию static BOOL CALLBACK callback(LPVOID lpCallbackValue,LISTPORTS_PORTINFO* lpPortInfo); в OnInitDialog вызов ListPorts( callback, this); и реализация BOOL CALLBACK CDlgProperties::callback(LPVOID lpCallbackValue,LISTPORTS_PORTINFO* lpPortInfo) { CDlgProperties *pTargetClassPtr = (CDlgProperties *)lpCallbackValue; pTargetClassPtr->m_comboNumber.AddString(lpPortInfo->lpPortName); return TRUE; } все что я сделал - ну еще посмотрел как реализован поиск , чуток оптимизнул в своем стиле, чтоб привычнее было.
|
|
|
Записан
|
Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать. (с) Артур Джонс
|
|
|
MOPO3
Ай да дэдушка! Вах...
Команда клуба
Offline
Пол:
Холадна аднака!
|
|
« Ответ #20 : 28-06-2004 13:11 » |
|
Джон, Если делаю так : hComm = CreateFile(comms_port.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); то WriteFile, ReadFile работает хорошо без ошибок, но если с FILE_FLAG_OVERLAPPED, то при попытке записать в порт или считать с порта, выкидывает ошибку В чём грабли то ? Почему в асинхронном режиме не работает ?
|
|
« Последнее редактирование: 28-11-2007 18:49 от Алексей1153++ »
|
Записан
|
MCP, MCAD, MCTS:Win, MCTS:Web
|
|
|
Pu
Большой босс
Offline
78
|
|
« Ответ #21 : 29-06-2004 05:56 » |
|
открытие порта я делаю так , может поможет, у меня все работает именно в асинхронном режиме:
if (INVALID_HANDLE_VALUE == (hPort = CreateFile( W2A(m_NamePort), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 0))) return ( FALSE ) ; else { SetCommMask(hPort, EV_RXCHAR); SetupComm(hPort, 4096, 4096) ; PurgeComm( hPort, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR ) ; // установки для overlapped I/O CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF ; CommTimeOuts.ReadTotalTimeoutMultiplier = 0 ; CommTimeOuts.ReadTotalTimeoutConstant = 1000 ; CommTimeOuts.WriteTotalTimeoutMultiplier = 20; CommTimeOuts.WriteTotalTimeoutConstant = 0 ; SetCommTimeouts( hPort, &CommTimeOuts ); }
|
|
|
Записан
|
Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать. (с) Артур Джонс
|
|
|
MOPO3
Ай да дэдушка! Вах...
Команда клуба
Offline
Пол:
Холадна аднака!
|
|
« Ответ #22 : 29-06-2004 07:15 » |
|
Взял статью Программирование COM - порта с использованием WinApi и Assemblera отсюда http://www.dchack.net/Адаптировал под своё приложение. Первая форма(список комов+настройки порта+кнопка открыть), по нажатию кнопки открывается вторая форма(типо окно куда выводятся сообщения о том что происходит). Проблем в том, что когда доходит до ожидания события на порт, прога плотно повисает Не могу ни между формами перерубиться ни какой-нить баттон нажать Вот код : hComm = CreateFile("COM3", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); int retcode = PurgeComm(hComm, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
if( retcode==NULL ) { ComTerm->ComInfo->Lines->Add("(-) PurgeComm() failed"); } else { ComTerm->ComInfo->Lines->Add("(+) Discarded all characters from the output and input buffer"); }
retcode = ClearCommBreak(hComm); if( retcode==NULL ){ ComTerm->ComInfo->Lines->Add("(-) ClearCommBreak() failed"); PrintLastError(); } else { ComTerm->ComInfo->Lines->Add("(+) Restored character transmission. Transmission line in a nonbreak state"); }
dcbCommPort.DCBlength = sizeof(DCB); retcode = GetCommState(hComm,&dcbCommPort); if( retcode==NULL ) { ComTerm->ComInfo->Lines->Add("(-) GetCommState() failed"); } else { ComTerm->ComInfo->Lines->Add("(+) Retrieved the current control settings for COM" + IntToStr((ComPort->ItemIndex + 1))); }
String info = BitsPerSecond->Text + ",N," + DataBits->Text + "," + StopBits->Text; BuildCommDCB(info.c_str(), &dcbCommPort);
retcode = SetCommState(hComm, &dcbCommPort); if( retcode==NULL ) { ComTerm->ComInfo->Lines->Add("(-) SetCommState() failed"); } else { ComTerm->ComInfo->Lines->Add("(+) Reinitialized all hardware and control settings"); }
DWORD CommEventMask = EV_BREAK | EV_CTS | EV_DSR | EV_ERR | EV_RING | EV_RLSD | EV_RXCHAR | EV_RXFLAG | EV_TXEMPTY; retcode = SetCommMask(hComm,CommEventMask); if( retcode==NULL ){ ComTerm->ComInfo->Lines->Add("(-) SetCommMask() failed"); PrintLastError(); } else { ComTerm->ComInfo->Lines->Add("(+) BREAK, CTS, DSR, ERR, RING, RLSD, RXCHAR, RXFLAG, TXEMPTY"); }
OVERLAPPED OL; OL.hEvent=CreateEvent(NULL, TRUE, FALSE, NULL); DWORD EventMask = 0; //n?aa aoaao caienai oei niauoey ComTerm->ComInfo->Lines->Add(" "); /////////////////////////////////////////////////////////////////// do| retcode = WaitCommEvent(hComm, &EventMask, &OL); if ( ( !retcode ) && (GetLastError()==ERROR_IO_PENDING) ) { ComTerm->ComInfo->Lines->Add("(!) Waiting for event"); WaitForSingleObject(OL.hEvent, INFINITE); } if(EventMask & EV_BREAK) ComTerm->ComInfo->Lines->Add("(i) EV_BREAK"); if(EventMask & EV_RLSD) ComTerm->ComInfo->Lines->Add("(i) EV_RLSD"); if(EventMask & EV_CTS) ComTerm->ComInfo->Lines->Add("(i) EV_CTS"); if(EventMask & EV_DSR) ComTerm->ComInfo->Lines->Add("(i) EV_DSR"); if(EventMask & EV_ERR) ComTerm->ComInfo->Lines->Add("(i) EV_ERR"); if(EventMask & EV_RING) ComTerm->ComInfo->Lines->Add("(i) EV_RING"); if(EventMask & EV_RXCHAR) ComTerm->ComInfo->Lines->Add("(i) EV_RXCHAR"); if(EventMask & EV_RXFLAG) ComTerm->ComInfo->Lines->Add("(i) EV_RXFLAG"); if(EventMask & EV_TXEMPTY) ComTerm->ComInfo->Lines->Add("(i) EV_TXEMPTY"); DWORD ErrorMask = 0; COMSTAT CStat; ClearCommError(hComm, &ErrorMask, &CStat); DWORD quelen = CStat.cbInQue; char *lpInBuffer = new char[ (int)quelen+1 ]; memset(&lpInBuffer, '\0', (int)quelen);
DWORD dwReaded = 0; retcode = ReadFile(hComm, lpInBuffer, quelen, &dwReaded, &OL);
if( dwReaded == 0 && GetLastError() == ERROR_IO_PENDING ) { // DoSomeThing retcode = GetOverlappedResult(hComm, &OL, &dwReaded, FALSE) ; } else { if (dwReaded>0) //anee i?i?eoaee aaiiua { ComTerm->ComInfo->Lines->Add("(+) " + IntToStr(dwReaded) + " bytes received (" + lpInBuffer + ")"); } else { ComTerm->ComInfo->Lines->Add("(-) ReadFile() failed. errno " + IntToStr(GetLastError()) + ""); } }
if( PurgeComm(hComm, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR) == NULL ) { ComTerm->ComInfo->Lines->Add("(-) PurgeComm() failed"); PrintLastError(); }else { ComTerm->ComInfo->Lines->Add("(+) Discarded all characters from the output and input buffer"); }
EventMask=0; ResetEvent(OL.hEvent); }while(1);
|
|
« Последнее редактирование: 28-11-2007 18:53 от Алексей1153++ »
|
Записан
|
MCP, MCAD, MCTS:Win, MCTS:Web
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #23 : 29-06-2004 07:17 » |
|
MOPO3, А overlapped структуру передаёшь? А какая ошибка? - ERROR_IO_PENDING? Тогда всё нормально. Это значит, что данные не все переданы и ты можешь продолжить чтение(запись) или прервать. В overlapped структуре поле скажет тебе сколько байт считалось.
Типа так:
1.
FileHandle = ::CreateFile( Name, GENERIC_READ | GENERIC_WRITE, // access mode FILE_SHARE_WRITE | FILE_SHARE_READ, // share mode NULL, // security desc. OPEN_EXISTING, // how to create FILE_FLAG_OVERLAPPED, // file attributes NULL // template file );
2. потом при чтении (записи)
BOOL succ;
succ = ReadFile( FileHandle, // handle of file to read Buffer(), // pointer to buffer that receives data NumberOfBytesToTransfer, // number of bytes to read &BytesTransferred, // pointer to number of bytes read &Overlapped // pointer to overlapped structure ); if( succ ) { Status = USBIO_ERR_SUCCESS; } else { Status = GetLastError(); if( Status == ERROR_IO_PENDING ) { succ = TRUE; } }
return succ;
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
MOPO3
Ай да дэдушка! Вах...
Команда клуба
Offline
Пол:
Холадна аднака!
|
|
« Ответ #24 : 29-06-2004 07:20 » |
|
Джон, видно с тобой в одно время запостили Смотри выше я код запостил. overlapped структуру я передаю вроде как Экзешник(если есть желание посмотреть что происходит. там практически не рабочая прога пока тока часть с комами програмлю) лежит тута : ссылку почикал сам [/b]
|
|
|
Записан
|
MCP, MCAD, MCTS:Win, MCTS:Web
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #25 : 29-06-2004 07:29 » |
|
MOPO3, Опередил меня на две минутки Сорри, ща нет времени в твоём коде детально разбираться. На первый взглаяд выглядит правильно (касательно тех пунктов про которые я говорил). А что за ошибка?
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
MOPO3
Ай да дэдушка! Вах...
Команда клуба
Offline
Пол:
Холадна аднака!
|
|
« Ответ #26 : 29-06-2004 07:30 » |
|
Джон, Опятьпостами разошлись выше смотри. А ошибки то и нет никакой просто прога зависает на ожидании ивента
|
|
|
Записан
|
MCP, MCAD, MCTS:Win, MCTS:Web
|
|
|
Pu
Большой босс
Offline
78
|
|
« Ответ #27 : 29-06-2004 07:45 » |
|
MOPO3, да и ышо , для приема в порт я создаю отдельный поток, который и висит постоянно в процедуре WaitCommEvent пока оно не случится . типа hCommThread = CreateThread( (LPSECURITY_ATTRIBUTES) NULL, 0, (LPTHREAD_START_ROUTINE)runProcess, (LPVOID) this, 0, &dwThreadID) //запуск нити DWORD RSPort::runProcess(void* Param) { return ((RSPort *)Param)->CommProc(0); } // CommProc(); DWORD RSPort::CommProc( LPSTR lpData ) { DWORD dwEvtMask ; OVERLAPPED os ; int nLength ; BYTE abIn[MAXBLOCK + 1] ; memset( &os, 0, sizeof(OVERLAPPED) ) ; os.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); if (os.hEvent == NULL) { return ( FALSE ) ; } if (!SetCommMask(hPort, EV_RXCHAR)) return ( FALSE ) ; Count = 0; while(CONNECTED) { dwEvtMask = 0 ; WaitCommEvent(hPort, &dwEvtMask, NULL); if (EV_RXCHAR == (dwEvtMask & EV_RXCHAR)) { //ATLTRACE("получаю\n"); Lock(); do { if (nLength = ReadCommBlock((LPSTR) abIn, MAXBLOCK )) { //ATLTRACE("получил %d байт\n",nLength); SleepEx(5,TRUE); } else break; } while(1); Unlock(); //ATLTRACE("закончил получать байты %d байт\n", Count ); SetEvent(hEventRead); // разбор полетов } } CloseHandle( os.hEvent ) ; THREADID = 0 ; return( TRUE ) ; }
|
|
|
Записан
|
Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать. (с) Артур Джонс
|
|
|
Pu
Большой босс
Offline
78
|
|
« Ответ #28 : 29-06-2004 07:46 » |
|
правда я асинхронно только принимаю . Но думаю что передавать можно так же
|
|
|
Записан
|
Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать. (с) Артур Джонс
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #29 : 29-06-2004 08:13 » |
|
MOPO3, Слушай я что-то не вижу .... Она у тебя наверно тут висит:
WaitForSingleObject(OL.hEvent, INFINITE);
Если так, то ставь время поменьше и прверяй переданные байты и решай оборвать или нет только проверяй WaitForSingleObject(OL.hEvent, 1000); на TIME_OUT
время задержки выбери согласно твоим условиям (скорости железа и тд)
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
|