Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Is it possible to use an EXE Comserver registration free?

Status
Not open for further replies.

Olaf Doschke

Programmer
Oct 13, 2004
14,847
DE
Every EXE generated with VFP has an embedded manifest and it's easy to modify this by simple having a project.exe.manifest file within the same folder as your project.pjx.

(See
It's well known (for example from Rick Strahl) how to embed information about a COM Server DLL like this:
Code:
<file name="multithreadserver.dll">
  <comClass clsid="{af2c2811-0657-4264-a1f5-06d033a969ff}"
              threadingModel="Apartment"
              progid="multithread.multithreadserver"
              description="multithread.multithreadserver" />
  </file>

But is something like this also applicable to a comClass in another EXE? I tried with this, but get error "Error in DLL" when creating the comserver:
Code:
<file name="oleautomationserver.exe">
    <comClass clsid="{....}"
              progid="oleautomationserver.application"
              description="oleautomationserver.application" />
</file>

The obvious solution will be just normally registering the EXE via oleautomationserver.exe /RegServer, so this is not a hard problem. I just would like to avoid that necessary step for software that lacks an installer. It's a complicated software package and the software distributor that offers this software only offers this in conjunction with using his central backend as a service anyway, they never bothered about creating a setup, partly because a customer can't install the software standalone anyway. I'd like to rear them in the right direction, but they already rejected an offer to do that 2017.

Well, and aside of that such regfree usage of COM Servers not only in DLLs would be handy to have anyway.

Bye, Olaf.

Olaf Doschke Software Engineering
 
Olaf,

Just to not left you unanswered: as far as I know, read, and tested, it seems that an executable COM server cannot be registered this way. For the tests, I got the same "Error in DLL" message.
 
Thanks for trying.

Meanwhile, I found this:

It's 10 years old, perhaps things have changed, but it seems the intention always only was to give a DLL hell solution, the EXE hell isn't touched.

Well, the same reasons applicable to several COM server versions of DLLs apply for EXE COM servers. It can't be a security concern, as you can still execute EXE files put in any folder and if you want to prevent any EXE to execute without being located in trusted folders (like Program files) you have group policies.

The last post gives a probable solution using the "ROT" which I guess means the "Running Object Table". That's beyond me right now, I'd have to look into what that is and how it can be used from VFP, and then it's simpler to tell my customer to register my EXE Comserver with /RegServer.

Bye, Olaf.

Olaf Doschke Software Engineering
 
Glad you brought this up.

I recently built a COM EXE and was looking through the Inno docs to figure out best way to register it - can't seem to find it - DLLs yes, but COM EXEs no. I know there is a solution with Inno, but have not had time yet...

Anyway, I have a STUB which runs some checks before calling the main EXE, so I decided to register the COM EXE there:

Code:
LOCAL llFailed, llNeedShutDown

TRY
    goApp.Process = CREATEOBJECT("MyProcess.ProcessSession")
CATCH WHEN .T.
    llFailed = .T.
ENDTRY

IF llFailed
*!*    Need permission elevation for Windows 10
   IF ShellExecute(0, "runas", (lcDefaultPath + "\myprocess.exe"), " /regserver", "", 0) > 32
      DOEVENTS FORCE
      WAIT "" WINDOW TIMEOUT 1

      TRY
          goApp.Process = CREATEOBJECT("MyProcess.ProcessSession")
      CATCH WHEN .T.
          llNeedShutDown = .T.
      ENDTRY
   ELSE
      llNeedShutDown = .T.
   ENDIF
ENDIF

It's a hack, but it works.
 
There is some code posted here about using the ROT, indeed, but this has the prerequisite the class is registered, so I don't see a benefit of going that route:

(look at the bottom half)

That code seems to have the goal to let client and COM Server communicate and that can be done much simpler, by passing in goApp, or any object you like to address in the COM Server for sharing data like settings in properties and to call goApp methods as a callback:

Code:
Procedure initialize(toApp)
   Public goApp
   goApp = toApp
Endproc
Notice: since an EXE COM server isn't in-process, it's not only its own session, it's its own process and doesn't share public variables, they are also not shared with DLL or MTDLL COM servers, as they share the same process, but don't share the same runtime. So that's always an idea to extend the scope of anything. Obviously, this introduces dependencies of a caller having such an object with the same interface (structure), but the use of that isn't limited to VFP, also a VB client can pass in a similar application class instance.

And, of course, the main reason to do an EXE COM server instead of a DLL isn't only to do multiprocessing instead of multithreading (that in itself would be a disadvantage) but to let it have UI, simply by setting its _SCREEN.visible =.t.

Bye, Olaf.

Olaf Doschke Software Engineering
 
Oh, and perhaps the more important feedback to you, vernpace:

I haven't done ab Inno setup yet, but AFAIK you can have a section of code called in the setup, and that could include the running of your.exe /regserver

You could also embed a manifest in that EXE to require running elevated, so it can self regsiter, but that's not applicable in most cases. So self-registering with ShellExecute is a rarely working solution.
PS: It's important to note, that your EXEexe doesn't only run, when you register it, later when you use CREATEOBJECT() (or similar mechanisms in other ürogramming languages), the OLE Server is started in two steps, first step is using the comandline your.exe /automation -embedding, which you can read from the Task-Manager. As per Christof Wollenhaupt's session on the topic, this is just a preparation step for the final start of one of possibly several COM Server classes in the EXE, but it means an EXE with a manifest asking for elevation to run also asks for that elevation while using the COM Server classes and thus is not working well.

Bye, Olaf.

Olaf Doschke Software Engineering
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top