请问用程序如何判断串口是被占用,还是串口不存在?我用的是spcomm控件。 ( 积分: 100 )

  • 主题发起人 主题发起人 doby_li
  • 开始时间 开始时间
D

doby_li

Unregistered / Unconfirmed
GUEST, unregistred user!
我用的是spcomm控件。

我现在是用这种方法:

if ComPortAvailable('COM1:') then
begin
//ShowMessage('com1口可以使用.!');
end
else
begin
try
comm1.CommName:='com1';
comm1.StopComm;
sleep(500);
comm1.StartComm;
Lblopencom.Caption:='当前使用的串口为:com1';
exit;
except
showmessage('不存在串口1或被占用。');
end;
end;

所用的函数:
function ComPortAvailable(Port:PChar):boolean;
Var
DeviceName:Array[0..80] of Char;
ComFile:THandle;
begin
StrPCopy(DeviceName,Port);
ComFile:=CreateFile(DeviceName,GENERIC_READ or GENERIC_WRITE,0,Nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
Result:=ComFile<>INVALID_HANDLE_VALUE;
CloseHandle(ComFile);
end;

上述的程序最大的一个问题是不能区分该串口是被占用,还是不存在。

请高手指点,谢谢。
 
所有串口可以在注册表中查到。

procedure QuerySystemComs(ComStrings: TStrings);
var
TmpReg: TRegistry;
TmpPath, TmpKey, TmpComName: string;
i: Integer;
begin
TmpReg := TRegistry.Create;
ComStrings.Clear;
try
TmpReg.RootKey := HKEY_LOCAL_MACHINE;
TmpPath := '/HARDWARE/DEVICEMAP/SERIALCOMM';

if TmpReg.OpenKeyReadOnly(TmpPath) then
for i := 0 to 9 do
begin
TmpKey := Format('/Device/Serial%d', );
TmpComName := TmpReg.ReadString(TmpKey);
if TmpComName <> '' then
ComStrings.Add(TmpComName);
end;
finally
TmpReg.Free;
end;
end;
 
现在发现在问题的症结。

即如果第一个软件打开了串口1,现在我用另一个软件试图先关闭串口1,然后再打开串口1,此时会报错,提示该串口被占用或不存在。

比如我用串口调试器软件打开了串口1,然后我再打开我的程序,试图先关掉串口1,再打开串口1,可这样会报错。

请问是不是在另一个软件里关闭不掉先前的软件所占用的串口?
有没有解决办法。
 
nicai_wgl,你好,
var
TmpReg: TRegistry;
这行编译时通不过呀,如何解决?
谢。
 
在帮助中搜索 TRegistry 就知道要uses Registry单元啦。
 
用注册表
 
通过注册表枚举串口
通过GetLastError取得错误码
 
nicai_wgl的方法只能枚举系统当前的串口,不能知道哪些串口现在正在被占用。
 
用一个循环,0-255.
 
自己写就是了,就别用spcomm控件了,我用过spcomm控件,还有mscomm控件,都遇到过问题,现在自己写的,用的很好。
 
用控件的话可以试试try..except..end结构。
try
MsComm.Open;
except
//串口打开失败,可能串口不存在或被占用。
end;

API的话直接判断CreateFile函数返回值就可以了。
 
var
hNewCommFile: THandle;
begin
hNewCommFile := CreateFile( PChar(FCommName),
GENERIC_READ or GENERIC_WRITE,
0, {not shared}
nil, {no security ??}
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED,
0 {template} );

if hNewCommFile = INVALID_HANDLE_VALUE then
raise ECommsError.Create( '串口打开失败。' );


if GetFileType( hNewCommFile ) <> FILE_TYPE_CHAR then
begin
CloseHandle( hNewCommFile );
raise ECommsError.Create( '不是正确的串口。 ' )
end;
 
多人接受答案了。
 
后退
顶部