Olaf Doschke
Programmer
First of all, you don't need QUIT in a DLL COM Server, as that's always running in the same thread as the caller you actually don't want to use that in such COM Servers.
And secondly, for EXE COM Servers, setting your reference to a COM Object to null does not only destroy the COM server but also exit the process of it.
Usually. You know, if you put together a few threads I started, that I work with Webrelated things in a VFP application and to do so free of side effects it turns out best to separate this into an own process uneffected by some timers and other application framework settings and general processing of things deadly for some aspects of my extensions. For example only that way I get a Webbrowser control and JS to behave correcly in regard to NewWindow2 events.
Anyway, to get to the question: In some yet not well understood cases oCOM = null does not end my COMServer EXE and I waste some Memory over the day with this. I got the glorious idea to simply do as Word and have a Quite method doing, well, QUIT, but that causes an exception. I could live with that and simply put the destruction of the COM object into TRY..CATCH in the client using it, but I wonder if that always was a thing or only in VFP9 or only in Win10 or some build of it, so if anyone would like to contribute to that knowledge, try this COMServer as EXEvutable and tell me whether you also get excpetions:
Store that as main.prg of a PJX you compile as EXE, run VFP as admin or finally register the exe with running your.exe /Regserver elevated.
Now play with it by trying the different ways to not only release the object variable but end the EXE in task manager. Simplest working way:
I have no repro code where o=null does not also end the process, but assume that's the case, then there should be a way to quit it, too, shouldn't there?
Especially when you do...
...you'll get OLE exception 0 from ?:?.. in the client using the COMServer.
Nothing errors within the COM Server and also strange no other method but QUIT ends the object, you can call CLOSE() or EXIT and afterward call ALIVE() just fine.
I could live with the fact the client die variable becomes a zombie reference, as that should simply get a RELEASE or get out of scope anyway, but I'd like an exit without throwing an exepction I have to catch.
And I wonder if that was always the case with QUIT.
Bye, Olaf.
Olaf Doschke Software Engineering
And secondly, for EXE COM Servers, setting your reference to a COM Object to null does not only destroy the COM server but also exit the process of it.
Usually. You know, if you put together a few threads I started, that I work with Webrelated things in a VFP application and to do so free of side effects it turns out best to separate this into an own process uneffected by some timers and other application framework settings and general processing of things deadly for some aspects of my extensions. For example only that way I get a Webbrowser control and JS to behave correcly in regard to NewWindow2 events.
Anyway, to get to the question: In some yet not well understood cases oCOM = null does not end my COMServer EXE and I waste some Memory over the day with this. I got the glorious idea to simply do as Word and have a Quite method doing, well, QUIT, but that causes an exception. I could live with that and simply put the destruction of the COM object into TRY..CATCH in the client using it, but I wonder if that always was a thing or only in VFP9 or only in Win10 or some build of it, so if anyone would like to contribute to that knowledge, try this COMServer as EXEvutable and tell me whether you also get excpetions:
Code:
Define Class Application As Session OlePublic
Procedure Alive() As String
Return "Hello from PID "+Transform(_vfp.ProcessID)
Endproc
Procedure Quit() As VOID
Quit
Endproc
Procedure Close() As VOID
#Define WM_DESTROY 0x2
#Define WM_CLOSE 0x10
Declare Long SendMessage In "user32" Long @ HWnd,Long @ wMsg,Integer @ wParam,String @ Lparam
SendMessage(_vfp.HWnd, WM_CLOSE, 0, 0)
SendMessage(_vfp.HWnd, WM_DESTROY, 0, 0)
SendMessage(_Screen.HWnd, WM_CLOSE, 0, 0)
SendMessage(_Screen.HWnd, WM_DESTROY, 0, 0)
Endproc
Procedure Exit() As VOID
Declare Long ExitProcess In "kernel32" Long exitcode
ExitProcess(0)
Endproc
Procedure RefRelease() As VOID
Sys(3098,This)
Endproc
Procedure Error()
Lparameters nError, cMethod, nLine
_Screen.Visible = .T.
Messagebox(Textmerge("<<nError>>,<<cMethod>>,<<nLine>>"))
Endproc
Enddefine
Store that as main.prg of a PJX you compile as EXE, run VFP as admin or finally register the exe with running your.exe /Regserver elevated.
Now play with it by trying the different ways to not only release the object variable but end the EXE in task manager. Simplest working way:
Code:
o = CreateObject("your.application") && name of class will depend on your PJX name
&& at this stage you will find your.exe in task manager, look out for PID given by:
? o.Alive()
o = null && EXE should vanish within task manager
I have no repro code where o=null does not also end the process, but assume that's the case, then there should be a way to quit it, too, shouldn't there?
Especially when you do...
Code:
o = CreateObject("your.application") && name of class will depend on your PJX name
&& at this stage you will find your.exe in task manager, look out for PID given by:
? o.Alive()
o.Quit()
Nothing errors within the COM Server and also strange no other method but QUIT ends the object, you can call CLOSE() or EXIT and afterward call ALIVE() just fine.
I could live with the fact the client die variable becomes a zombie reference, as that should simply get a RELEASE or get out of scope anyway, but I'd like an exit without throwing an exepction I have to catch.
And I wonder if that was always the case with QUIT.
Bye, Olaf.
Olaf Doschke Software Engineering