Detectar si una clase OCX se ha registrado en Windows
Pregunta
Necesito saber cómo se puede detectar si una clase OCX (ClassID) se ha registrado en Windows
algo así como
function IsClassRegistered(ClassID:string):boolean;
begin
//the magic goes here
end;
begin
if IsClassRegistered('{26313B07-4199-450B-8342-305BCB7C217F}') then
// do the work
end;
Solución
se puede comprobar la existencia de la CLSID HKEY_CLASSES_ROOT
en el Registro de windows .
comprobar esta muestra
function ExistClassID(const ClassID :string): Boolean;
var
Reg: TRegistry;
begin
try
Reg := TRegistry.Create;
try
Reg.RootKey := HKEY_CLASSES_ROOT;
Result := Reg.KeyExists(Format('CLSID\%s',[ClassID]));
finally
Reg.Free;
end;
except
Result := False;
end;
end;
Otros consejos
ActiveX / COM es una bestia compleja, registros tienen muchas piezas a ellos, y Vista + en adelante que sea más complicado con las normas UAC Registro de virtualización.
La mejor opción es intentar simplemente crear una instancia del OCX y ver si tiene éxito o no. Eso le indicará si el OCX se ha registrado correctamente, todas las piezas son de hasta enganchado, si el OCX es aún utilizable dentro del contexto del usuario que llama, etc.
El problema con (muchos, muchos) sugerencias de rastrear el registro es que:
- hay más de una ubicación de registro que tendría que mirar a
- una clase puede ser registrada y no existe en el registro
Registro de libre COM permite que una clase esté disponible sin ella siendo registrado. Conceptualmente no desea saber si una clase es "registrado" , lo que desea saber que se ha registrado suficiente para ser creado.
Por desgracia la única (y mejor) manera de hacerlo es crearlo:
//Code released into public domain. No attribution required.
function IsClassRegistered(const ClassID: TGUID): Boolean;
var
unk: IUnknown;
hr: HRESULT;
begin
hr := CoCreateInstance(ClassID, nil, CLSCTX_INPROC_SERVER or CLSCTX_LOCAL_SERVER, IUnknown, {out}unk);
unk := nil;
Result := (hr <> REGDB_E_CLASSNOTREG);
end;