2

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.

FrankB
  • 349
  • 4
  • 10
  • 1
    You always can use PerUserRegistartion instead of global. It does not require Administrator right. – Denis Anisimov Jun 19 '14 at 10:59
  • 1
    Why do you bother registering the server. Use registration free COM. – David Heffernan Jun 19 '14 at 12:10
  • @DenisAnisimov does not seem to exist in Delphi5 – FrankB Jun 20 '14 at 10:03
  • @DavidHeffernan I tried that - but could not get it to work... Also I read somewhere that registration-free-COM does not really work with scripts. – FrankB Jun 20 '14 at 10:05
  • @FrankB Delphi 5 does not define COM. COM is part of the system. If you want to register per use, just do so. If the Emba classes don't offer the functionality, write it yourself. If you must use a 15 year old tool, do expect it to be 15 years out of date. Do expect to have to write code to make up for that. – David Heffernan Jun 20 '14 at 10:05
  • @DavidHeffernan AFAIK, registration free COM requires the manifest files to be located in the same folder as the COM client. Since WSH is the client here that wouldn't be possible with the given restrictions. – SpeedFreak Jun 20 '14 at 13:57
  • @SpeedFreak Fair enough – David Heffernan Jun 20 '14 at 14:12

2 Answers2

1

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.

Stijn Sanders
  • 35,982
  • 11
  • 45
  • 67
  • I don't really understand what this is trying to do. Either you need to write to the registry or you don't. If you do, then how can you just continue silently? – David Heffernan Jun 20 '14 at 07:11
  • @DavidHeffernan the point is to NOT register without sufficient rights, but have the program useable - then the COM-Automation is not available; but that's ok in my context. However, this solution does not achieve that - at least not with Delphi5. – FrankB Jun 20 '14 at 10:02
  • @David It's trying to register if possible and fail silently if not possible - just like the OP requested. It's not the solution I would use but I can't see why it shouldn't be valid in this particular case. – SpeedFreak Jun 20 '14 at 13:38
  • @SpeedFreak because the exception is still thrown and stops the program from starting up properly. The actual Execption happens in ComServer.Initialize (not in the AutoObjectFactory). Maybe that's different in different Versions of Delphi... – FrankB Jun 20 '14 at 13:56
  • @FrankB Without specifics about the error I'll have to guess so I'll guess that it's not the registration of the COM server that fails but the registration of the type library. How do you initiate the registration? Have you tried just calling ComServer.UpdateRegistry(True) directly inside a try...except? – SpeedFreak Jun 20 '14 at 14:08
  • @FrankB please note my last addition at the bottom. The ComServer.Initialize error may be due to missing registry entries. For your component to work, it still needs to have these registry entries, either by script or an installer or a first run with administrative privileges. – Stijn Sanders Jun 20 '14 at 17:42
0

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...

FrankB
  • 349
  • 4
  • 10