Как восстановить доступ к COM-порту после отказа в доступе?
Вот некоторый код, который просто открывает com-порт и должен позволить мне делать с ним что-то, однако это не так, потому что COM-порт возвращается с "отказано в доступе", как вы можете видеть, я пытаюсь сделать все, чтобы очистить это сообщение для следующего запуска, чтобы освободить порт безрезультатно. Порт остается замороженным, если происходит какая-то ошибка ... есть идеи, как освободить порт, перезапустить его или что-то еще, чтобы восстановить доступ к порту после того, как произошла ошибка, без необходимости отключать его, снова подключать? спасибо за вашу помощь!
DCB dcb; b->h1 = CreateFile(b->port,GENERIC_READ | GENERIC_WRITE, 0, // comm devices must be opened w/exclusive-access NULL, // no security attributes OPEN_EXISTING, // comm devices must use OPEN_EXISTING 0, // overlapped I/O NULL); if (b->h1 == INVALID_HANDLE_VALUE) { //Major Error Need to Prepare for next run & Exit with error //Clear Comm Error Flag and also reset for I/O DWORD MsgID = GetLastError(); char *TextSize; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, MsgID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPTSTR) &TextSize, 0, 0); DWORD dwErrorFlags; COMSTAT ComStat; int result; BOOL fSuccess2; ClearCommError(b->h1, &dwErrorFlags, &ComStat ); ClearCommBreak(b->h1); // Fill in some DCB values and set the com state: // 57,600 bps, 8 data bits, no parity, and 1 stop bit. dcb.BaudRate = b->boud; // set the baud rate dcb.ByteSize = 8; // data size, xmit, and rcv dcb.Parity = NOPARITY; // no parity bit dcb.StopBits = ONESTOPBIT; // one stop bit SetCommState(b->h1, &dcb); //Port is still open so try to restart the comm port with those new settings above. fSuccess2 = SetCommState(b->h1, &dcb); //Do a complete purge of the comm now. PurgeComm(b->h1, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR); //Now Close Port CloseHandle(b->h1); b->h1 = NULL; b = NULL; a = NULL; hSock = NULL; hSock2 = NULL; ComSock.Close(); ClosePort(); return 2; }
[EDIT Jochen Arndt: скопировано из решения]
Идея состоит в том, чтобы иметь возможность "принудительно" закрыть порт, проблема в том, что другой поток может иметь открытый порт, и я хочу закрыть его, не имея доступа к другому экземпляру, который столкнулся с ошибкой.
Например, кто-то может вытащить аккорд во время передачи, если мы столкнемся с ошибкой, теперь мы хотим очистить порт, чтобы все было хорошо при следующем запуске, я особенно заинтересован в этих функциях, так как они, кажется, помогают в этом процессе, но они не сделали много для устранения ошибки "отказано в доступе".:
ClearCommError(b->h1, &dwErrorFlags, &ComStat ); ClearCommBreak(b->h1); PurgeComm(b->h1, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
Еще одним вариантом, который я рассматривал во время расследования, было использование DevCon.exe это не то, что я ищу, я специально ищу, чтобы перезапустить com-порт с помощью кода, а не подключать и отключать устройство и т. д....
Спасибо за вашу помощь и советы!
[no name]
Все это не имеет никакого смысла. если (b->h1 == INVALID_HANDLE_VALUE) является однозначным, и вы продолжаете пытаться выполнять операции над b->h1? Нет смысла пытаться закрыть недопустимый дескриптор. Начните снова и сначала напишите какой-нибудь псевдокод.
Jochen Arndt
Вы должны отредактировать свой вопрос, используя зеленую ссылку "улучшить вопрос", а не добавлять дополнительную информацию в решение. Я скопировал текст для вас.
Я предлагаю удалить ваше решение до того, как оно будет автоматически удалено, когда другие сообщат о нем как о "не решении".
Я также обновлю свой ответ.
Shirzad Sharif
хорошая идея, я здесь новичок, спасибо! :)
Shirzad Sharif
Имеет смысл, однако я думаю, что вся цель этой функции: ClearCommError(b->h1, &dwErrorFlags, &ComStat ); состоит в том, чтобы получить сломанный дескриптор и очистить ошибку, обычно я просто заканчиваю оператор if строкой FormatMessage, но сначала я хочу очистить ошибку...
[no name]
Вы можете очистить ошибки, возникающие на допустимом дескрипторе. В этом случае вы вообще не получаете действительного дескриптора. Предполагая, что поток, который содержал допустимый дескриптор, находится под вашим контролем, вот где вы должны очистить.
Shirzad Sharif
очень хорошая мысль... спасибо!