Tuesday, November 30, 2004

Keeping out-of-proc automation servers alive

I know, out-of-proc automation servers aren't very popular in these days when you have COM+ and .NET. But if you're still a person writing out of proc automation servers, (like Microsoft is with Word, Excel and the whole lot) you might need to consider a small fact.

Delphi assumes that if your EXE was already running when a COM call was made to an object hosted inside it, then AFTER that call finishes, Delphi keeps your application running. (Obviously, I guess) But if your EXE isn't already running, then a COM call will *instantiate* your EXE, and create the COM object. Fine. But after the COM object is released, your EXE shuts down!!!!

This is because of some code in ComServ.pas that's specific to automation - it actually checks if your EXE was launched through Automation (i.e. with a /AUTOMATION or /EMBEDDING parameter) and if so, when your object is released, it clears a reference to the factory. The Windows COM subsystem maintains references to the object factory in your application...and when that count reaches zero, COM assumes your factory has bid it goodbye, and in subsequent calls, will create a NEW instance of your application.

So if you want to be able to say "I don't care how my EXE is launched but once it's launched I want the same EXE to handle all subsequent calls to the COM objects I host.", then read on. (If you're totally confused by now, stop.)

What you need to do, is to trick COM into thinking your object factory is still alive. So, in some global create code (maybe in a form create event in an autocreated form, or a constructor of a global object) add this:

ComObj.CoAddRefServerProcess;

and in the corresponding destructor or FormDestroy, add:

ComObj.CoReleaseServerProcess;

(obviously, use ComObj.)

Friday, November 26, 2004

Like Firefox? Want it INSIDE your Delphi app?

If you like Firefox 1.0, you're probably using it as your default browser, copying your favourites and all that stuff. Well, if you want to migrate your Delphi applications to use it instead of TWebBrowser, you're in Luck!

Check out The Mozilla ActiveX Control and Dave Murray's article on how to use it in Delphi. Will save you some (or all) of the trouble you have with SP2 going berserk - like Allen Bauer seemed to have had. (If you're curious, that problem has been solved.)

Thursday, November 25, 2004

Delphi 2005: Use only the Win32 part?

Well, if you want to do this, you CAN. And this page gives you step by step instructions....so if you're anti .NET, go for it.

More useful, in my opinion is to use that in conjunction with Corbin Dunn's article on how to use the /r command line option in Delphi. Try it - you can set up a completely different IDE if you like, and one for Win32, and one for .NET. Btw, all of that works with Delphi 7 too, as I recently found out.

Sunday, November 14, 2004

Deleting a SOAP attachment file

If you're creating a SOAP attachment on the server, and creating a temporary file for the purpose, you probably need to delete the file after you're done. You can't do this in ANY of the events provided - the attachment stream is not freed before any event occurs. So, what you must do is that instead of using TSOAPAttachment.SetSourceFile, you must use TSOAPAttachment.SetSourceStream instead, but with your own stream like so:


type
TMyStream = class( TFileStream )
public
destructor Destroy; override;
end;
...
destructor TMyStream.Destroy;
begin
inherited;
Deletefile('c:\sql1.txt'); // or whatever has to be deleted
end;


and in your implementation have something like this:


var str : TMYStream;
begin
Result := TSOAPAttachment.Create;
Str := TMyStream.Create('c:\sql1.txt', fmOPenread);

Result.SetSourceStream(Str,soOwned) ;
end;