Hiding COM-Server OLE error message when user does not have sufficient rights

186 Views Asked by At

I am upgrading a Delphi-software project with a COM-automation interface to simplify some batch tasks (via WSH-Scripting). That in itself is easy... However, most of the "actual" users of the software do not need (or even know of) this interface, and I would like to spare them the registering of the COM-Server OR the error message that pops up, when the program cannot start the com server (Currently the software has no installer - it is just copy-and-go. Registering anything would be an extra step for users. It's inhouse, so the clients are used to that...).

Here is the actual question: Can I find out programmatically whether the current user running the software has sufficient rights to register the COM server and then (if not) avoid trying to create the server? I'd like a behavior that when the user does not have sufficient rights, the automation server just isnt there (with no error messages).

I tried adding a try-catch around the TAutoObjectFactory.Create(...) but that does not prevent the error. Adding a command line parameter that enables the server does not work either, because then creating the automation object from a script would start the program without that parameter and thus also not create the server.

2

There are 2 best solutions below

6
On

To solve this I use a TMyAutoObjectFactory object that inherits from TAutoObjectFactory and just overrides the UpdateRegistry method with a silent try/except clause, and update the initialization section at the bottom to use it. Like this:

type
  TMyAutoObjectFactory=class(TAutoObjectFactory)
  public
    procedure UpdateRegistry(Register: Boolean); override;
  end;

{ TMyAutoObjectFactory }

procedure TMyAutoObjectFactory.UpdateRegistry(Register: Boolean);
begin
  try
    inherited;
  except
    //silent
  end;
end;

initialization
  TMyAutoObjectFactory.Create(ComServer, TMyObjectSomething, Class_MyObjectSomething, ciMultiInstance, tmApartment);
end.

This will silence the error, but you will still need to run the app once with administrative privileges, or have an installer add the required registry entries.

0
On

I solved the problem by copying Delphis comserv-unit into the project, and placing a try-except block around the Comserver.Initialize-method(-body), because it turns out that the exception happened there (and not while registering the TAutoObjectFactory):

PROCEDURE TComServer.Initialize;
BEGIN
  TRY
    TRY
      UpdateRegistry(FStartMode <> smUnregServer);
    EXCEPT
      ON E: EOleRegistrationError DO
      // User may not have write access to the registry.
      // Squelch the exception unless we were explicitly told to register.
        IF FStartMode = smRegServer THEN RAISE;
    END;
    IF FStartMode IN [smRegServer, smUnregServer] THEN Halt;
    ComClassManager.ForEachFactory(Self, FactoryRegisterClassObject);
  EXCEPT
  ELSE
    FStartSuspended := true;
  END;
END;

Note: only the outter try-block is mine; the rest is the original that comes with Delphi5(!). This seems to suppress the error (before anyone asks: yes I know that the server is not running then, but that's the desired result; at least the program starts up - I don't understand anyway why the whole program fails to start if the server cant be registered).

PS: I am not setting this as the accepted answer as it "feels" too much like a hack, because it leaves a half initialized ComServer, and I dont know if that may have any side effects...