Техник
318 / 176 / 27
Регистрация: 09.10.2009
Сообщений: 3,109
1

Список COM портов

14.08.2015, 13:46. Показов 16286. Ответов 14
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Доброго времени суток! Делаю программку по считывают COM портов из реестра. Использую такой код:

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
SerialCommNum: TStringList;
//------------------
 
procedure GetSerialPortsList();
var
  Registry: TRegistry;
  i: integer;
begin
  Registry := TRegistry.Create;
    try
        Registry.RootKey := HKEY_LOCAL_MACHINE;
        Registry.OpenKey('hardware\devicemap\serialcomm', false);
        Registry.GetValueNames(SerialCommNum);
        for i:=0 to SerialCommNum.Count-1 do
            SerialCommNum.Add(Registry.ReadString(SerialCommNum.Strings[i]));
    finally
      Registry.CloseKey;
      Registry.Free;
  end;
end;
Столкнулся с проблемой! Функция GetValueNames считывает не только само значение но и имена. Точнее сначала имена, затем значения. В итоге имеем список вида:

[0] \Device\Serial0
[1] \Device\VCP0
[2] \Device\VCP1
[3] COM1
[4] COM2
[5] COM3

Хотя этот же код на С++ работает без проблем. После выполнения GetValueNames имеем в списке только сами значения, вида:

[0] COM1
[1] COM2
[2] COM3

Как на Delphi сделать тоже самое? Чтобы считывались только значения?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
14.08.2015, 13:46
Ответы с готовыми решениями:

Список COM портов
Может кто-нибудь написать простой примерчик для получения списка ком портов в с++. В нете читал...

Список портов в/в
Здравтсвуйте До перехода в защищенный режим можно юзать bios-прерывания, однако после перехода,...

запретить список портов
Всем привет!!! Такой вопрос: есть сервер win 2003 он раздает интернет, стоит Traffic Inspector, как...

Где посмотреть список com портов?
Здесь не видно

14
10231 / 6609 / 498
Регистрация: 28.12.2010
Сообщений: 21,156
Записей в блоге: 1
14.08.2015, 14:46 2
...реестр не дает гарантии доступности порта. Используйте следующий код:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var temp: pansichar; 
   i: integer;
  h: handle;
begin
 // сканируем доступные порты
 for i:= 1 to 128 do begin
  if i<9 then temp:= pansichar('COM' + inttostr(i))
   else temp:= pansichar('\\\\.\\' + 'COM' + inttostr(i));
 
  h:= CreateFileA(temp, GENERIC_READ , 0, nil, OPEN_EXISTING, 0, 0);
  if (h <> INVALID_HANDLE_VALUE) then begin
   SerialCommNum.Items.add(temp);
   CloseHandle(h)
  end;
 end;
1
Техник
318 / 176 / 27
Регистрация: 09.10.2009
Сообщений: 3,109
14.08.2015, 14:47  [ТС] 3
Нашел ошибку! Видимо когда переводил из Си на Делфи, случайно выкинул пару строк.

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
procedure GetSerialPortsList();
var
  Registry: TRegistry;
  i: integer;
  SerialCommValues: TStringList;
begin
  SerialCommValues := TStringList.Create;
  Registry := TRegistry.Create;
    try
        Registry.RootKey := HKEY_LOCAL_MACHINE;
        Registry.OpenKey('hardware\devicemap\serialcomm', false);
        Registry.GetValueNames(SerialCommValues);
        for i:=0 to SerialCommValues.Count-1 do
              SerialCommNum.Add(Registry.ReadString(SerialCommValues.Strings[i]));
    finally
      Registry.CloseKey;
      Registry.Free;
      SerialCommValues.Free;
  end;
end;
Добавлено через 1 минуту
raxp, Спасибо!)
1
Эксперт .NET
10530 / 6458 / 1502
Регистрация: 25.05.2015
Сообщений: 19,579
Записей в блоге: 14
14.08.2015, 17:57 4
Цитата Сообщение от raxp Посмотреть сообщение
...реестр не дает гарантии доступности порта. Используйте следующий код:
Это перебирает несуществующие порты в попытке их все открыть.
Список портов лучше брать-таки из реестра. А открыты они или заняты чем-то, уже в этом реестровом списке можно проверять.
Помимо реестра ещё через WMI можно получить.
0
пофигист широкого профиля
4732 / 3167 / 858
Регистрация: 15.07.2013
Сообщений: 18,248
14.08.2015, 18:47 5
Цитата Сообщение от Rius Посмотреть сообщение
Это перебирает несуществующие порты в попытке их все открыть.
Ну и правильно.
Цитата Сообщение от Rius Посмотреть сообщение
Список портов лучше брать-таки из реестра.
Нет не лучше.
0
Эксперт .NET
10530 / 6458 / 1502
Регистрация: 25.05.2015
Сообщений: 19,579
Записей в блоге: 14
14.08.2015, 19:27 6
Цитата Сообщение от northener Посмотреть сообщение
Нет не лучше.
Почему? Реестр может не содержать перечень существующих портов?

Добавлено через 14 минут
Исходники/библиотека с ещё несколькими методами получения списка портов EnumSerialPorts.
0
10231 / 6609 / 498
Регистрация: 28.12.2010
Сообщений: 21,156
Записей в блоге: 1
14.08.2015, 20:15 7
Реестр может содержать неверные записи, заблокирован, поврежден. Служба же WMI вообще не обязана быть активной.

ещё несколькими методами получения
SetupAPI.

GetNumCom.DLL.
1
пофигист широкого профиля
4732 / 3167 / 858
Регистрация: 15.07.2013
Сообщений: 18,248
15.08.2015, 01:55 8
Цитата Сообщение от Rius Посмотреть сообщение
Почему? Реестр может не содержать перечень существующих портов?
Цитата Сообщение от raxp Посмотреть сообщение
Реестр может содержать неверные записи
Вот именно поэтому. Реестр ничего не знает о железе, кроме того что в него пишут разработчики кривых программ/драйверов.
0
Эксперт .NET
10530 / 6458 / 1502
Регистрация: 25.05.2015
Сообщений: 19,579
Записей в блоге: 14
15.08.2015, 10:40 9
Пока ещё не встречал такой кривизны. Если так плохо написано, то найти имя порта может оказаться не главной проблемой.

Некоторые виртуальные порты могут иметь имена типа
C++
1
CreateFile("\\\\.\\CNCA0", ...).
. Так что CreateFile обрастёт ещё костылями.

Плюс, при SPP в Bluetooth, CreateFile вроде попытается соединиться с устройством. Что должно затормозить получение списка портов ниже плинтуса. Надо проверить .
0
10231 / 6609 / 498
Регистрация: 28.12.2010
Сообщений: 21,156
Записей в блоге: 1
15.08.2015, 11:15 10
могут иметь имена типа
это решается через SetupAPI.

Пока ещё не встречал такой кривизны
значит еще не пришло время.
0
пофигист широкого профиля
4732 / 3167 / 858
Регистрация: 15.07.2013
Сообщений: 18,248
16.08.2015, 01:20 11
Цитата Сообщение от Rius Посмотреть сообщение
Пока ещё не встречал такой кривизны.
Например, был эпизод с драйверами от FTDI, когда преобразователи USB-COM каждый раз при подключении создавали новый СОМ-порт, ибо "забывали" при отключении удалить из реестра прежнюю запись.
P.S.
Но самую вопиющую кривизну, которую я встречал, создали разработчики драйвера от TwinMos (если я правильно запомнил название фирмы). Контроллеры COM+LPT "морозили" винду по чёрному, если LPT-порта в железе не было.
1
1 / 1 / 0
Регистрация: 17.08.2019
Сообщений: 15
21.10.2019, 16:39 12
На основе части кода из одной статьи сделал такую функцию, которая возвращает ИМЕННО сом-порты (существующие, в том числе и виртуальные) в формате "СОМ1..2" (без всяких "Devices\Serial" и прочего).
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
var
  Form2: TForm2;
  function listComPorts:TStringList;
 
implementation
{$R *.lfm}
 
{ TForm2 }
 
 
 
function listComPorts:TStringList;
var
  i: Integer;
  Ports: TStringList;
  reg: TRegistry;
begin
  Ports := TStringList.Create;
  result:=TStringList.Create;
  reg := TRegistry.Create(KEY_READ);
    with reg do
    try
      reg.RootKey := HKEY_LOCAL_MACHINE;
      if reg.OpenKey('hardware\devicemap\serialcomm', false) then
        try
          ports.BeginUpdate();
          try
            reg.GetValueNames(ports);
            for i := ports.Count -1 downto 0 do            // обязательно в обратном порядке
            ports.Strings[i] := reg.ReadString(ports.Strings[i]);
            result:=ports;                  // вот тут присваиваем значения
            ports.sort()
 
          finally
            ports.EndUpdate()
          end
        finally
          reg.CloseKey()
        end
      else
        ports.clear()
    finally
    reg.free()
    end
 
end;
 
procedure TForm2.Button1Click(Sender: TObject);
begin
   memo1.Lines.Assign(listComPOrts);         //отображение СОМ-портов в Мемо1
   combobox1.Items.Assign(listComPOrts);  //отображение СОМ-портов в Комбобоксе
end;
1
5777 / 4520 / 1430
Регистрация: 14.04.2014
Сообщений: 20,143
Записей в блоге: 20
21.10.2019, 18:54 13
Цитата Сообщение от northener Посмотреть сообщение
каждый раз при подключении создавали новый СОМ-порт
а я вообще считал что windows так всегда и делает

век живи ))
0
пофигист широкого профиля
4732 / 3167 / 858
Регистрация: 15.07.2013
Сообщений: 18,248
22.10.2019, 02:30 14
Цитата Сообщение от krapotkin Посмотреть сообщение
а я вообще считал что windows так всегда и делает
Не а.
На каждое сочетание преобразователь+USB-порт создается один СОМ-порт, который и запоминается на всю оставшуюся жизнь данного конкретного экземпляра ОС Windows. И даже это меня постоянно бесит! Работать с такими преобразователями приходится в основном в полевых условиях, когда преобразователь втыкаешь в тот USB-разъём, где он меньше всего мешает работать. И каждый раз перед началом работы нужно лезть в диспетчер устройств, чтобы узнать какой нынче СОМ-порт выбрать. Прям хоть таблицу соответствий составляй.
Преобразователь от Болид + USBX = COMX
Преобразователь от Aritech + USBX = COMY
Преобразователь от Стрельца + USBX = COMZ
Преобразователь от моей бывшей фирмы + USBX = COM...
Вот только где эту таблицу держать?

И вот я не понимаю почему это так.
Если Винда умеет отличать один преобразователь от другого, то зачем создавать разные СОМ-порты при подключении одного преобразователя к разным USB-портам?
0
5777 / 4520 / 1430
Регистрация: 14.04.2014
Сообщений: 20,143
Записей в блоге: 20
22.10.2019, 14:20 15
я в свое время быстренько накидывал поиск портов где теперь сидит мой модем именно способом CreateFile в цикле))
ну и потом еще научился чистить неиспользуемые
0
22.10.2019, 14:20
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
22.10.2019, 14:20
Помогаю со студенческими работами здесь

Получить список TCP портов
Здравствуйте. Как мне получить список ВСЕХ незанятых портов машины. Пытаюсь IPGlobalProperties...

Как узнать список доступных портов в Qt
Здравствуйте, я хочу создать программу для &quot;общения&quot; с ардуино. Мне нужно узнать доступные порты и...

Список сом-портов, доступных в системе
Кто-нибудь разбирался как получить Список сом-портов, доступных в системе? Пока единственный...

[Qt] Получить список tcp соединений и прослушиваемых портов
Никак не могу найти, как получить список текущих подключений. Нужна такая же информация, как при...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru