Forum Delphi.cz

Delphi => Obecné => Téma založeno: Faltynek 06-05-2019, 07:42:22

Název: CreateFile pro com>9
Přispěvatel: Faltynek 06-05-2019, 07:42:22
Dobrý den,
jaká je správná syntaxe pro otevření sériového portu přes CreateFile?
MSDN říká, že pro číslo portu 1 až 9 by to mohlo být
Kód: Delphi [Vybrat]
  1. h = CreateFile("\\.\" + Port, GENERIC_READ Or GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
a pro číslo portu > 9 potom
Kód: Delphi [Vybrat]
  1. h = CreateFile("\\\\.\\" + Port, GENERIC_READ Or GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)

teda doslova se uvádí:
Kód: Delphi [Vybrat]
  1.     //For serial port numbers higher than 9 see KB115831
  2.    CreateFile(
  3.       "\\\\.\\COM10",     // address of name of the communications device
  4.       fdwAccess,          // access (read-write) mode
  5.       0,                  // share mode
  6.       NULL,               // address of security descriptor
  7.       OPEN_EXISTING,      // how to create
  8.       0,                  // file attributes
  9.       NULL                // handle of file with attributes to copy
  10.    );
  11.  

Potíž je v tom, že to nefunguje. Na Windows 7 hlásí com 10 error 161, tj. zadaná cesta neexestuje a pokud použiju zápis se třemi lomítky, vyskočí error 121.
Naopak na Windows 10 funguje pouze zápis se třemi lomítky pro libovolné číslo portu.

Asi v tom bude nějaký háček?

Dalibor.

Název: Re:CreateFile pro com>9
Přispěvatel: Morrison 06-05-2019, 08:46:03
Asi v tom bude jiný problém, mně zápis se třemi lomítky funguje pro jakékoliv číslo portu, a to i na Win7.
Název: Re:CreateFile pro com>9
Přispěvatel: geby 06-05-2019, 10:10:39
Ona je to uplne standardni UNC cesta. Ta preci zacina dvema zpetnymi lomitky, pak nasleduje jmeno pocitace (tecka tam znamena "já"), pak jedno zpetne lomitko, a pak nazev zarizeni. (U sitoveho pristupu treba nazev sdileni, atd...)

Tedy zapis '\\.\COM10' je spravny. Muzes si to overit treba pohledem do meho Synaseru, tam tohle pouzivam uz opravdu mnoho let a funguje to.

Zmateni s mnoha zpetnymi lomitky vznika tim, ze mnoho prikladu je uvedeno v jazyce C, kde je zpetne lomitko escape znak pro zapis specielnich znaku. Takze kdyz tam chces napsat zpetne lomitko, musis jej zdvojit. Coz se ale v Pascalu nedela.

Jasne?
Název: Re:CreateFile pro com>9
Přispěvatel: Faltynek 06-05-2019, 10:24:54
Citace
Zmateni s mnoha zpetnymi lomitky vznika tim, ze mnoho prikladu je uvedeno v jazyce C, kde je zpetne lomitko escape znak pro zapis specielnich znaku. Takze kdyz tam chces napsat zpetne lomitko, musis jej zdvojit. Coz se ale v Pascalu nedela.
Už jasné, díky, nejsem céčkař, takže jsem to nevěděl.

Citace
Asi v tom bude jiný problém, mně zápis se třemi lomítky funguje pro jakékoliv číslo portu, a to i na Win7.
Tak jsem to vyzkoušel na jeden konkrétní com, 19 kde je připojené zařízení s kterým si chci povídat.
A máš pravdu, i na sedmičkách to funguje se třemi lomítky. Nevím teda proč s tím MSDN mystifikuje.
Problémek vzniká tím, že přes API GetDefaultCommConfig zjišťuji předtím existující comy a postupně se je snažím otevírat a poslat do nich příkaz do zařízení. No a to by mi mělo odpovědět. Pokud neodpoví do timeoutu, zkusím další com dokud se neozve, nebo nedojdu na konec smyčky.
JENOMŽE v seznamu nalezených comů mi najde i čísla comů, která ve správci zařízení v seznamu comů NEJSOU!
Jak je to možný? Na těch se to zasekne a vytuhne.

Jasně, mohl bych to neřešit a říct, předtím než začneš používat program, mrkni, na jterým to je comu a zadej ho třeba do ini souboru, ale nějak se mi to nelíbí. Program by to měl poznat sám.

Dalibor.
Název: Re:CreateFile pro com>9
Přispěvatel: Morrison 06-05-2019, 10:52:34
Není to asi tak čistý řešení jako API funkce, ale já si seznam COMů načítám z registru "HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM".
Název: Re:CreateFile pro com>9
Přispěvatel: Faltynek 06-05-2019, 13:04:31
Citace
Není to asi tak čistý řešení jako API funkce, ale já si seznam COMů načítám z registru "HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM".

Jo, taky jsem to někde četl ale nezkusil.
Jinak - už mi to funguje s těma 3 lomítkama, měl jsem tam navíc ještě nějaký bordýlek v cyklech, ale stejně mě vrtá hlavou, co jsou ty neexistující comy.
Název: Re:CreateFile pro com>9
Přispěvatel: Faltynek 06-05-2019, 13:05:55
Díval jsem se do registrů, a jsou tam čtyři BthModem, asi něco s Bluetoothem..
Název: Re:CreateFile pro com>9
Přispěvatel: Faltynek 07-05-2019, 11:11:26
Citace
Není to asi tak čistý řešení jako API funkce, ale já si seznam COMů načítám z registru "HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM".

Ahoj,
zkoušel jsem číst registry, protože by to dost zrychlilo start inicializace karty oproti hledání správného comu, ale pořád se mi vrací nula-klíč nenalezen. Funkce funguje, ale jenom na klíče bez lomítka. Jak to napsat, když cesta je "HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM" a klíč má název DEVICE\VCP0" ?

Dalibor.

Název: Re:CreateFile pro com>9
Přispěvatel: Morrison 07-05-2019, 11:36:38
ZKusil bych otevřít klíč "HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM\DEVICE" a v něm hledat "VCP0". Pro přístup k registru používám standardní objekt TRegistry
Název: Re:CreateFile pro com>9
Přispěvatel: Faltynek 07-05-2019, 14:26:24
HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM\DEVICE\DCP0

Toto by měl být klíč i s cestou. Podle příkladu z helpu:

Kód: Delphi [Vybrat]
  1. var
  2.   reg        : TRegistry;
  3.   openResult : Boolean;
  4.   today      : TDateTime;
  5. begin
  6.   reg := TRegistry.Create(KEY_READ);
  7.   reg.RootKey := HKEY_LOCAL_MACHINE;
  8.  
  9.   if (not reg.KeyExists(edit1.text)) then
  10.     begin
  11.       MessageDlg('Key not found! .',
  12.                             mtInformation, mbOKCancel, 0);
  13.     end;
  14.  
  15. end;
  16.  

Do Edit1 to napíšu, odpálím tlačítko, ale reg.keyexist vrací furt false. Vůbec nevím co s tím.
Název: Re:CreateFile pro com>9
Přispěvatel: Faltynek 07-05-2019, 14:40:17
Když do editu napíšu HARDWARE\DEVICEMAP\SERIALCOMM (jasně, protože reg.RootKey := HKEY_LOCAL_MACHINE) a otestuju to, tak KeyExist vrátí True. Ale jak se dostat na to co je dál?
Název: Re:CreateFile pro com>9
Přispěvatel: Faltynek 07-05-2019, 16:05:53
Díky, mezitím jsem to vykoumal viz code:
Kód: Delphi [Vybrat]
  1. procedure TForm32.Button1Click(Sender: TObject);
  2. var
  3.   reg        : TRegistry;
  4.   openResult : Boolean;
  5.   today      : TDateTime;
  6.   i          : integer;
  7.   s: string;
  8. begin
  9.   listbox1.clear;
  10.   listbox2.clear;
  11.   reg := TRegistry.Create(KEY_READ);
  12.   reg.RootKey := HKEY_LOCAL_MACHINE;
  13.  
  14.   if (not reg.KeyExists(edit1.text)) then
  15.     begin
  16.       MessageDlg('Key not found! .',
  17.                             mtInformation, mbOKCancel, 0);
  18.     end
  19.     else
  20.     begin
  21.       MessageDlg('Nalezen! .', mtInformation, mbOKCancel, 0);
  22.       openResult := reg.OpenKey(edit1.text,True);     // oteviram klic
  23.       MessageDlg('Otevřen klíč ' + edit1.text, mtInformation, mbOKCancel, 0);
  24.       reg.GetValueNames(listbox1.Items);
  25.       for i:=0 to listbox1.Items.Count-1 do
  26.                 listbox2.items.add(reg.ReadString(listbox1.Items[i]));
  27.       reg.CloseKey();
  28.       MessageDlg('Zavřen klíč '+ edit1.text, mtInformation, mbOKCancel, 0);
  29.  
  30.     end;
  31.     reg.Free;
  32. end;
  33.  

V Edit1 je "HARDWARE\DEVICEMAP\SERIALCOMM"

A ještě se zeptám blbě, jmenuje se v registrech klíč HARDWARE\DEVICEMAP\SERIALCOMM na WinXP, Win7 a Win 10 stejně, nebo je to všude jinak?
Název: Re:CreateFile pro com>9
Přispěvatel: Faltynek 08-05-2019, 06:56:08
Každopádně jsem to vyzkoušel teď na Win 7 i Win 10 a je to stejné.
Ještě jsem zkoušel taky přístup do registru přes WScript, tady mi zatím daří najít jenom klíče, hodnoty ne.