Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Loading an un-registered object ?

798 views
Skip to first unread message

R.Wieser

unread,
Apr 20, 2016, 6:53:48 AM4/20/16
to
Hello All,

I would like to be able to load/access and unregistered object into either a
w- or cscript environment. Some googeling in that regard returned
"GetObject", but no matter what I try I can't get it to work.

I tried :

GetObject("MyObject.dll")

GetObject("MyObject.dll","MyObject.foobar")

wscript.GetObject("MyObject.dll")

wscript.GetObject("MyObject.dll","MyObject.foobar")

All of the above just throw an error, appearantly long before the
"MyObject.dll" is even loaded (I've put a debugging statement in the DLL's
initialisation code, and have not seen it).

Any ideas ?

Regards,
Rudy Wieser


Mayayana

unread,
Apr 20, 2016, 9:10:05 AM4/20/16
to
There are several variants of GetObject, but none
of them can load an unregistered server. There's a lot
of work going on behind the scenes to load the library
and map out the functions so that VBS can access
them. WScript needs the typelib to do that.

It's possible to load an unregistered server through
compiled code. I use a small tool in VB6, directCOM.dll,
to load my own Ax DLLs without reg. It's a free DLL
written by Olaf Schmidt. You could maybe create a
wrapper executable for that, but that would be getting
messy and reckless because you wouldn't have direct
control over your wrapper, unless you also register that.

I don't know of any way to do what you want in VBS,
aside from writing involved command line functionality.

What you may be finding with GetObject is reference
to the WScript.GetObject ability to create an object
based on a file, which is pretty much useless. It only
works for HTML, MS Office files if MS Office is installed,
etc. In other words, if you can access the file as an
object through a COM server then GetObject can save
you the step of creating the server explicitly. Whoopee.

Set Doc = WScript.GetObject("C:\Windows\Desktop\somefile.html")
MsgBox typename(Doc)
Set Bod = Doc.body
MsgBox Bod.innerText
Set Bod = Nothing
Set Doc = Nothing


R.Wieser

unread,
Apr 20, 2016, 10:03:27 AM4/20/16
to
Mayayana,

> WScript needs the typelib to do that.

Are you sure ? The VBS engine itself does not need it ...

> It's possible to load an unregistered server through
> compiled code.

True. I've wrapped the VBS engine in a program of mine, and had no
problem with adding a function which could load objects and make them
available to the script.

The problem is that I want to ditch that program, and use the default
available w- and/or c-script programs instead.

> I use a small tool in VB6, directCOM.dll, to load my own
> Ax DLLs without reg.

Something I was also thinking about, a small object that would function as a
boostrap-loader. I'd rather not though (not all computers allow a user to
install ActiveX components -- for a good reason).

> What you may be finding with GetObject is reference
> to the WScript.GetObject ability to create an object
> based on a file, which is pretty much useless.

Thats the one, and it looks to be that way. :-\ :-)

Thanks for the info.

Regards,
Rudy Wieser


-- Origional message:
Mayayana <maya...@invalid.nospam> schreef in berichtnieuws
nf7usv$lu1$1...@dont-email.me...

GS

unread,
Apr 20, 2016, 10:47:51 AM4/20/16
to
Adding info...

You can do this without directCOM.dll via API LoadLibrary(). For that
matter, you could use the directCOM.dll features this way if you wish,
but any DLL can be used reg-free with this API.

--
Garry

Free usenet access at http://www.eternal-september.org
Classic VB Users Regroup!
comp.lang.basic.visual.misc
microsoft.public.vb.general.discussion

---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus

Mayayana

unread,
Apr 20, 2016, 11:15:55 AM4/20/16
to
| > WScript needs the typelib to do that.
|
| Are you sure ? The VBS engine itself does not need it ...
|
Interesting issue.
The following line does a great deal of work to load
the library and work out the available functions:

Set FSO = CreateObject("Scripting.FileSystemObject")

WScript then looks up Scripting.FileSystemObject,
which turns out to have a CLSID of:

{0D43FE01-F093-11CF-8940-00A0C9054228}

Looking under that key there's a Typelib key
with this default value:

{420B2830-E718-11CF-893D-00A0C9054228}

Tracking that CLSID to HKCR\Typelib\
turns up this:

HKEY_CLASSES_ROOT\TypeLib\{420B2830-E718-11CF-893D-00A0C9054228}\1.0\0\win32

The default value in that key is the path to
scrrun.dll, which is where the typelib is in this
case. If you change that path to something
invalid, instantiating FSO will fail.

I don't entirely understand the whole thing. As I
understand it, there's no reason that WScript can't
call GetIDsOfNames and Invoke from a COM library
with a Dispatch interface (the only kind VBS can use)
and just wing it, assuming your script is making
valid calls. But it doesn't do that. It looks up the
typelib to map the interfaces and fails if it can't
do that. Maybe the other way would just be too
messy. With typelibs, WScript can oversee whether
you make valid calls. Without it, if you call FSO.FileExxists
then WScript would have to depend of scrrun.dll to
provide smooth error handling. A few typos could
potentially result in a few crashed DLLs.

| > It's possible to load an unregistered server through
| > compiled code.
|
| True. I've wrapped the VBS engine in a program of mine, and had no
| problem with adding a function which could load objects and make them
| available to the script.

I don't mean wrapping wscript. I mean directly loading
a DLL through C++ code, with no need for that DLL to
be registered. I don't understand the details
myself. C++ mixed with COM is a very messy business.
It seems to involve loading an Ax DLL with LoadLibrary
and/or CoCreateInstance. I'm not sure, in that case,
whether a typelib is still required or whether the
loading process could just use Dispatch functions to
map function addresses.

There was a humorous posting by Raymond Chen some
years ago. I came across it once when I was trying to
understand Windows shell functions in VB. He wrote C++
code to find the focused item in an Explorer window:

https://blogs.msdn.microsoft.com/oldnewthing/20040720-00/?p=38393

It's a very complicated mess. Something that VBS
can do in a few simple lines. COM is designed to make
things easy and object-oriented, but the mechanics
behind it are complicated.

| > I use a small tool in VB6, directCOM.dll, to load my own
| > Ax DLLs without reg.
|
| Something I was also thinking about, a small object that would function as
a
| boostrap-loader. I'd rather not though (not all computers allow a user
to
| install ActiveX components -- for a good reason).
|

That's the point of DirectCOM. It loads Ax without
any registration. It may be that the Ax must have an
internal typelib, and/or it may be that the Ax can only
be used through a Dispatch interface. But that
wouldn't matter for VBS. What you want is exactly
why I use DirectCOM: I have an Ax DLL in an a program
that gets installed and I wanted to avoid registration
issues. Especially with later Windows versions, it's
cleaner if I can load a COM object from my own program
folder without needing to register it.

--------- DirectCOM ----------------
In case this might be of use to you:


The link here contains directCOM.dll:

http://www.thecommon.net/

Version 3 has it. Version 4 might. But at least one
of the downloads does. The rest of the download is
not of much use. Olaf has created a very impressive
and extensive set of libraries that are free to use,
but the design of them is unorthodox and docs are
non-existent.

Usage in VB6:

Private Declare Function GETINSTANCE Lib "DirectCOM.dll" (FName As String,
ClassName As String) As Object

Private Cls1 as Server1.Class1 ' example: Scripting.FileSystemObject

Set Cls1 = GETINSTANCE(App.Path & "\yourlib.dll", "Class1")

DirectCOM instantiates the class and hands it off. One
need only set the object to Nothing to release it. I guess
that theoretically something like DirectCOM could provide
a commandline option that VBS could use, but as far as
I know there's no such thing available.

And of course you'd need to be careful with this method.
DirectCOM is getting the Dispatch interface and handing
it off. From there it's up to you and the Ax DLL how well
you get along. :)


Mayayana

unread,
Apr 20, 2016, 11:26:58 AM4/20/16
to
| You can do this without directCOM.dll via API LoadLibrary(). For that
| matter, you could use the directCOM.dll features this way if you wish,
| but any DLL can be used reg-free with this API.
|

Do you do that in VB? I was curious exactly how
it's done. LoadLibrary will load a DLL into the
process, but then how are you instantiating a
class instance?

It all seems very tricky from script. Unless one
processes the typelib inside the "masterkey" DLL
and err-checks against calls coming in from VBS
it could get very messy.
Even then, it puts one back in the same boat:
The master key DLL has to be registered in order
to load other DLLs reg-free. VBS won't be able to
use it otherwise.


R.Wieser

unread,
Apr 20, 2016, 2:00:35 PM4/20/16
to
GS,

> You can do this without directCOM.dll via API LoadLibrary().

:-) That is how I did it in my wrapped VBS engine.

Regards,
Rudy Wieser


-- Origional message:
GS <g...@v.invalid> schreef in berichtnieuws nf84ka$c65$1...@dont-email.me...

GS

unread,
Apr 20, 2016, 2:31:36 PM4/20/16
to
Each DLL would be called separately in this case, making all
individually available for reg-free use. Once the DLL is loaded
in-process, the object ref is 'set' in the normal fashion.

I see Rudy's post that he has already done this...

R.Wieser

unread,
Apr 20, 2016, 3:34:41 PM4/20/16
to
Mayayana,

> As I understand it, there's no reason that WScript can't
> call GetIDsOfNames and Invoke from a COM library
> with a Dispatch interface (the only kind VBS can use)

It can, and it does: When my VBScript-wrapper program loads an object using
LoadLibrary and the script than tries to access any of the
loaded-but-not-registered objects methods it certainly goes that way. At
least, if I may believe my logfiles.

> and just wing it, assuming your script is making
> valid calls.

It does not need to wing it, as it asks the COM object if it actually has a
certain property/method (every single time!), and only if it does continues
with the Invoke.

> With typelibs, WScript can oversee whether you make valid calls.

I'm sorry, but nope doesn't. Not in my experience with it and creating COM
and ActiveX components anyway.

> I don't mean wrapping wscript. I mean directly loading a DLL
> through C++ code, with no need for that DLL to be registered.

I did not either. I put the VBS engine object in a program of mine, added
an object name thru IActiveScript AddNamedItem, and than return an object
pointer when IActiveScriptSite GetItemInfo searches for that name. That
object implements a method which ultimatily calls LoadLibrary, creates the
class factory, and than the (default) object.

> COM is designed to make things easy and object-oriented,
> but the mechanics behind it are complicated.

Yep. Hiding all the nitty-gritty behind the curtains. Thats what high(er)
level languages are for.

> That's the point of DirectCOM. It loads Ax without
> any registration.

Ahrrgg ... I think we where talking about two just a slightly bit
different things here: Its my intention to load an unregistered object
in(to) a VBScript -- so the *script* can use it.

Loading an unregistered object into a program isn't the problem.

I've already implemented code that does something similar as DirectCOM
thingy as part of my own program, but want to ditch it in favour of w-
and/or cscript.

> And of course you'd need to be careful with this method.
> DirectCOM is getting the Dispatch interface and handing
> it off. From there it's up to you and the Ax DLL how well
> you get along. :)

I'm not really afraid of that, as I've already got *that* running. :-)
(though there is enough area I've not yet explored, like events generated by
an object).

Regards,
Rudy Wieser


-- Origional message:
Mayayana <maya...@invalid.nospam> schreef in berichtnieuws
nf868t$imn$1...@dont-email.me...

R.Wieser

unread,
Apr 20, 2016, 3:58:50 PM4/20/16
to
Mayayana,

> Do you do that in VB? I was curious exactly how
> it's done. LoadLibrary will load a DLL into the
> process, but then how are you instantiating a
> class instance?

The to-be-loaded object/DLL needs to expose a DllGetClassObject function,
after which you call the ClassFactories CreateInstance method, providing it
with the IID of the actual object (there might be more than one available).

At least, that is what my code does, and it works well. :-)

> Unless one processes the typelib inside the "masterkey"
> DLL and err-checks against calls coming in from VBS
> it could get very messy.

No such thing is needed. Using the above loading method the only one using
the typelib, if at all present, is the instanciated object itself (also see
my other message).

> Even then, it puts one back in the same boat:
> The master key DLL has to be registered in order
> to load other DLLs reg-free. VBS won't be able to
> use it otherwise.

*If* that DLL contains an (COM/ActiveX) object than yes, it would solve
little.

As I was not so sure what it is myself I did google a bit and found this:

http://microsoft.public.vb.general.discussion.narkive.com/iIx1HCGm/vb6-regfr
ee-com

[quote]
There is a ready to use, very small and *free* dll (named
DirectCOM.Dll), specifically tailored for the use with VB6
...
The dll itself is a standard (non COM server) dll
[/uote]

In other words: you cannot access it thru scripting.

Regards,
Rudy Wieser


-- Origional message:
Mayayana <maya...@invalid.nospam> schreef in berichtnieuws
nf86tl$l5m$1...@dont-email.me...

Mayayana

unread,
Apr 20, 2016, 5:16:08 PM4/20/16
to
| The to-be-loaded object/DLL needs to expose a DllGetClassObject function,
| after which you call the ClassFactories CreateInstance method, providing
it
| with the IID of the actual object (there might be more than one
available).
|
| At least, that is what my code does, and it works well. :-)
|
| > Unless one processes the typelib inside the "masterkey"
| > DLL and err-checks against calls coming in from VBS
| > it could get very messy.
|
| No such thing is needed. Using the above loading method the only one
using
| the typelib, if at all present, is the instanciated object itself (also
see
| my other message).

Interesting. So with a CLSID one can load the object.
Without it one could still read the typelib to get that
CLSID. But if WScript loads FSO it has the CLSID from
the Registry and it also has the DLL file path from the
Registry. There must be some reason why it will fail when
it can't get the typelib.



R.Wieser

unread,
Apr 21, 2016, 3:33:02 AM4/21/16
to
Mayayana,

> > With typelibs, WScript can oversee whether you make
> > valid calls.
>
> I'm sorry, but nope doesn't. Not in my experience with it
> and creating COM and ActiveX components anyway.

As always, only *after* posting I realized I've been blundering away ... :-(

You're in fact right, it does. A typelib is used by wscript to from-and-to
translate between the variants from the script and the variable types the
objects method uses. It also allows you to "ignore" some trailing
arguments, or to give arguments that are not specified (like when having
nothing between two comma's) a default value.

But although the above could generate, seen from the POV of the script,
*some* kind of checking on the arguments, its far from airtight (I've got a
particular problem where, even when a method is specified as a "get"
property it also get called when the script tries to do a "put" action (and
only fails *after* the "get" method has returned)

> > It looks up the typelib to map the interfaces and fails if it
> > can't do that.

I realized (again too late) that I can't remember if I ever tried to load an
object *without* a typelib ...

I do have typelib-less objects, but until now allways "injected" them into
the VBS engine before a script was even loaded (its methods recieve a pair
of result and array-of-arguments variants when called), bypassing WScripts
loading mechanism.

Regards,
Rudy Wieser


----- Original Message -----
Mayayana <maya...@invalid.nospam> schreef in berichtnieuws
nf868t$imn$1...@dont-email.me...

R.Wieser

unread,
Apr 21, 2016, 4:16:30 AM4/21/16
to
Mayayana,

> Interesting. So with a CLSID one can load the object.

Yep.

> Without it one could still read the typelib to get that CLSID.

:-) Thats exactly what I thought I could do. But after looking at a
number of extracted typelibs I found I could not find it. The ones I looked
at only contained the GUIDs of the typelibs and the IIDs of the interfaces.

> There must be some reason why it will fail when it can't
> get the typelib.

Well, most likely because it actually needs that typelib ... :-)

It looks like I was too rash in assuming that because I could get an object
without a typlib to work in the VBS engine such an object could be loaded
into wscript too. My apologies for that.

By the way: you can also get the typelib using the OleAut32.dll LoadTypeLib
function, which, if the file is a DLL, simply extracts the (defaulting to
first) typelib resource stored in it.

Regards,
Rudy Wieser


-- Origional message:
Mayayana <maya...@invalid.nospam> schreef in berichtnieuws
nf8rca$7j1$1...@dont-email.me...

R.Wieser

unread,
Apr 21, 2016, 7:38:58 AM4/21/16
to
> :-) Thats exactly what I thought I could do. But after looking
> at a number of extracted typelibs I found I could not find it.

The powers-that-be must have a fun day with me ... :-\

I was just looking at my own .IDL file (which the typelib is compiled from),
and it poked me in the eye: The CLSID of my object is actually named in a
CoClass section, referring to the interface. When "dumping" the contents of
the compiled TypeLibrary I noticed the CoClass than has the CANCREATE flag
(which stands to reason).

No idea why I did not see that before. :-(

It also will make my own "LoadObject" method easier: If can omit the
objects CLSID if I want to create the first (or only) object available.

Regards
Rudy Wieser



Mayayana

unread,
Apr 21, 2016, 9:50:21 AM4/21/16
to

| By the way: you can also get the typelib using the OleAut32.dll
LoadTypeLib
| function, which, if the file is a DLL, simply extracts the (defaulting to
| first) typelib resource stored in it.
|

I wrote code for that at one point when I wanted to
put an object browser and "intellisense" into my own
editor program:

http://www.jsware.net/jsware/vbcode.php5#tlbc

I also wrote a VBS version dependent on tlbinf32.dll.

http://www.jsware.net/jsware/scrfiles.php5#obbro

But when I eventually looked at oleaut32.dll I realized
that tlbinf32 was actually a somewhat hokey mixup
of the typelib API and best abandoned, though it is
convenient in that it's script-accessible.

This whole topic is intriguing and tempts me to look
into options incorporating it all. Something like directCOM
for VBS. But then I can't really think of how it could be
widely useful for scripters. Registering is not a big deal.
Using a reg-free tool would probably require more
expertise for the average scripter to grasp. And you
seem to have already invented that wheel but are finding
it will only take you so far....
Sometimes I have free time and get in the mood for a
juicy coding project, but just can't think of one. :)


R.Wieser

unread,
Apr 21, 2016, 11:06:47 AM4/21/16
to
Mayayana,

> But then I can't really think of how it could be
> widely useful for scripters. Registering is not a
> big deal.

True.

But to me there was a good reason for implementing it: with it I could test
an ActiveX component I was working on (without having to think about
de-registering the, possibly half-finished, product), and two, the object is
only active for the current script, and cannot be loaded from anywhere else.

Regards,
Rudy Wieser


-- Origional message:
Mayayana <maya...@invalid.nospam> schreef in berichtnieuws
nfalke$qtk$1...@dont-email.me...
0 new messages