![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Com-порт проблема под NT server ! [D7, Win95/98, Win2k]
Роман © (2004-03-04 12:14:00)Проблема такого рода. Понадобилось мне написать программу для управления устройством через COM-порт, скачал я страницу с данного сайта: http://www.delphimaster.ru/articles/comport2/index.html"Работа с COM-портами под Windows". Написал программу и обнаружил, что под Windows 2000 pro и Windows 98 se она работает, а под Windows 2000 server выскакивает ошибка: "Невозмажно создать данный файл, так как он уже существует." :-| !!!
Используется функция CreateFile, далее пример кода:
CommHandle:=CreateFile('COM1', GENERIC_READ or GENERIC_WRITE, FILE_SHARE_WRITE and FILE_SHARE_READ, nil, OPEN_ALWAYS, FILE_FLAG_OVERLAPPED, 0);
Для анализа ошибки использовалась FormatMessage.
Подскажите, если возможно, почему под Windows 2000 NT server эта функция не работает, а под Windows 2000 pro или Windows 98 se работает? Проблема в самой программе или в настройках системы? Запретить использовать Com1 для "мыши" я уже пробовал - не помогло (ставиться ключ в boot.ini: /NoSerialMice:COM1). В данный момент к Com-порту ничего не подключено. :-(
Роман. (2004-03-08 18:39:00) [1]Перейдите к вопросу:
Com-порт против NT Server.
http://www.delphimaster.ru/cgi-bin/forum.pl?id=1078760207&n=2
Пожалуйста.
Talla2k (2004-03-05 02:19:00) [2]Ох и пример ты взял!!!Там одни БАГИ!
Вот поюзай:
function LStr(const Source:Ansistring;Count:Integer):Ansistring;
begin
Result:=Copy(Source,1,Count);
end;
function OpenComm(Mode:AnsiString):THandle;
var
DCB : TDCB;
TOut: TCommTimeouts;
I:Integer;
Bfr:AnsiString;
begin
Bfr:=Mode;
UniqueString(Bfr);
I:=Pos(':',Bfr)-1;
if I<=0 then I:=4;
Result := CreateFile(PChar(LStr(Bfr,I)),GENERIC_READ or GENERIC_WRITE,
0,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
GetCommState( Result, DCB) ;
BuildCommDCB(PChar(Bfr),DCB);
DCB.EvtChar := #13;
SetCommState( Result, DCB) ;
//
TOut.ReadIntervalTimeout := MAXDWORD;
TOut.ReadTotalTimeoutMultiplier := 0;
TOut.ReadTotalTimeoutConstant := 0;
TOut.WriteTotalTimeoutMultiplier := 0;
TOut.WriteTotalTimeoutConstant := 0;
SetCommTimeOuts( Result, TOut);
SetCommMask(Result,EV_RLSD OR EV_RXFLAG);
PurgeComm(Result,PURGE_TXCLEAR); //clear transmit buffer
PurgeComm(Result,PURGE_RXCLEAR); //clear receive buffer
end;
function ReadComm(Handle:THandle; var Bfr:AnsiString):Integer;
var
I,J:DWord;
begin
Result:=0;
J:=Length(Bfr);
repeat
ReadFile(Handle, Bfr[Result+1], J-DWord(Result), I, nil);
Inc(Result,Integer(I));
if DWord(Result)=J then break;
until I=0;
end;
function WriteComm(Handle:THandle; const Bfr:AnsiString):Integer;
var
I,J:DWord;
begin
Result:=0;
J:=Length(Bfr);
repeat
WriteFile(Handle, Bfr[Result+1], J-DWord(Result), I, nil);
Inc(Result,Integer(I));
if DWord(Result)=J then break;
until I=0;
end;
function CloseComm(Handle:THandle):boolean;
begin
CloseHandle(Handle);
result:=true;
end;
function SetRxTime(Handle:THandle; const TimeC,TimeM:Integer):Boolean;
var
TOut:TCommTimeouts;
begin
if (TimeC=0) AND (TimeM=0) then
TOut.ReadIntervalTimeout := MAXDWORD
else TOut.ReadIntervalTimeout := 0;
TOut.ReadTotalTimeoutMultiplier := TimeM;
TOut.ReadTotalTimeoutConstant := TimeC;
TOut.WriteTotalTimeoutMultiplier := 0;
TOut.WriteTotalTimeoutConstant := 0;
Result:=SetCommTimeOuts(Handle, TOut);
end;
работать так
...
Handle:=OpenComm('COM'+co+':BAUD='+baud+' PARITY=N DATA=8 STOP=1');
if Handle=INVALID_HANDLE_VALUE then begin result:=false;exit;end;
if GetFileType(Handle)<>FILE_TYPE_CHAR then begin result:=false;exit;end;
setrxtime(handle,100,25); //100,25
...
Роман (2004-03-04 17:38:00) [3]Кому: Polevi
Не помогло... :-(
SetLastError(0);
lpMsgBuf:='';
DCB.DCBlength:=sizeof(TDCB);
if not (GetCommState(CommHandle, DCB)) then
ShowMessage('Неудача выгрузки в DCB сотояния!');
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER + FORMAT_MESSAGE_FROM_SYSTEM, nil, GetLastError, LANG_SYSTEM_DEFAULT, @lpMsgBuf, 100, nil);
ShowMessage('После GetCommState:'+' №='+IntToStr(GetLastError)+' '+lpMsgBuf);
На всё это творчество ответ: "После GetCommState: №=183 Невозможно создать файл, так как он уже существует."
Хотя CreateFile прошёл без замечаний...
Ещё вопрос: как проверить, на что указывает CommHandle? Вдруг не на Com1, уже и не знаю что предположить...
Polevi (2004-03-04 16:31:00) [4]DCB.DCBlength:=sizeof(TDCB)
if not (GetCommState(CommHandle, DCB))...
Роман (2004-03-04 15:59:00) [5]Кому: Reindeer Moss Eater
Ранее...
Вот раздел объявлений переменных:
var
Form1: TForm1;
DCB: TDCB;
Over: OVERLAPPED;
CommHandle: HFILE;
arRData: array [0..4] of Byte;
lpMsgBuf: PChar;
Success: boolean;
OFStruct1: OFSTRUCT;
Reindeer Moss Eater (2004-03-04 15:13:00) [6]Причём CreateFile выполняется на ура... :-(
Это еще не гарантия того, что в вызове GetCommState указан дескриптор открытого файла.
Короме того, где у тебя декларация переменной DCB?
Роман (2004-03-04 14:25:00) [7]Кому: Reindeer Moss Eater
Нет, вроде 1, код я указал:
ShowMessage('После GetCommState: LastError = '+IntToStr(GetLastError)+' '+lpMsgBuf);
Да и комментарий дан FormatMessage...
Причём CreateFile выполняется на ура... :-(
Reindeer Moss Eater (2004-03-04 14:18:00) [8]А может -1?
И не ERROR_INVALID_FUNCTION, а LZERROR_BADINHANDLE ?
Роман (2004-03-04 14:02:00) [9]LastError = 1
А вообще пишет: "Неверная функция".
Участок кода:
if not (GetCommState(CommHandle, DCB)) then
begin
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER + FORMAT_MESSAGE_FROM_SYSTEM,
nil, GetLastError, LANG_SYSTEM_DEFAULT, @lpMsgBuf, 100, nil);
ShowMessage('После GetCommState: LastError = '+IntToStr(GetLastError)+' '+lpMsgBuf);
end;
Reindeer Moss Eater (2004-03-04 13:05:00) [10]var
DCB : TDCB;
begin
if not (GetCommState(CommHandle, DCB)) then
ShowMessage('LastError = '+IntToStr(GetLastError));
Роман (2004-03-04 12:39:00) [11]Спасибо в этом месте заработало, но теперь другой глюк:
if not (GetCommState(CommHandle, DCB)) then
ShowMessage('Неудача получения состояния! GetCommState(CommHandle, DCB)');
{Типа загрузить состояние и тут же проверить "Удачно ли?"}
Не загружается состояние Com-порта в структуру DCB, таких мест в программе несколько и все они не работают.
Anatoly Podgoretsky (2004-03-04 12:27:00) [12]Он и в примере тоже
Reindeer Moss Eater (2004-03-04 12:21:00) [13]Про флаг OPEN_EXISTING забыл