COM Macro Architecture Topology - Servers





5.00/5 (15 votes)
Jul 25, 2001
27 min read

167599
An article about COM Architecture, COM Servers, COM DLL Servers and the Registry
Overview
Purpose
This article shows how to implement a COM Server in 3 different configurations:
- The COM Server as an executable.
- 2 DLLs, one is the COM DLL Server and the other the Proxy/Stub DLL.
- 1 single DLL in which the COM Server and the Proxy/Stub are merged into.
Although Servers seem different, mostly steps to build and implement COM objects and interfaces into them are common.
Here I will not explain how to make a COM Server as a Windows NT service. In fact, you can see this option in the same way as a COM Executable Server with:
- More functions in order to register the service with the operating system.
- Some restrictions when you register your COM Server.
- Some restrictions in using the Windows API.
Requirements
All the code in these samples have been written in C++, using Visual C++ 6.0 (sp4) under Windows 2000. They also use the Active-X Template Library (ATL v3.0).Other articles in this series
This article is part of a series called "COM Macro-Architecture Topology". Here are the links to other articles:- the main article, "COM Macro-Architecture Topology"
- The client application, "COM Macro-Architecture Topology (Client)".
- COM IDs & Registry keys in a nutshell.
COM Servers
General
All the Server presented in this article are composed of one COM class (or CoClass) calledCoMacroTopo
. It exposes two COM interfaces:
IMacroTopoDisp
, it is a dispatch interface.IMacroTopoCustom
, it is a custom interface.
ShowHello()
, which displays a message box within it the "Hello" message.Add(A, B) : C
, which adds "A" and "B" (numbers) and return the result in "C".
ShowHelloCustom()
and AddCustom()
. 
- Choose a Server Type such as an Executable, 2 DLLs or 1 DLL allowing proxy merged.
- Edit project settings (for 1 DLL allowing proxy merged, click here).
- Create the CoClass definition.
- Add
methods to
IMacroTopoDisp.
. - Add
the new interface
IMacroTopoCustom
. - Build the project.
- Register the server (Executable, 2 DLLs or 1 DLL allowing proxy merged).
- Configure the security for your Server.
- Unregister the server (Executable, 2 DLLs or 1 DLL allowing proxy merged).
The "copy files to target machine" and the "remove files from the target machine" process have not been taken into account in this article. Obviously, in real situation you should consider them: the former will be just after Step 6 and the latter after Step 9.
The Executable configuration
To build the COM Server as an executable, follow the steps
define in the General's
section.
Step 1 - Choose the Server Type 
To create the server, you have to follow the steps below
:- Start the Visual C++ IDE and Select File, New and fill in like below:

- You want to create an Executable Server so choose Server type's option like that:

After that, the ATL COM wizard will create these files :
- Workspace:
macrotoposerver_exe.dsw
- Project:
macrotoposerver_exe.dsp
- Initialisation code in
macrotoposerver_exe.cpp
andmacrotoposerver_exe.h
- IDL source in
macrotoposerver_exe.idl
- and files for the Proxy/Stub DLL:
macrotoposerver_exeps.mk
macrotoposerver_exeps.def
MACROTOPOSERVER_EXE.EXE
.
Step 2 to 6 and 8 - Common part 
Follow the common steps: step
2, step
3, step
4, step
5, step
6, and step
8.
Step 7 - Register your Server 
As you have used the ATL Wizard to generate your
project, it automatically added the command to register your server (in the
Project Settings window, in the tab of the Custom build). However,
it does not do anything for the Proxy/Stub DLL, so you have to do it
yourself.You also have to consider that generally the build machine is different from the client or server machine.
Local consideration
To register manually, in your build machine, do like that (in this order):- To register the Proxy/Stub file (MACROTOPOSERVER_EXEPS.DLL):
- Open a DOS-Command window and go to your project's directory,
- type the command ">
regsvr32 macrotoposerver_exeps.dll
".
- To register the COM server file (MACROTOPOSERVER_EXE.EXE):
- Open a DOS-Command window and go to your project's directory,
- go to your built directory (e.g.
\Debug
) - type the command ">
MACROTOPOSERVER_EXE.EXE -RegServer
".
Remote consideration
In this case, you have to perform two installations: one on the client machine and the other on the server machine. Here are the instructions for both:- On the client machine
- Register the Proxy/Stub file (MACROTOPOSERVER_EXEPS.DLL)
using the command line ">regsvr32 MACROTOPOSERVER_EXEPS.DLL
".
- Register the remote server entries.
Generally we do not want (and we do not need) to register the full Server component on the Client machine. In that case, we need to create a registry file to add the necessary keys to enable the remote access of our component on the Server machine. So, create a new text file with the extension".reg"
(e.g.registry_client_exe.reg
) and add these lines to it:[HKEY_CLASSES_ROOT\CLSID\{12345678-0000-0000-0000-abababababab}] @="CoMacroTopo Class" "AppID"="{AppID_GUIDGEN_BY_ATL}" [HKEY_CLASSES_ROOT\AppID\{AppID_GUIDGEN_BY_ATL}] @="macrotoposerver_exe" "RemoteServerName"="myservercomputer"
"myservercomputer" is the machine name where the COM Server is installed.
The AppID "{AppID_GUIDGEN_BY_ATL}" has been generated by the ATL wizard and you can find it (not the same value) on your resource files (e.g.CoMacroTopo.rgs
ormacrotoposerver_exe.rgs
). So, keep with the same value because it is now part of your Executable file.
If you have more than one COM Class object in your server (here, you have only CoMacroTopo), you have to repeat the first 3 lines for eachCLSID
you have. Nevertheless, keep with the same value for the "AppID" key:[HKEY_CLASSES_ROOT\CLSID\{<another COM Class ID>}] @="CoAnother Class" "AppID"="{AppID_GUIDGEN_BY_ATL}" ...
Now you have to register all this information on the registry. Using Windows Explorer, double-click on your file. The registry will ask you if you want to add this information to the current registry (if you have the administrator rights) click "Yes" and that is it.
- Register the Proxy/Stub file (MACROTOPOSERVER_EXEPS.DLL)
- On the server machine
- Register the Proxy/Stub file (MACROTOPOSERVER_EXEPS.DLL)
by using the command line ">regsvr32 MACROTOPOSERVER_EXEPS.DLL
".
- Register the server entries stored in your executable file
(MACROTOPOSERVER_EXE.EXE)
by using the command line ">MACROTOPOSERVER_EXE.EXE -RegServer
".
- Register the Proxy/Stub file (MACROTOPOSERVER_EXEPS.DLL)
Step 9 - Unregister your Server 
Local consideration
To unregister manually do like that:- Unregister the Proxy/Stub file (MACROTOPOSERVER_EXEPS.DLL):
- Open a DOS-Command window and go to your project's directory,
- type the command ">
regsvr32 /u MACROTOPOSERVER_EXEPS.DLL
"
- Unregister the COM server file (MACROTOPOSERVER_EXE.EXE):
- Open a DOS-Command window and go to your project's directory,
- go to your built directory where is your registered file (e.g.
\Debug
) - type the command ">
MACROTOPOSERVER_EXE.EXE -UnregServer
"
Remote consideration
To unregister manually do like that:- On the client machine
- Unregister the Proxy/Stub file (MACROTOPOSERVER_EXEPS.DLL)
by using the command line ">regsvr32 /u MACROTOPOSERVER_EXEPS.DLL
".
- Unregister the remote server entries.
You have to remove them manually using the information you have used during the registration step (the registry file created with the extension".reg"
).
So, launch the Registry Editor (REGEDIT.EXE), then look for the entries you added before (at least 2) like these:[HKEY_CLASSES_ROOT\AppID\{AppID_GUIDGEN_BY_ATL}] [HKEY_CLASSES_ROOT\CLSID\{CLSID_value}]
And remove them.
If you have more than one COM Class object in your server (here, we have only CoMacroTopo) you might have added more than one CLSID. In this case, you should remove all these entries.
- Unregister the Proxy/Stub file (MACROTOPOSERVER_EXEPS.DLL)
- On the server machine
- Unregister the Proxy/Stub file (MACROTOPOSERVER_EXEPS.DLL)
by using the command line ">regsvr32 /u MACROTOPOSERVER_EXEPS.DLL
".
- Unregister the server entries stored in your server machine registry by
using the command line ">MACROTOPOSERVER_EXE.EXE -UnregServer
".
- Unregister the Proxy/Stub file (MACROTOPOSERVER_EXEPS.DLL)
The 2 DLLs configuration
To build the COM Server as 2 DLLs, follow the steps define
in the General's
section.
Step 1 - Choose the Server Type 
To create the server, you have to follow the steps below
:
- Start the Visual C++ IDE and Select File, New and fill in like below:
- You want to create a DLL Server without merging the Proxy/Stub code, so choose Server type's option like that:

After that, the ATL COM wizard will create these files :
- Workspace:
macrotoposerver_dll_psdll.dsw
- Project:
macrotoposerver_dll_psdll.dsp
- Initialisation code in
macrotoposerver_dll_psdll.cpp
andmacrotoposerver_exe.h
- IDL source in
macrotoposerver_dll_psdll.idl
- and files for the Proxy/Stub DLL:
macrotoposerver_dll_psdllps.mk
macrotoposerver_dll_psdllps.def
MACROTOPOSERVER_DLL_PSDLL.DLL
.
Step 2 to 6 and 8 - Common part 
Follow the common steps: step
2, step
3, step
4, step
5, step
6, and step
8.
Step 7 - Register your Server 
As you have used the ATL Wizard to generate your
project, it automatically added the command to register your server (in the
Project Settings window, in the tab of the Custom build). However,
it does not do anything for the Proxy/Stub DLL, so you have to do it
yourself.You also have to consider that generally the build machine is different from the client or server machine.
Local In-process consideration
To register manually, in your build machine, do like that (in that order):- To register the Proxy/Stub file (MACROTOPOSERVER_DLL_PSDLLPS.DLL):
- Open a DOS-Command window and go to your project's directory,
- type the command ">
regsvr32 MACROTOPOSERVER_DLL_PSDLLPS.DLL
"
- To register the COM DLL server file (MACROTOPOSERVER_DLL_PSDLL.DLL):
- Open a DOS-Command window and go to your project's directory,
- go to your built directory (e.g.
\Debug
) - type the command ">
regsvr32 MACROTOPOSERVER_DLL_PSDLL.DLL
"
Remote consideration
In this case, you have to perform two installations: one on the client machine and the other on the server machine. Here are the instructions for both:- On the client machine
- Register the Proxy/Stub file (MACROTOPOSERVER_DLL_PSDLLPS.DLL)
using the command line ">regsvr32 MACROTOPOSERVER_DLL_PSDLLPS.DLL
".
- Register the remote server entries.
Generally we do not want (and we do not need) to register the full Server component on the Client machine. In that case, we need to create a registry file to add the necessary keys to enable the remote access of our component on the Server machine. So, create a new text file with the extension".reg"
(e.g.registry_client_exe.reg
) and add these lines to it:[HKEY_CLASSES_ROOT\CLSID\{12345678-0000-0000-0000-abababababab}] @="CoMacroTopo Class" "AppID"="{AppID_GUIDGEN_BY_YOU}" [HKEY_CLASSES_ROOT\AppID\{AppID_GUIDGEN_BY_YOU}] @="MacroTopoServer_2dlls" "RemoteServerName"="myservercomputer"
"myservercomputer" is the machine name where the COM Server is installed.
If you have more than one COM Class object in your server (here, you have only CoMacroTopo), you have to repeat the first 3 lines for eachCLSID
value you have. However, keep with the same value of AppID_GUIDGEN_BY_YOU for the "AppID" key:[HKEY_CLASSES_ROOT\CLSID\{<another COM Class ID>}] @="CoAnother Class" "AppID"="{AppID_GUIDGEN_BY_YOU}" ...
Now you have to register all this information on the registry. Using Windows Explorer, double-click on your file. The registry will ask you if you want to add this information to the current registry (if you have the administrator rights) click "Yes" and that is it.
- Register the Proxy/Stub file (MACROTOPOSERVER_DLL_PSDLLPS.DLL)
- On the server machine
- Register the Proxy/Stub file (MACROTOPOSERVER_DLL_PSDLLPS.DLL)
by using the command line ">regsvr32 MACROTOPOSERVER_DLL_PSDLLPS.DLL
".
- Register the server entries stored in your server file
(MACROTOPOSERVER_DLL_PSDLL.DLL)
by using the command line ">regsvr32 MACROTOPOSERVER_DLL_PSDLL.DLL
".
- Register the server entries indicating the use of the DLL surrogate
application.
You need to create a registry file to add the necessary keys to enable the management of our component by the DLL Surrogate application. So, create a new text file with the extension".reg"
(e.g.registry_server_exe.reg
) and add these lines to it:[HKEY_CLASSES_ROOT\CLSID\{12345678-0000-0000-0000-abababababab}] "AppID"="{AppID_GUIDGEN_BY_YOU}" [HKEY_CLASSES_ROOT\AppID\{AppID_GUIDGEN_BY_YOU}] @="MacroTopoServer_2dlls" "DllSurrogate"=""
The main point is to permit our COM DLL server to be launched using the surrogate application. Here, the value is an empty field "" which means that COM will use the default one provided with by the system (e.g. the default surrogate application on Windows NT 4.0 and Windows 2000 is DLLHOST.EXE).
If you have more than one COM Class object in your server (here, you have only CoMacroTopo), you have to repeat the first 3 lines for eachCLSID
you have. However, keep with the same value for the "AppID_GUIDGEN_BY_YOU" key:[HKEY_CLASSES_ROOT\CLSID\{<another COM Class ID>}] @="CoAnother Class" "AppID"="{AppID_GUIDGEN_BY_YOU}" ...
Now you have to register all this information on the registry. Using Windows Explorer, double-click on your file. The registry will ask you if you want to add this information to the current registry (if you have the administrator rights) click "Yes" and that is it.
- Register the Proxy/Stub file (MACROTOPOSERVER_DLL_PSDLLPS.DLL)
Local Surrogate consideration
You can as well look for a variant configuration that uses your COM DLL Server on the same machine as your client application but outside of the client process.Nonetheless, a DLL can never run without a parent process. COM provides a default DLL surrogate application that can load your COM DLL Server and provide it a process environment.
In order to do like that, you have just to do the same things as explain on the section above (Remote Consideration) and follow the instructions below "On the server machine".
Of course you have to execute them on the Server machine, i.e. in this case the same as your Client machine (here we are interested in the Local Surrogate consideration).
Now, you have to change your client code and ask explicitly for loading the COM DLL Server in a separate process space (runs on the same machine but in a different process) using the DLL Surrogate application.
To indicate to COM that you want to create your object in the different process space you have to use the Flag CLSCTX_LOCAL_SERVER (and only this flag) on the CoCreateInstance() call, CoCreateInstanceEx() call or on the ATL Interface smart pointer constructor like this:
... IMacroTopoDispPtr pDisp(__uuidof(CoMacroTopo), NULL, CLSCTX_LOCAL_SERVER); long lA(500), lB(114); long lResultat = pDisp->Add(lA,lB); ...A remark about the relation between a COM DLL server and a DLL surrogate application. COM DLL servers are loaded, by default, into their own surrogate process. If for some reasons, you need to load other COM DLL servers into an existing surrogate process, so it supports more than one COM DLL servers, there are two requirements:
- The COM DLL servers must have the same AppID value.
- The security context of the COM DLL servers must be the same. This means that they have matching security identities.
Step 9 - Unregister your Server 
Local In-process consideration
To unregister manually do like that:- Unregister the Proxy/Stub file (MACROTOPOSERVER_DLL_PSDLLPS.DLL):
- Open a DOS-Command window and go to your project's directory,
- type the command ">
regsvr32 /u MACROTOPOSERVER_DLL_PSDLLPS.DLL
"
- Unregister the COM DLL server file (MACROTOPOSERVER_DLL_PSDLL.DLL):
- Open a DOS-Command window and go to your project's directory,
- go to your built directory where is your registered file (e.g.
\Debug
) - type the command ">
regsvr32 /u MACROTOPOSERVER_DLL_PSDLL.DLL
"
Remote consideration
To unregister manually do like that:- On the client machine
- Unregister the Proxy/Stub file (MACROTOPOSERVER_DLL_PSDLLPS.DLL)
by using the command line ">regsvr32 /u MACROTOPOSERVER_DLL_PSDLLPS.DLL
".
- Unregister the remote server entries.
You have to remove them manually using the information you have used during the registration step (the registry file created with the extension".reg"
).
So, launch the Registry Editor (REGEDIT.EXE), then look for the entries you added before (at least 2) like these:[HKEY_CLASSES_ROOT\AppID\{AppID_GUIDGEN_BY_YOU}] [HKEY_CLASSES_ROOT\CLSID\{CLSID_value}]
And remove them.
If you have more than one COM Class object in your server (here, we have only CoMacroTopo) you might have added more than one CLSID. In this case, you should remove all these entries.
- Unregister the Proxy/Stub file (MACROTOPOSERVER_DLL_PSDLLPS.DLL)
- On the server machine
- Unregister the Proxy/Stub file (MACROTOPOSERVER_DLL_PSDLLPS.DLL)
by using the command line ">regsvr32 /u MACROTOPOSERVER_DLL_PSDLLPS.DLL
".
- Unregister the COM DLL server entries stored in your server machine
registry by
using the command line ">regsvr32 /u MACROTOPOSERVER_DLL_PSDLL.DLL
".
- Unregister the Surrogate server entries.
You have to remove them manually using the information you have used during the registration step (the registry file created with the extension".reg"
).
So, launch the Registry Editor (REGEDIT.EXE), then look for the entry AppID_GUIDGEN_BY_YOU you added before :[HKEY_CLASSES_ROOT\AppID\{AppID_GUIDGEN_BY_YOU}]
And remove it. You do not need to remove the CLSID_value key(s):[HKEY_CLASSES_ROOT\CLSID\{CLSID_value}]
because when you unregister your COM DLL server it will do it for you.
- Unregister the Proxy/Stub file (MACROTOPOSERVER_DLL_PSDLLPS.DLL)
Local Surrogate consideration
In order to do like that, you have just to do the same things as explain on the section above (Remote Consideration) and follow the instructions below "On the server machine".Of course you have to execute them on the Server machine, i.e. in this case the same as your Client machine (here we are interested in the Local Surrogate consideration).
The Single DLL configuration (or merged)
To build the COM Server as a single DLL, you have to follow
the steps define in the General's
section (1 DLL).
Step 1 - Choose the Server Type 
To create the server, you have to follow the steps
below:- Start the Visual C++ IDE and Select File, New and fill in like below:

- You want to create a DLL Server with merging the Proxy/Stub code, so choose Server type's option like that:

After that, the ATL COM wizard will create these files :
- Workspace:
macrotoposerver_dllmerged.dsw
- Project:
macrotoposerver_dllmerged.dsp
- Initialisation code in
macrotoposerver_dllmerged.cpp
andmacrotoposerver_exe.h
- IDL source in
macrotoposerver_dllmerged.idl
- and files for the Proxy/Stub DLL:
macrotoposerver_dllmergedps.mk
macrotoposerver_dllmergedps.def
Therefore, although you have asked to have the Proxy/Stub code merged you get the necessary code to build a Proxy/Stub DLL file.
The final COM Server name is
MACROTOPOSERVER_DLLMERGED.DLL
.
Step 2 - Edit project settings 
You have to follow the general instructions at Common
Step 2 - Edit project settings. Although you have checked the checkbox "allow merging of Proxy/Stub code", this is not enough to build your COM DLL Server with the merged code.
So, In the project settings do as follow:
- Choose "All configurations", be sure that the project node is selected.
- In the C++ tab:
- In the Pre-processor definitions go to the end, append a comma and add _MERGE_PROXYSTUB

- Select the dlldatax.c file and always for All configurations.
- In the General tab:
- Uncheck the Exclude file from build.

- Now, go to the C++ tab:
- Select Precompiled Headers in the Category drop down list-box.
- Select the Not using precompiled headers choice.
- And press OK.

The file dlldatax.c includes dlldata.c and file(s) called like "your_idl_filename_p.c". The former contains code for the necessary COM entry points for the COM DLL Server, such as DllGetClassObject. The latter contains code to marshal (i.e. the Proxy/Stub code) all Interfaces defined in the IDL file. These files are generated by the MIDL compiler (Microsoft IDL compiler) deliver with the Win32 SDK.
Step 3 to 6 and 8 - Common part 
Follow the common steps: step
3, step
4, step
5, step
6, and step
8.
Step 7 - Register your Server 
As you have used the ATL Wizard to generate your
project, it automatically added the command to register your server (in the
Project Settings window, in the tab of the Custom build). However,
it does not do anything for the Proxy/Stub DLL, so you have to do it
yourself.You also have to consider that generally the build machine is different from the client or server machine.
Local In-process consideration
To register manually, in your build machine, do like that:- To register the COM DLL server file (MACROTOPOSERVER_DLLMERGED.DLL):
- Open a DOS-Command window and go to your project's directory,
- go to your built directory (e.g.
\Debug
) - type the command ">
regsvr32 MACROTOPOSERVER_DLLMERGED.DLL
"
Here, the Proxy/Stub code is register at the same time.
Remote consideration
In this case, you have to perform two installations: one on the client machine and the other on the server machine. Here are the instructions for both:- On the client machine
- Register the Proxy/Stub file (MACROTOPOSERVER_DLLMERGEDPS.DLL)
using the command line ">regsvr32 MACROTOPOSERVER_DLLMERGEDPS.DLL
".
- Register the remote server entries.
Generally we do not want (and we do not need) to register the full Server component on the Client machine. In that case, we need to create a registry file to add the necessary keys to enable the remote access of our component on the Server machine. So, create a new text file with the extension".reg"
(e.g.registry_client_exe.reg
) and add these lines to it:[HKEY_CLASSES_ROOT\CLSID\{12345678-0000-0000-0000-abababababab}] @="CoMacroTopo Class" "AppID"="{AppID_GUIDGEN_BY_YOU}" [HKEY_CLASSES_ROOT\AppID\{AppID_GUIDGEN_BY_YOU}] @="MacroTopoServer_dllmerged" "RemoteServerName"="myservercomputer"
"myservercomputer" is the machine name where the COM Server is installed.
If you have more than one COM Class object in your server (here, you have only CoMacroTopo), you have to repeat the first 3 lines for eachCLSID
value you have. However, keep with the same value of AppID_GUIDGEN_BY_YOU for the "AppID" key:[HKEY_CLASSES_ROOT\CLSID\{<another COM Class ID>}] @="CoAnother Class" "AppID"="{AppID_GUIDGEN_BY_YOU}" ...
Now you have to register all this information on the registry. Using Windows Explorer, double-click on your file. The registry will ask you if you want to add this information to the current registry (if you have the administrator rights) click "Yes" and that is it.
- Register the Proxy/Stub file (MACROTOPOSERVER_DLLMERGEDPS.DLL)
- On the server machine (in that
order)
- Register the server entries stored in your server file
(MACROTOPOSERVER_DLLMERGED.DLL)
by using the command line ">regsvr32 MACROTOPOSERVER_DLLMERGED.DLL
".
- Register the server entries indicating the use of the DLL surrogate
application.
You need to create a registry file to add the necessary keys to enable the management of our component by the DLL Surrogate application. So, create a new text file with the extension".reg"
(e.g.registry_server_exe.reg
) and add these lines to it:[HKEY_CLASSES_ROOT\CLSID\{12345678-0000-0000-0000-abababababab}] "AppID"="{AppID_GUIDGEN_BY_YOU}" [HKEY_CLASSES_ROOT\AppID\{AppID_GUIDGEN_BY_YOU}] @="MacroTopoServer_dllmerged" "DllSurrogate"=""
The main point is to permit our COM DLL server to be launched using the surrogate application. Here, the value is an empty field "" which means that COM will use the default one provided with by the system (e.g. the default surrogate application on Windows NT 4.0 and Windows 2000 is DLLHOST.EXE).
If you have more than one COM Class object in your server (here, you have only CoMacroTopo), you have to repeat the first 3 lines for eachCLSID
you have. However, keep with the same value for the "AppID_GUIDGEN_BY_YOU" key:[HKEY_CLASSES_ROOT\CLSID\{<another COM Class ID>}] @="CoAnother Class" "AppID"="{AppID_GUIDGEN_BY_YOU}" ...
Now you have to register all this information on the registry. Using Windows Explorer, double-click on your file. The registry will ask you if you want to add this information to the current registry (if you have the administrator rights) click "Yes" and that is it.
- Register the server entries stored in your server file
(MACROTOPOSERVER_DLLMERGED.DLL)
Local Surrogate consideration
You can as well look for a variant configuration that uses your COM DLL Server on the same machine as your client application but outside of the client process.Nonetheless, a DLL can never run without a parent process. COM provides a default DLL surrogate application that can load your COM DLL Server and provide it a process environment.
In order to do like that, you have just to do the same things as explain on the section above (Remote Consideration) and follow the instructions below "On the server machine".
Of course you have to execute them on the Server machine, i.e. in this case the same as your Client machine (here we are interested in the Local Surrogate consideration).
You have to register the Proxy/Stub DLL file for your client application as well:
- Register the Proxy/Stub file (MACROTOPOSERVER_DLLMERGEDPS.DLL)
by using the command line ">regsvr32 MACROTOPOSERVER_DLLMERGEDPS.DLL
".
Now, you have to
change your client code and ask explicitly for loading the COM DLL Server
in a separate process space (runs on the same machine but in a different
process) using the DLL Surrogate application.
To indicate to COM that you
want to create your object in the different process space you have to use the
Flag CLSCTX_LOCAL_SERVER (and only this flag) on the CoCreateInstance()
call, CoCreateInstanceEx() call or on the ATL Interface smart pointer
constructor like this:
... IMacroTopoDispPtr pDisp(__uuidof(CoMacroTopo), NULL, CLSCTX_LOCAL_SERVER); long lA(500), lB(114); long lResultat = pDisp->Add(lA,lB); ...A remark about the relation between a COM DLL server and a DLL surrogate application. COM DLL servers are loaded, by default, into their own surrogate process. If for some reasons, you need to load other COM DLL servers into an existing surrogate process, so it supports more than one COM DLL servers, there are two requirements:
- The COM DLL servers must have the same AppID value.
- The security context of the COM DLL servers must be the same. This means that they have matching security identities.
Step 9 - Unregister your Server 
Local In-process consideration
To unregister manually do like that:- Unregister the COM DLL server file (MACROTOPOSERVER_DLLMERGED.DLL):
- Open a DOS-Command window and go to your project's directory,
- go to your built directory where is your registered file (e.g.
\Debug
) - type the command ">
regsvr32 /u MACROTOPOSERVER_DLLMERGED.DLL
"
- On the client machine
- Unregister the Proxy/Stub file (MACROTOPOSERVER_DLLMERGEDPS.DLL)
by using the command line ">regsvr32 /u MACROTOPOSERVER_DLLMERGEDPS.DLL
".
- Unregister the remote server entries.
You have to remove them manually using the information you have used during the registration step (the registry file created with the extension".reg"
).
So, launch the Registry Editor (REGEDIT.EXE), then look for the entries you added before (at least 2) like these:[HKEY_CLASSES_ROOT\AppID\{AppID_GUIDGEN_BY_YOU}] [HKEY_CLASSES_ROOT\CLSID\{CLSID_value}]
And remove them.
If you have more than one COM Class object in your server (here, we have only CoMacroTopo) you might have added more than one CLSID, In this case, you should remove all these entries.
- Unregister the Proxy/Stub file (MACROTOPOSERVER_DLLMERGEDPS.DLL)
- On the server machine
- Unregister the COM DLL server entries stored in your server machine
registry by
using the command line ">regsvr32 /u MACROTOPOSERVER_DLLMERGED.DLL
".
- Unregister the Surrogate server entries.
You have to remove them manually using the information you have used during the registration step (the registry file created with the extension".reg"
).
So, launch the Registry Editor (REGEDIT.EXE), then look for the entry AppID_GUIDGEN_BY_YOU you added before :[HKEY_CLASSES_ROOT\AppID\{AppID_GUIDGEN_BY_YOU}]
And remove it. You do not need to remove the CLSID_value key(s):[HKEY_CLASSES_ROOT\CLSID\{CLSID_value}]
because when you unregister your COM DLL server it will do it for you.
- Unregister the COM DLL server entries stored in your server machine
registry by
Local Surrogate consideration
In order to do like that, you have just to do the same things as explain on the section above (Remote Consideration) and follow the instructions below "On the server machine".Of course you have to execute them on the Server machine, i.e. in this case the same as your Client machine (here we are interested in the Local Surrogate consideration).
You have to unregister the Proxy/Stub DLL file:
- Unregister the Proxy/Stub file (MACROTOPOSERVER_DLLMERGEDPS.DLL)
by using the command line ">regsvr32 /u MACROTOPOSERVER_DLLMERGEDPS.DLL
".
Common steps
Step 2 - Edit project settings 
In the project settings, I generally do those changes in
order to avoid launching a makefile from the command line for the Proxy/Stub
DLL:- Choose "All configurations",
- In the Post-build step's tab:
- Write a Post-build description,
- Create a new Post-build command as " nmake -f " + the Proxy/Stub
DLL makefile (e.g.
macrotoposerver_exeps.mk
), - And press OK.

Step 3 - Create the CoClass definition 
Now lets insert our COM object and its Interface.
- Select Insert and New ATL Object :

- Double click on simple object (or click on Next) and in the
Names' tab:
- Enter the Short Name as CoMacroTopo
- Enter the Interface name as IMacroTopoDisp

- In the Attributes' tab:
- Choose Both as value for Threading model,
- Dual (default) as value for Interface,
- Yes (default) as value for aggregation,
- Add Support ISupportErrorInfo,
- And press OK.

Step 4 - Adding methods to IMacroTopoDisp

Now lets insert our methods.
- Go to the ClassView's tab in the Workspace window,
- Select the
IMacrotTopDisp
item (the one from the root node and not from theCCoMacroTopo
node), - using the right click mouse button, select Add method... from the popup menu.

- Enter the Method Name as ShowHello
- And press OK.

Let's do the same for the second method:
- do the same steps as before to open the "Add method dialog box",
- Enter the Method Name as Add
- Enter the Parameters as [in] long A, [in] long B, [out, retval] long* C
- And press OK.

To edit the code implementation of those methods you have to:
- Go to the ClassView's tab in the Workspace window,
- Open the
CCoMacroTopo
node item, - Open the
IMacrotTopDisp
node item, - Double-click on ShowHello() item.

Write the function's body like that:
STDMETHODIMP CCoMacroTopo::ShowHello() { // Display a message box. ::MessageBox(NULL, _T("Hello world ;~) - Dispatch"), _T("CoMacroTopoServer - Executable"), MB_OK); return(S_OK); } Do the same for the <CODE>Add() method and write the function's body like that:
STDMETHODIMP CCoMacroTopo::Add(long A, long B, long *C) { // Add : A + B. *C = A + B; return(S_OK); }
Step 5 - Adding a new Interface
IMacroTopoCustom

You will do it by hand as ATL wizard can not do it
(except if you want to create a new ATL CoCalss with a new Interface). The first
thing you must do is to edit the IDL file to add the new interface (For further
information look at "Learning DCOM" [Bi3]). The most relevant part of the IDL
file is: ...
[
object,
uuid(IID_GUIDGEN_BY_YOU),
helpstring("IMacroTopoCustom Interface")
]
interface IMacroTopoCustom : IUnknown
{
};
...
coclass CoMacroTopo
{
[default] interface IMacroTopoDisp;
interface IMacroTopoCustom;
};
You must use the GUID Generator (GUIDGEN.EXE) in order to
obtain your unique IID_GUIDGEN_BY_YOU (Interface ID).
Just remember you that a custom Interface can not be used from an Automated environment like VBScript. Custom interface does not inherit from IDispatch.
Edit the
declaration file for the CCoMacroTopo class
(CoMacroTopo.h
) and add the code in bold:
class ATL_NO_VTABLE CCoMacroTopo : public CComObjectRootEx<CComMultiThreadModel>, public CComCoClass<CCoMacroTopo, &CLSID_CoMacroTopo>, public ISupportErrorInfo, public IDispatchImpl<IMacroTopoDisp, &IID_IMacroTopoDisp, &LIBID_MACROTOPOSERVER_EXELib> , public IMacroTopoCustom public: CCoMacroTopo() { } DECLARE_REGISTRY_RESOURCEID(IDR_COMACROTOPO) DECLARE_PROTECT_FINAL_CONSTRUCT() BEGIN_COM_MAP(CCoMacroTopo) COM_INTERFACE_ENTRY(IMacroTopoDisp) COM_INTERFACE_ENTRY(IDispatch) COM_INTERFACE_ENTRY(ISupportErrorInfo) COM_INTERFACE_ENTRY(IMacroTopoCustom) END_COM_MAP() ... };Save the files (".idl" and ".h"). Visual will detect automatically these changes and updates interfaces and CoCLass objects in the ClassView's tab in the workspace window. So, now repeat the step for adding methods to an Interface (as you have done for the
IMacroTopoDisp
interface). Be careful, remember to select
the Interface node item before. Doing this, change the name of the methods
like that:
ShowHello()
toShowHelloCustom()
,Add()
toAddCustom()
.
IMacroTopeDisp
. STDMETHODIMP CCoMacroTopo::ShowHelloCustom() { // Display a message box. ::MessageBox(NULL, _T("Hello world ;~) - Custom"), _T("CoMacroTopoServer - Executable"), MB_OK); return(S_OK); } STDMETHODIMP CCoMacroTopo::AddCustom(long A, long B, long *C) { // Add : A + B. *C = A + B; return(S_OK); }
Step 6 - Compilation & Linking 
Ok, now you can compile and link:
- our COM Server (e.g.
MACROTOPOSERVER_EXE.EXE
) - our Proxy/Stub DLL (e.g.
MACROTOPOSERVER_EXEPS.DLL
)
Microsoft IDL compiler
Proxy/Stub DLL build
Step 8 - Configure the security of your Server 
To build and test the COM Server describe in this
article you do not need to do anything if your are using them as Local servers
(in-process or out-of-process). However, if you are testing them as Remote
servers you need at least to enable them to run with the Interactive user
account. This is due to display the Dialog box when you call
ShowHello().To enable the COM Server to use the Interactive user for activation launch DCOMCNFG.EXE application (you can use as well OLEVIEW.EXE):
- Scroll down the Applications list until finding your COM
application and select it (e.g.
MacroTopoServer_dllmerged
). - Click on Properties...

- Select the Identity tab.

- In the user account radio buttons, choose the Interactive User.
- Click on Ok and close the application.

Now, your component will be launched with the Interactive user account. This means also that if no one is connected, your component can not be launched as well. However, here we just need an account to test our component.
Other points
- CoClass and Interface name
CoClass and Interface (human readable) names are the same for the 3 servers. COM documentation refers these names at Logical name (e.g.IMacroTopoDisp
). However, each server has its own unique set of GUIDs (for Library ID, Interface ID and CoClass ID) which are different. COM documentation refers these names at Physical name (e.g.{12345678-ABCD-FEDC-A1B2-F1F2F3F4F5D5}
). For further information about COM GUIDs, click here.
To have the same logical name as another Interface or CoClass might happen, but does not matter since you have different Physical names, because COM will look after the Physical names. There is an exception with the ProgID as COM will look for a text name, but at the end, this logical name is coupled to a physical name (i.e. a CLSID).
That is one of the main concepts in COM: to be able to identify uniquely your coclasses and interfaces.
- COM Server as a Windows NT Service
- Currently only a single instance of a Win32 service may be running at a
given time on a machine. COM services must therefore register their class
objects on launch using REGCLS_MULTIPLEUSE to support multiple
clients.
- A COM Server running as a service has some API restrictions such as: it can not display dialog boxes or windows.
- Currently only a single instance of a Win32 service may be running at a
given time on a machine. COM services must therefore register their class
objects on launch using REGCLS_MULTIPLEUSE to support multiple
clients.