Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Making Multi-Instance COM Server Work When Started in Delphi 10 Seattle IDE


This question is answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 9 - Last Post: Feb 4, 2016 11:59 AM Last Post By: Remy Lebeau (Te...
Sean Keeley

Posts: 6
Registered: 12/9/15
Making Multi-Instance COM Server Work When Started in Delphi 10 Seattle IDE  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 27, 2016 3:44 PM
I have found that a multi-instance (the default) COM Server created in Delphi 10 Seattle Update 1 does not work correctly when it is started from within the IDE, either with or without debugging.

With the COM Server running, a CreateOleObject in another Delphi program or a CreateObject in VBS script will create a new instance rather than connect to the running instance. This does not happen when the COM Server is run from Windows Explorer.

Is there something I need to do in the COM Server to make this work or is this a bug in Delphi?

Edited by: Sean Keeley on Jan 27, 2016 3:45 PM
Peter Below

Posts: 1,227
Registered: 12/16/99
Re: Making Multi-Instance COM Server Work When Started in Delphi 10 Seattle IDE [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 28, 2016 10:12 AM   in response to: Sean Keeley in response to: Sean Keeley
Sean Keeley wrote:

I have found that a multi-instance (the default) COM Server created
in Delphi 10 Seattle Update 1 does not work correctly when it is
started from within the IDE, either with or without debugging.

With the COM Server running, a CreateOleObject in another Delphi
program or a CreateObject in VBS script will create a new instance
rather than connect to the running instance. This does not happen
when the COM Server is run from Windows Explorer.

Is there something I need to do in the COM Server to make this work
or is this a bug in Delphi?

Is this a out-of-process server (a EXE, not a DLL)? Does it register
itself into the running objects table? What you see is actually the
default, a client wanting to connect to a running instance of the COM
server has to explicitely request that by using GetActiveObject instead
of CreateOleObject/CoCreateInstance. If several instance may be running
and registered with the ROT you have to get an interface for the ROT
first and enumerate the instances to find the one you want to connect
to.

--
Peter Below
TeamB
Sean Keeley

Posts: 6
Registered: 12/9/15
Re: Making Multi-Instance COM Server Work When Started in Delphi 10 Seattle IDE [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 28, 2016 11:52 AM   in response to: Peter Below in response to: Peter Below
Peter Below wrote:
Sean Keeley wrote:

I have found that a multi-instance (the default) COM Server created
in Delphi 10 Seattle Update 1 does not work correctly when it is
started from within the IDE, either with or without debugging.

With the COM Server running, a CreateOleObject in another Delphi
program or a CreateObject in VBS script will create a new instance
rather than connect to the running instance. This does not happen
when the COM Server is run from Windows Explorer.

Is there something I need to do in the COM Server to make this work
or is this a bug in Delphi?

Is this a out-of-process server (a EXE, not a DLL)? Does it register
itself into the running objects table? What you see is actually the
default, a client wanting to connect to a running instance of the COM
server has to explicitely request that by using GetActiveObject instead
of CreateOleObject/CoCreateInstance. If several instance may be running
and registered with the ROT you have to get an interface for the ROT
first and enumerate the instances to find the one you want to connect
to.

--
Peter Below
TeamB

It is an out-of process (EXE) server. The COM Server is registered via the Register Type Library button in the Delphi IDE.

The CreateOleObject call does not create a new instance when the server is started manually via Windows Explorer or via a CreateProcess API call. The new instance is only created when the server was started by the Delphi IDE. It appears that something in the way the Delphi IDE starts the server program breaks the the multi-instance behaviour of the COM server.

The code in question was originally developed by me in Delphi 2 back in the 90's and has been in production 24/7 since then in a completely "lights out" environment. The system is made up of a number of components, all of which use "peer to peer" OLE Automation; that is, each component is both a server and a client and they communicate with each other via OLE Automation. Each component does a FindWindow and only does the CreateOleObject if it finds the server it is looking for is already running.

I'm trying to port 2 of the 5 components in this system to Delphi 10 so that their interface to another program (Lotus Notes) can be changed from OLE Automation to COM (Delphi 2 doesn't support COM, only OLE, otherwise I would still be using Delphi 2.). The code is complex and I really need to be able to run it in the Delphi debugger but, as I indicated, it only works when it is not run from Delphi 10 -- this is a change from Delphi 2.. Porting all the components in the system to Delphi 10 is not really an option since the other components are tightly integrated with another product and the communication is multi-threaded, so the port would be very difficult. As a result, I can't change to using GetActiveObject, I need to get CreateOleObject to work within the Delphi IDE as it does outside the IDE.
Sean Keeley

Posts: 6
Registered: 12/9/15
Re: Making Multi-Instance COM Server Work When Started in Delphi 10 Seattle IDE [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 28, 2016 2:03 PM   in response to: Peter Below in response to: Peter Below
Peter Below wrote:
Sean Keeley wrote:

I have found that a multi-instance (the default) COM Server created
in Delphi 10 Seattle Update 1 does not work correctly when it is
started from within the IDE, either with or without debugging.

With the COM Server running, a CreateOleObject in another Delphi
program or a CreateObject in VBS script will create a new instance
rather than connect to the running instance. This does not happen
when the COM Server is run from Windows Explorer.

Is there something I need to do in the COM Server to make this work
or is this a bug in Delphi?

Is this a out-of-process server (a EXE, not a DLL)? Does it register
itself into the running objects table? What you see is actually the
default, a client wanting to connect to a running instance of the COM
server has to explicitely request that by using GetActiveObject instead
of CreateOleObject/CoCreateInstance. If several instance may be running
and registered with the ROT you have to get an interface for the ROT
first and enumerate the instances to find the one you want to connect
to.

--
Peter Below
TeamB

Further information ... I tried using GetActiveOleObject in Delphi 10 and if the server is started via Explorer, the GetActiveOleObject works as expected but if the server is started from within the Delphi IDE the GetActiveOleObject call gets an EOleSysError with message ‘Operation unavailable’.
Peter Below

Posts: 1,227
Registered: 12/16/99
Re: Making Multi-Instance COM Server Work When Started in Delphi 10 Seattle IDE [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 29, 2016 9:44 AM   in response to: Sean Keeley in response to: Sean Keeley
Sean Keeley wrote:

Peter Below wrote:
Sean Keeley wrote:

I have found that a multi-instance (the default) COM Server
created in Delphi 10 Seattle Update 1 does not work correctly
when it is started from within the IDE, either with or without
debugging.

With the COM Server running, a CreateOleObject in another Delphi
program or a CreateObject in VBS script will create a *new
instance* rather than connect to the running instance. This does
not happen when the COM Server is run from Windows Explorer.

Is there something I need to do in the COM Server to make this
work or is this a bug in Delphi?

Is this a out-of-process server (a EXE, not a DLL)? Does it register
itself into the running objects table? What you see is actually the
default, a client wanting to connect to a running instance of the
COM server has to explicitely request that by using GetActiveObject
instead of CreateOleObject/CoCreateInstance. If several instance
may be running and registered with the ROT you have to get an
interface for the ROT first and enumerate the instances to find the
one you want to connect to.

--
Peter Below
TeamB

Further information ... I tried using GetActiveOleObject in Delphi 10
and if the server is started via Explorer, the GetActiveOleObject
works as expected but if the server is started from within the Delphi
IDE the GetActiveOleObject call gets an EOleSysError with message
‘Operation unavailable’.

At least that shows that the server is registering itself with the ROT
when run normally. Do you run it for debugging from the IDE, or without
debugging? That may make a difference here. Also, do you run the IDE
under a different account (for example run as admin)? That would also
influence the behaviour since the started process runs under the same
account the IDE runs under.


--
Peter Below
TeamB

Sean Keeley

Posts: 6
Registered: 12/9/15
Re: Making Multi-Instance COM Server Work When Started in Delphi 10 Seattle IDE [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 29, 2016 10:38 AM   in response to: Peter Below in response to: Peter Below
Peter Below wrote:
Sean Keeley wrote:

Peter Below wrote:
Sean Keeley wrote:

I have found that a multi-instance (the default) COM Server
created in Delphi 10 Seattle Update 1 does not work correctly
when it is started from within the IDE, either with or without
debugging.

With the COM Server running, a CreateOleObject in another Delphi
program or a CreateObject in VBS script will create a *new
instance* rather than connect to the running instance. This does
not happen when the COM Server is run from Windows Explorer.

Is there something I need to do in the COM Server to make this
work or is this a bug in Delphi?

Is this a out-of-process server (a EXE, not a DLL)? Does it register
itself into the running objects table? What you see is actually the
default, a client wanting to connect to a running instance of the
COM server has to explicitely request that by using GetActiveObject
instead of CreateOleObject/CoCreateInstance. If several instance
may be running and registered with the ROT you have to get an
interface for the ROT first and enumerate the instances to find the
one you want to connect to.

--
Peter Below
TeamB

Further information ... I tried using GetActiveOleObject in Delphi 10
and if the server is started via Explorer, the GetActiveOleObject
works as expected but if the server is started from within the Delphi
IDE the GetActiveOleObject call gets an EOleSysError with message
‘Operation unavailable’.

At least that shows that the server is registering itself with the ROT
when run normally. Do you run it for debugging from the IDE, or without
debugging? That may make a difference here. Also, do you run the IDE
under a different account (for example run as admin)? That would also
influence the behaviour since the started process runs under the same
account the IDE runs under.


--
Peter Below
TeamB


The problem happens whenever the server is run under the IDE either with or without debugging.
I run the IDE as an Administrator but it is not a separate account.

I'm about to raise a support case with Embarcadero on this issue. I'll update this thread if I
learn anything new.

UPDATE

Raised the support case and got a response email within the hour (very impressed). Over the course of the afternoon, had several email exchanges but the support engineer could not reproduce the issue so it looks like it's some kind of weird issue with my machine. Good to know for everyone else, but bad news for me. Will update again if I find anything of general interest.

Edited by: Sean Keeley on Jan 29, 2016 3:38 PM
Sean Keeley

Posts: 6
Registered: 12/9/15
Re: Making Multi-Instance COM Server Work When Started in Delphi 10 Seattle IDE  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 4, 2016 11:24 AM   in response to: Sean Keeley in response to: Sean Keeley
Sean Keeley wrote:
I have found that a multi-instance (the default) COM Server created in Delphi 10 Seattle Update 1 does not work correctly when it is started from within the IDE, either with or without debugging.

With the COM Server running, a CreateOleObject in another Delphi program or a CreateObject in VBS script will create a new instance rather than connect to the running instance. This does not happen when the COM Server is run from Windows Explorer.

Is there something I need to do in the COM Server to make this work or is this a bug in Delphi?

Edited by: Sean Keeley on Jan 27, 2016 3:45 PM

SOLVED. What was happening was a security feature of Windows 7 of which I was not aware. With the default Windows 7 UAC settings, a COM server running as an administrator will not accept a connection from a COM client unless the client is also running as an administrator. Since I was running the Delphi IDE as an administrator to work around the (to me) bug that the IDE does not elevate when registering a type library or a server, the COM server run under the IDE was also running as administrator causing non-admin programs to start a second copy of the COM server.

After much back and forth with Embarcadero support (excellent support BTW), it was determined that Embarcadero could not reproduce my problem because they had changed the UAC default on their machines by disabling the Local Security Option "Run all administrators in Admin Approval Mode". This has a side-effect of allowing non-admin COM clients to connect to an admin COM server.
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Making Multi-Instance COM Server Work When Started in Delphi 10Seattle IDE  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 4, 2016 11:47 AM   in response to: Sean Keeley in response to: Sean Keeley
Sean wrote:

SOLVED. What was happening was a security feature of Windows 7 of
which I was not aware. With the default Windows 7 UAC settings, *a
COM server running as an administrator will not accept a connection
from a COM client unless the client is also running as an administrator*.

Or, if the COM server uses CoInitializeSecurity() at startup to allow non-admin
clients to connect to it.

--
Remy Lebeau (TeamB)
Sean Keeley

Posts: 6
Registered: 12/9/15
Re: Making Multi-Instance COM Server Work When Started in Delphi 10Seattle IDE  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 4, 2016 11:54 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
Sean wrote:

SOLVED. What was happening was a security feature of Windows 7 of
which I was not aware. With the default Windows 7 UAC settings, *a
COM server running as an administrator will not accept a connection
from a COM client unless the client is also running as an administrator*.

Or, if the COM server uses CoInitializeSecurity() at startup to allow non-admin
clients to connect to it.

--
Remy Lebeau (TeamB)

Do you know if there is a way to have the standard Delphi 10 library use CoInitializeSecurity()? I'm just using the normal COM server initialization code generated by the Com server wizard.
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Making Multi-Instance COM Server Work When Started in Delphi10Seattle IDE  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 4, 2016 11:59 AM   in response to: Sean Keeley in response to: Sean Keeley
Sean wrote:

Do you know if there is a way to have the standard Delphi 10
library use CoInitializeSecurity()?

No, I do not. I just call it manually at program startup.

--
Remy Lebeau (TeamB)
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02