Autor |
Beitrag |
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mo 29.11.10 21:37
norics hat folgendes geschrieben : | Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| function TForm1.GetUser: String; var CompName : Array [1..20] of Char; SizeD : DWord; i:Integer; begin SizeD := 15; GetUserName( @CompName, SizeD ); begin Result := ''; for I := 1 to Length(CompName) do if CompName[i] <> #0 then Result := Result + CompName[i] ; end; result:=CompName; end; | |
Da kannst du dir die Schleife auch komplett sparen...
Außerdem ist Length(CompName) durch das feste Array eh immer gleich. Warum du ein Array der Länge 20 definierst und dann als Größe 15 übergibst, ist mir allerdings ein Rätsel.
Außerdem ist die maximale Länge UNLEN als 255 oder so definiert...
Jedenfalls schau dir doch bitte einmal die Dokumentation an... Du bekommst die Anzahl der Zeichen schließlich auf dem Silbertablett.
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Mo 29.11.10 21:51
Ein feste Buffergröße festzulegen ist schlecht. Du sagst ja selber, dass du nicht weißt, wie groß er sein muss.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| function GetCurrUserName: string; var Size : DWORD; begin Size := MAX_COMPUTERNAME_LENGTH + 1; SetLength(Result, Size); if GetUserName(PChar(Result), Size) then SetLength(Result, Size) else Result := ''; end; |
Und am Ende gegeben falls noch Trim aufrufen um unnötige Steuerzeichen zu entfernen.
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mo 29.11.10 21:54
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Mo 29.11.10 22:05
Hm, dann muss ich meine Funktion in meinem Archiv mal überprüfen.
|
|
delphi10
      
Beiträge: 447
Erhaltene Danke: 2
W2K, XP, Vista64, Win7 64
RAD-Studio 2010
|
Verfasst: Mo 29.11.10 23:20
_________________ Salus populi suprema lex esto
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Mo 29.11.10 23:28
Ihr macht mich noch wahnsinnig. Warum versucht ihr krampfhaft Trim nicht zu verwenden, sondern entwickelt andauernd eure eigenen frickel Lösungen?
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Di 30.11.10 00:16
delphi10 hat folgendes geschrieben : | // Result enthält den Usernamen + #0 |
Aber auch nur, wenn man die API-Funktion falsch benutzt.
Siehe oben...
Luckie hat folgendes geschrieben : | Warum versucht ihr krampfhaft Trim nicht zu verwenden, sondern entwickelt andauernd eure eigenen frickel Lösungen? |
Im Nachhinein Trim zu verwenden, weil man die Funktion falsch aufruft, ist aber auch nicht gerade sauber.
Deshalb hier einmal die laut Dokumentation korrekte Variante: Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| function GetCurrUserName: string; const UNLEN = 256; var BufferSize: DWORD; begin BufferSize := UNLEN + 1; SetLength(Result, BufferSize); if GetUserName(PChar(Result), BufferSize) then SetLength(Result, BufferSize - 1) else Result := ''; end; | Damit funktioniert es auch korrekt.
@ Luckie: MAX_COMPUTERNAME_LENGTH ist die falsche Konstante. Benutzernamen können durchaus länger als 15 Zeichen sein. UNLEN als Maximallänge ist in der API als 256 definiert.
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Di 30.11.10 00:25
Ächtz, langsam wird es peinlich. Ist irgendwo ein Schreibtisch in der Nähe zum darunter Kriechen? 
|
|
delphi10
      
Beiträge: 447
Erhaltene Danke: 2
W2K, XP, Vista64, Win7 64
RAD-Studio 2010
|
Verfasst: Di 30.11.10 00:39
_________________ Salus populi suprema lex esto
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Di 30.11.10 02:08
OK, hier ist die korrigierte Funktion:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| function GetCurrentUserName: string; const UNLEN = 256; var Size : DWORD; begin Size := UNLEN + 1; SetLength(Result, Size); if GetUserName(PChar(Result), Size) then SetLength(Result, Size - 1) else raise Exception.Create(SysErrorMessage(GetLastError)); end; |
|
|
Gerd Kayser
      
Beiträge: 632
Erhaltene Danke: 121
Win 7 32-bit
Delphi 2006/XE
|
Verfasst: Di 30.11.10 09:46
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Di 30.11.10 12:32
Der Unterschied liegt darin, dass ich das Ergebnis auf die tatsächliche Größe zu recht stutze und so verhindere, dass noch Müll mit ausgeliefert wird. Außerdem habe ich einer Fehlerbehandlung, die eine Exception wirft, wenn was schief geht. Bei dir würde einfach Müll zurückgegeben.
Für diesen Beitrag haben gedankt: jaenicke
|
|
Gerd Kayser
      
Beiträge: 632
Erhaltene Danke: 121
Win 7 32-bit
Delphi 2006/XE
|
Verfasst: Di 30.11.10 18:05
Luckie hat folgendes geschrieben : | Der Unterschied liegt darin, dass ich das Ergebnis auf die tatsächliche Größe zu recht stutze und so verhindere, dass noch Müll mit ausgeliefert wird. Außerdem habe ich einer Fehlerbehandlung, die eine Exception wirft, wenn was schief geht. Bei dir würde einfach Müll zurückgegeben. |
Da liegst Du aber falsch.
1. Durch "Result := Buffer;" werden nur die relevanten Bytes ohne #0 übertragen.
2. Das Array of Char hat als erstes Zeichen ein #0. Wird GetUserName z. B. mit Groesse = 3 aufgerufen, obwohl der Name länger ist, dann bleibt das Array mit der #0 als erstem Zeichen unverändert. Nur der Wert der Variablen Groesse ändert sich. Result ist dann ein LeerString, enthält also auch in diesem Fall keinen Müll.
3. Wenn der Buffer 256 Bytes groß sein soll (siehe UNLEN), das Array auch mindestens so groß ist (in meinem Beispiel 257 Bytes), die Groesse richtig an die Funktion übermittelt wird, was soll dann schief gehen? Wenn trotz richtigem Aufruf etwas dennoch schief laufen sollte, hat der Anwender wohl ein größeres Problem, das aber nicht an der Anwendung liegt, sondern wohl eher an Windows. Man kann sich auch zu Tode prüfen.
|
|
bummi
      
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: Di 30.11.10 18:21
da bin ich froh daß meine 10 Jahre alte Funktion bis XE durchgehalten hat.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| Function Get_UserName:String; var p:Pchar; dw:Dword; begin dw:=255; p:=stralloc(dw); GetUsername(p,dw); Result:=StrPas(p); strdispose(p); end; |
_________________ Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
|
|