I need to validate the user input and check if the entered string is a valid GUID. How can I do that? Is there some sort of IsValidGuid
validation function?
Asked
Active
Viewed 1,400 times
2

AmigoJack
- 5,234
- 1
- 15
- 31

peer____42
- 45
- 8
2 Answers
4
You can call the WinAPI function CLSIDFromString
and check (at its failure) if the returned value was not CO_E_CLASSSTRING
(which stands for an invalid input string). Calling the built-in StringToGUID
function is not reliable as it raises exception from which you're not able to get the reason of the failure.
The following function returns True
if the input string is a valid GUID, False
otherwise. In case of other (unexpected) failure it raises an exception:
const
S_OK = $00000000;
CO_E_CLASSSTRING = $800401F3;
type
LPCLSID = TGUID;
LPCOLESTR = WideString;
function CLSIDFromString(lpsz: LPCOLESTR; pclsid: LPCLSID): HRESULT;
external 'CLSIDFromString@ole32.dll stdcall';
function IsValidGuid(const Value: string): Boolean;
var
GUID: LPCLSID;
RetVal: HRESULT;
begin
RetVal := CLSIDFromString(LPCOLESTR(Value), GUID);
Result := RetVal = S_OK;
if not Result and (RetVal <> CO_E_CLASSSTRING) then
OleCheck(RetVal);
end;
-
thanks TLama, thats the quality i know from you. That was exactly the snippet i was looking for. – peer____42 Jul 30 '15 at 08:04
2
How about this?
Uses System.SysUtils;
function IsValidGuid(GUID: String): Boolean;
begin
try
StringToGUID(GUID);
Result := True;
except
Result := False;
end;
end;
If the StringToGUID
function is not successful in converting a string to a TGUID
, it will raise an error. This is how I used it in my project and it works fine.
Another alternative:
function IsValidGuid(const GUID: string): Boolean;
var
G: string;
L: Integer;
begin
Result := False;
L := Length(GUID);
if not (L in [36, 38]) then
Exit;
G := UpperCase(GUID);
if (L = 38) and (G[1] = '{') and (G[L] = '}') then
G := Copy(G, 2, L - 2);
Result := (Length(G) = 36) and (G[09] + G[14] + G[19] + G[24] = '----');
if Result then
begin
G := StringReplace(G, '-', '', [rfReplaceAll]);
for L := 1 to 32 do
Result := Result and (G[L] in ['0'..'9', 'A'..'F']);
end;
end;

Mahan
- 135
- 7
-
The implementation of that function is `OleCheck(CLSIDFromString(PWideChar(WideString(S)), Result));` and as such it's the same as the answer from 2015 (which already mentioned this function and why it's not the most reliable). – AmigoJack Dec 06 '22 at 11:01
-
1I think uncomplicated and more readable code is always better. That's why I posted that answer. – Mahan Dec 06 '22 at 12:14
-
...at the price of also returning `FALSE` for other reasons, unbound to a valid or invalid format. – AmigoJack Dec 06 '22 at 14:17