I use the Microsoft Web Browser Control as the primary UI for an app. This means I need a ton of support files like cascading stylesheets, javascript files, images, etc.
Typically, I create a subfolder in the Windows “Temp” (SYS(2023)) folder for the HTML files, then subfolders for each of the support file types (CSS, JS, IMG). I don’t like to install the support files with the app, because there’s always someone out there that wants to modify the files or just poke around to see how some things get done.
In the past, I simply included the support files in the EXE and did a series of STRTOFILE()’s to copy the files to the temporary location. But as the app (and the number of support files it uses) grows, it really bloats the EXE. So I created a DLL which contained all the included files, with methods to do the file copying.
During startup, the EXE instantiates the OLEPUBLIC classes in the DLL and fires the methods to copy the files. Works great, and it keeps the size of the EXE a bit smaller.
Yep, works great. Except when the DLL doesn’t get properly registered during the install, and the instantiation fails. I get error reports from time to time where the DLL hasn’t been registered. Though I’ve been unable to recreate it here, it seems the common denominator is a particular anti-virus software solution – I’m looking at you, Kaspersky.
So, I’m stuck with needing to manually register the DLL if it hasn’t been registered. I suppose I could use Reg-Free COM, manifest files, elevation, etc. to register the DLL programmatically, but I worry about going through all of that only to find that it still won’t register for the same reason it didn’t during installation (I’m still looking at you, Kaspersky).
I stumbled on an idea earlier this week and thought I’d give it a try. The idea was to SET PROCEDURE TO MyDll. Why not create a DLL, then, instead of going through registering it, just SET PROCEDURE to it and call the methods?
Duh. Can’t do it. It’s an object method, and I haven’t created the object.
So I did a little refactoring on the DLL. It contains one OLEPUBLIC class, which is nothing more than a class definition – no properties, no methods, no nothing. Then I split the methods out to simple FUNCTIONs.
Recompiled the DLL, then got rid of the registration info that was added to the Windows Registry. Then I tried the SET PROCEDURE TO.
The pseudocode looks like this:
IF MyDll.dll Exists then SET PROCEDURE TO MyDll.dll MyFunction() RELEASE PROCEDURE MyDll.dll ENDIF
And, it worked! No registration, just a simple check to see if the file exists. If it does, run the method. This assumes, of course, that the method exists (since there’s no PEMSTATUS I can check – remember, no object or class exists).
Now for the disclaimer (before the comments start rolling in):
- Yes, I am well aware that SET PROCEDURE TO was not designed to be used this way.
- Yes, I know the best way to “fix” the problem is to determine what the problem actually is and find a “real” solution.
- Yes, I know this wouldn’t be considered “best practice”.
On the other hand, though, my purpose for this is pretty specific, and was completed very quickly. Plus, with a little bit of coding on the app’s update procedure, I can now update the DLL anytime I need to, without having to install a whole new update. Best of all, it appears that the problem has been solved. I still try to instantiate the object first, but if it fails I fallback to the new “unregistered” DLL. Not a single error report since the last update.
So far, so good…