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

Error using Matthew Curland's ROT classes with a service

77 views
Skip to first unread message

rcc

unread,
Aug 19, 2004, 10:33:07 AM8/19/04
to
I have successfully built an ActiveX Exe COM server with Matthew
Curland's ROT classes. I can launch the EXE and have clients connect
to it by using
set obj = <project>.<class>

Then I tried launching my ActiveX exe as a service, and here's where
problems began. I tried using srvany and the exe is launched but when
the client instantiates the server class, it simply starts another
process and ignores the one that was launched by srvany.
I then tried Adrian Di Ruggiero's NTServiceWrapper, which is pretty
much like srvany but gives more control over the service, as well as
the source code. The results were the same. This solution uses
CreateProcess, so I replaced this with ShellExecuteEx, and finally to
the VB Shell command. I always got the exact same results.

Anyone has any idea of what is going on? It seems that the problem is
that the ROT registration is somehow failing. I tried changing the
service's user from System to my own account (the one I use to launch
the exe) but still had the same results.

Thanks in advance!

Tony Proctor

unread,
Aug 19, 2004, 11:38:37 AM8/19/04
to
Does your ROT registration specify ROTFLAGS_ALLOWANYCLIENT? This is just a
guess though. The symptoms you're seeing look like the default behaviour for
an ActiveX EXE that's being invoked from different user contexts when no
DCOM settings have been applied using dcomcnfg.exe

Tony Proctor

"rcc" <manuel...@yahoo.com> wrote in message
news:ea860a80.04081...@posting.google.com...

rcc

unread,
Aug 20, 2004, 6:13:52 AM8/20/04
to
I think you're right, that must be the problem. I looked up the value
for ROTFLAGS_ALLOWANYCLIENT and found out it was 2 (in wtypes.h of
VC++). Then in the ExposeObject function I changed the
RegisterActiveObject call to this:

ExposeObject = RegisterActiveObject(This.ThisPointer, clsid,
ACTIVEOBJECT_WEAK + ROTFLAGS_ALLOWANYCLIENT, This.dwRegister)

The results were not brilliant. I still got the same problem when
running the exe from a service account. Besides, now when launching it
from Explorer, the process won't die after it accepted a connection from
a client. It just lurks there in Task Manager. This doesn't happen if I
don't specify ROTFLAGS_ALLOWANYCLIENT.

I also found out in some newsgroups that RegisterActiveObject doesn't
accept ROTFLAGS_ALLOWANYCLIENT and that if one wishes to use this option
one has to write his own RegisterActiveObject. I'll try this approach
unless someone tells me otherwise of course.

Thanks!

*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!

Tony Proctor

unread,
Aug 20, 2004, 6:35:03 AM8/20/04
to
I don't think the ROTFLAGS can be passed to the RegisterActiveObject
function. For instance, the 2 defined ROTFLAGS have values of 1 and 2, but
these conflict with the documented ACTIVEOBJECT_* values which are 0 and 1.
The IRunningObjectTable::Register method will accept ROTFLAGS. However, this
is not directly callable from VB. On the other hand, if you're using Matt's
tools then he has the appropriate typelib to make it callable from VB.

Tony Proctor

"rcc" <man_...@yahoo.com> wrote in message
news:uFGrl5ph...@TK2MSFTNGP09.phx.gbl...

rcc

unread,
Aug 20, 2004, 1:24:07 PM8/20/04
to
Well, I created an ATL COM DLL with an object that has only the function
MyRegisterActiveObject, which in turn calls
IRunningObjectTable::Register

However it fails with error 80004015 (wrong security context) when I try
to pass ACTIVEOBJECT_WEAK + ROTFLAGS_ALLOWANYCLIENT or only
ROTFLAGS_ALLOWANYCLIENT.

If I pass ACTIVEOBJECT_WEAK, it works.

Apparently I should be launching my exe as a service (which isn't
possibile because it's a vb project) or I should put the value
RunAs=InteractiveUser in the AppId section in the registry, under
HKEY_CLASSES_ROOT.

Now the problem is that I don't know what is AppId, or how I can get it
from a VB6 application. Can you help (again)?

Thank you...

Tony Proctor

unread,
Aug 21, 2004, 8:37:50 AM8/21/04
to
ACTIVEOBJECT_WEAK/_STRONG are not relevant to the
IRunningObjectTable::Register method. The ROTFLAGS_REGISTRATIONKEEPSALIVE
flag is responsible for strong/weak registrations in this case.

Passing ACTIVEOBJECT_WEAK is really passing ROTFLAGS_REGISTRATIONKEEPSALIVE
(i.e. doing a 'strong' registration) because both constants have the value
of 1.

I'm not sure about the error message you're getting but a registration can
only be performed from the STA that created the relevant object. Maybe this
is a factor with your C++ DLL. If, as you say, you're using Matt Curland's
tools then why not use his typelib to achieve the call to
IRunningObjectTable::Register, and avoid a separate C++ DLL?

The AppID can be found by looking at the registry key:
HKEY_CLASSES_ROOT\AppID\MyEXEName("AppID")

Tony Proctor

"rcc" <man_...@yahoo.com> wrote in message

news:#IC2Aqth...@tk2msftngp13.phx.gbl...

Schmidt

unread,
Aug 22, 2004, 7:57:47 AM8/22/04
to

"rcc" <man_...@yahoo.com> schrieb im Newsbeitrag
news:%23IC2Aqt...@tk2msftngp13.phx.gbl...

> Now the problem is that I don't know what is AppId, or how I
> can get it from a VB6 application.

You must create one yourself for your ExeName.
The following Code registers a Public Class from an AX-Dll in the ROT with
ROTFLAGS_ALLOWANYCLIENT.
The ClassObject can be a hosted either inside an AX-Exe or a
VB-Standard-Exe.
(the GETINSTANCE-API allows instantiation of Singleton-Classes, that don't
have to be registered previously see
www.datenhaus.de/Downloads/dh_DirectCom.zip for the DirectCom.Dll and
examples).
The "ROTKey" is realized by a FileMoniker-Binding (no ClassID-Binding), so
even multiple Instances of the same Class could be registered in parallel
all with different ROTKeys. The ROT-Objects can be accessed from the
Client-Apps by GetObject(ROTKey) and not GetObject( , ProgID).

'****Into a Module (needs a reference to Edanmos OleLib.tlb)
Option Explicit

Private Declare Function GETINSTANCE Lib "DirectCom" _
(FName$, CName$) As Object

Private Declare Function RegOpenKeyA& Lib "advapi32" _
(ByVal hKey&, ByVal lpSubKey$, phkResult&)
Private Declare Function RegCloseKey& Lib "advapi32" (ByVal hKey&)
Private Declare Function RegCreateKeyA& Lib "advapi32" _
(ByVal hKey&, ByVal lpSubKey$, phkResult&)
Private Declare Function RegSetValueExA& Lib "advapi32" (ByVal hKey&, _
ByVal ValName$, ByVal Rsrv&, ByVal lType&, ByVal Data$, ByVal cbData&)
Private Const HKCR = &H80000000

Public RegIDs As New Collection

Function ROTRegisterClass(ROTKey$, FName$, CName$) As Object
Dim ROT As IRunningObjectTable, U As olelib.IUnknown, M As IMoniker,RegID&
On Error Resume Next
If Not RegisterAppID(App.ExeName & ".exe") Then _
MsgBox "Couldn't register AppID": Exit Function
Set ROT = GetRunningObjectTable
Set M = CreateFileMoniker(ROTKey)
Set U = GETINSTANCE(FName, CName) 'or use CreateObject(ProgID)
If U Is Nothing Then MsgBox "Couldn't create " & CName: Exit Function
RegID = ROT.Register(ROTFLAGS_ALLOWANYCLIENT, U, M)
If RegID = 0 Then MsgBox "Coudn't register " & CName: Exit Function
RegIDs.Add RegID, ROTKey
Set ROTRegisterClass = U
End Function

Sub ROTUnregisterClass(ROTKey$)
Dim ROT As IRunningObjectTable, U As olelib.IUnknown, M As IMoniker,RegID&
On Error Resume Next
RegID = RegIDs(ROTKey)
If RegID = 0 Then Exit Sub
Set ROT = GetRunningObjectTable
ROT.Revoke RegID
End Sub

Function RegisterAppID(ExeName$) As Boolean
Dim sGUID$, GUID As UUID, hKey As Long
If RegOpenKeyA(HKCR, "AppID\" & ExeName, hKey) Then
If RegCreateKeyA(HKCR, "AppID\" & ExeName, hKey) Then Exit Function
CoCreateGuid GUID: sGUID = Space(40)
StringFromGUID2 GUID, sGUID, Len(sGUID): sGUID = Left$(sGUID, 38)
RegSetValueExA hKey, "AppID", 0&, 1&, sGUID, Len(sGUID)
RegCloseKey hKey: hKey = 0
If RegCreateKeyA(HKCR, "AppID\" & sGUID, hKey) Then Exit Function
RegCloseKey hKey
End If
RegisterAppID = True
End Function

Olaf


Schmidt

unread,
Aug 22, 2004, 4:17:57 PM8/22/04
to

"Schmidt" <s...@online.de> schrieb im Newsbeitrag
news:%23exnB8D...@TK2MSFTNGP09.phx.gbl...

Sorry, forgot to add the AuthenticationLevel-Entry with "1=None" in the
AppID-Section.
Also added the RunAs-Entry with "Interactive User".
(Changed one API-Declare and the RegisterAppId-Funtion)

Here comes the whole thing again:

Option Explicit

Private Declare Function GETINSTANCE Lib "DirectCom" _
(FName$, CName$) As Object

Private Declare Function RegOpenKeyA& Lib "advapi32" _
(ByVal hKey&, ByVal lpSubKey$, phkResult&)
Private Declare Function RegCloseKey& Lib "advapi32" (ByVal hKey&)
Private Declare Function RegCreateKeyA& Lib "advapi32" _
(ByVal hKey&, ByVal lpSubKey$, phkResult&)

Private Declare Function RegSetValueExW& Lib "advapi32" (ByVal hKey&, _
ByVal ValName&, ByVal Rsrv&, ByVal lType&, ByVal Data&, ByVal cbData&)


Private Const HKCR = &H80000000

Public RegIDs As New Collection

Function ROTRegisterClass(ROTKey$, FName$, CName$) As Object
Dim ROT As IRunningObjectTable, U As olelib.IUnknown, M As IMoniker, RegID&
On Error Resume Next
If Not RegisterAppID(App.ExeName & ".exe") Then _
MsgBox "Couldn't register AppID": Exit Function
Set ROT = GetRunningObjectTable
Set M = CreateFileMoniker(ROTKey)
Set U = GETINSTANCE(FName, CName) 'or use CreateObject(ProgID)
If U Is Nothing Then MsgBox "Couldn't create " & CName: Exit Function
RegID = ROT.Register(ROTFLAGS_ALLOWANYCLIENT, U, M)
If RegID = 0 Then MsgBox "Coudn't register " & CName: Exit Function
RegIDs.Add RegID, ROTKey
Set ROTRegisterClass = U
End Function

Sub ROTUnregisterClass(ROTKey$)
Dim ROT As IRunningObjectTable, U As olelib.IUnknown, M As IMoniker, RegID&
On Error Resume Next
RegID = RegIDs(ROTKey)
If RegID = 0 Then Exit Sub
Set ROT = GetRunningObjectTable
ROT.Revoke RegID
End Sub

Private Function RegisterAppID(ExeName$) As Boolean
Dim sID$, GUID As UUID, hK As Long, sIA$
If RegOpenKeyA(HKCR, "AppID\" & ExeName, hK) Then
If RegCreateKeyA(HKCR, "AppID\" & ExeName, hK) Then Exit Function
CoCreateGuid GUID: sID = Space(40)
StringFromGUID2 GUID, sID, Len(sID): sID = Left$(sID, 38)
RegSetValueExW hK, StrPtr("AppID"), 0, 1, StrPtr(sID), LenB(sID) + 2
RegCloseKey hK: hK = 0
If RegCreateKeyA(HKCR, "AppID\" & sID, hK) Then Exit Function
RegSetValueExW hK, StrPtr("AuthenticationLevel"), 0, 4, VarPtr(1&), 4
sIA = "Interactive User"
RegSetValueExW hK, StrPtr("RunAs"), 0, 1, StrPtr(sIA), LenB(sIA) + 2
RegCloseKey hK

Tony Proctor

unread,
Aug 23, 2004, 5:22:51 AM8/23/04
to
I was assuming that the OP had already used dcomcnfg.exe Olaf, which would
mean the AppID already exists in the registry.

Tony Proctor

"Schmidt" <s...@online.de> wrote in message
news:#exnB8Di...@TK2MSFTNGP09.phx.gbl...

Schmidt

unread,
Aug 23, 2004, 6:22:51 AM8/23/04
to

"Tony Proctor" <tony_proctor@aimtechnology_NoMoreSPAM_.com> schrieb im
Newsbeitrag news:O5gebKP...@tk2msftngp13.phx.gbl...

> I was assuming that the OP had already used dcomcnfg.exe Olaf,
> which would mean the AppID already exists in the registry.

Ok, that's one instance that can create the appropriate Registry-Entries.
Just wanted to point out (per Code), what has to be written to the registry
in detail, because my google-search regarding ROTFLAGS_ALLOWANYCLIENT in
combination with the correct AppID-Entries was not very satisfying.
I hope, this topic (ROT-Singleton-Access from different
accounts/windowstations) has some better "google-codebase" now (at least for
the VB-Classic-Community).

Olaf


rcc

unread,
Aug 23, 2004, 7:34:04 AM8/23/04
to
Thanks Olaf,

I only have 2 questions about your code:
1. What is the ROTKey? Isn't it supposed to be the clsid for the object
I want to expose? And what do you mean by GetObject(RotKey) ?
2. Meanwhile, can you check these steps to get it working?
- For the com server (which is an ax exe):
- Add a reference to Eduardo Morcillo's OLELIB to my exe project
(already downloaded it)
- Copy DirectCom.dll file to my project directory (I think I don't
need to other ones)
- Create a BAS file with your code
- Create an AX DLL with the class I want to expose (can't be in the
same exe can it?)
- Use ROTRegisterClass from the exe, specifiying the rot key (?), dll
file and the class name
- Call ROTUnregisterClass before the application
- For the client:
- Just use GetInstance() ??? Or use that GetObject(RotKey) notation?

Meanwhile, I've tried creating a COM+ app in dcomcnfg with the Ax DLL
that calls IRunningObjectTable::Register(). I thought I could create a
"ROT Registrar" service, that would run in an allowed security context
(interactive user), and which I could call from my exe server. Now I get
an exception from something called "COM Surrogate". I guess it's just
not allowed to register an object from a different process. But why the
exception?

Finally, Tony Proctor said that I could use Matt Curland's tlb to
register the object. That's what I thought I was doing... What am I
missing?

Almost there... again

# rcc

Schmidt

unread,
Aug 23, 2004, 9:10:35 AM8/23/04
to

"rcc" <man_...@yahoo.com> schrieb im Newsbeitrag
news:Oq4DZUQ...@TK2MSFTNGP11.phx.gbl...

> I only have 2 questions about your code:
> 1. What is the ROTKey? Isn't it supposed to be the clsid for the object

The ClsID is neccessary for the RegisterActiveObject-Call.
IRunningObjectTable.Register supports a "Free-Moniker-Binding", so why not
use a FileMoniker then, wich is supported by the first Param of VBs
GetObject-Function.
The ROTKey is the Creation-Key for the FileMoniker but doesn't have to be a
"real" FileName.
You can register for example one instance of a public Class under ROTKey
"abc123" and another instance of the same Class under "xyz345" inside your
Server-App.

> I want to expose? And what do you mean by GetObject(RotKey) ?

Your Clients can get a Proxy-Instance for the marshaled ROT-Instance1 by:
Set MySingletonObj1 = GetObject("abc123")
and a another connect to ROT-Instance2 by:
Set MySingletonObj2 = GetObject("xyz345")

> 2. Meanwhile, can you check these steps to get it working?
> - For the com server (which is an ax exe):

...and also could be a VB-Standard-Exe.

> - Add a reference to Eduardo Morcillo's OLELIB to
> my exe project (already downloaded it)

Ok.

> - Copy DirectCom.dll file to my project directory
> (I think I don't need to other ones)

You don't need the other ones. You need DirectCom.Dll only, if you want to
create instances from AX-Dlls without using the registry.
If the Component is registered, all wellknown methods of instantiation will
also work of course.

> - Create a BAS file with your code
> - Create an AX DLL with the class I want to expose (can't be in the
> same exe can it?)

It can, but only in AX-Exes, not in Standard-Exes.

> - Use ROTRegisterClass from the exe, specifiying the rot key
> (?), dll file and the class name

Yes, but you can change ROTRegisterClass (and the Params) yourself to
support other methods of instantiation.
In your case (ax-exe with public class) you would need only one param
(ROTKey) and use New ... instead of DirectCOM-Instantiation.

> - Call ROTUnregisterClass before the application

...terminates, yes.

> - For the client:
> - Just use GetInstance() ???

No, see GetInstance(FileName,ClassName) as a registryindependent replacement
for CreateObject("ProjName.ClassName") - nothing more - nothing less.

> Or use that GetObject(RotKey) notation?

Yes, of course.

> Meanwhile, I've tried creating a COM+ app in dcomcnfg with the Ax DLL
> that calls IRunningObjectTable::Register(). I thought I could create a
> "ROT Registrar" service, that would run in an allowed security context
> (interactive user), and which I could call from my exe server. Now I get
> an exception from something called "COM Surrogate". I guess it's just
> not allowed to register an object from a different process. But why the
> exception?

I'm no COM+ expert - we always try to avoid the use of DCOM or COM+ in our
apps.
But a surrogate-process is not, what is needed here, to get things working
with "AllowAnyClient".
You already have an "Exe" as a ClassObject-Wrapper, just register it
correctly in the AppID-Section by calling the Function in my second post or
by using dcomconfg as Tony suggested.

> Finally, Tony Proctor said that I could use Matt Curland's tlb to
> register the object. That's what I thought I was doing... What am I
> missing?

I already haven't played around with Curlands ROT-Examples.
I mostly use Eduardo Morcillos "All-In-One-Package", if I need special
interfaces.

Olaf

P.S. Please let us know, if you got it working the one ore the other way. If
not, I could post a link to a working example (StandardExe-Server+AXDll and
StandardExe-Client)


rcc

unread,
Aug 24, 2004, 1:15:57 PM8/24/04
to
Hi Olaf and Tony,

I have managed to put your (Olaf's) code to work, though it still
doesn't do what it should. It's strange, but I had to change the
RegisterAppId code because I got a few errors. To start with, the
compiler wouldn't even consider regopenkeya declared. After I corrected
that, I could see the key in HKCR\AppId but it had only garbage. Finally
I rewrote the function and now it's working. I also couldn't use OLELIB
with CoCreateGUID/StringFromGUID2. I'm sure it would eventually work but
I decided to use code I already got. I've included the code below.

In the end, it worked with exactly the same limitations it had before.
AAARRRRGGHHHH.....
When launched from windows Explorer it works. I can also see my Rotkey
in RotView, with type FileMoniker, and my client calls GetObject(RotKey)
successfully. However, when using srvany (which creates a "proxy"
service that in turn launches my exe), the statement ROT.Register fails
(I get the message box saying "Couldn't register <class>". I added
another message box with Err.Description (clearing Err.Number before
calling and testing against 0 after) and it shows this message:

"Automation Error
The class is configured to run as a security id different from the
caller"

I then tried the other approach (Matt Curland's). I included the
RegisterAppId first, and then I would use my "registrar" ax dll (a dll
that basically calls IRunningObjectTable::Register). I took it out of
Component Services and declared the object with New, so it should be
inproc right? I continued getting 0x8004015 (wrong security context)
when the exe was called from srvany.

Could IRunningObjectTable::Register simply be somehow ignoring the AppId
key that was written to the registry? Is there an API call that tells me
what security context is actually being used?

' -- CODE REPLACEMENT FOR REGISTERAPPID()

Private Declare Function StringFromGUID2 Lib "ole32.dll" (rguid As GUID,
ByVal lpsz As Long, ByVal cbMax As Long) As Long
Private Declare Function CoCreateGuid Lib "ole32.dll" (pguid As GUID) As
Long

Private Type GUID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(0 To 7) As Byte
End Type

Private Declare Function RegOpenKey Lib "advapi32.dll" Alias
"RegOpenKeyA" (ByVal hKey As Long, ByVal lpSubKey As String, phkResult
As Long) As Long
Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As
Long) As Long
Private Declare Function RegCreateKey Lib "advapi32.dll" Alias
"RegCreateKeyA" (ByVal hKey As Long, ByVal lpSubKey As String, phkResult
As Long) As Long
Private Declare Function RegSetValueEx Lib "advapi32.dll" Alias
"RegSetValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal
Reserved As Long, ByVal dwType As Long, ByVal lpData As String, ByVal
cbData As Long) As Long
Private Declare Function RegSetValueExLong Lib "advapi32.dll" Alias
"RegSetValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal
Reserved As Long, ByVal dwType As Long, lpValue As Long, ByVal cbData As
Long) As Long

Public Function RegisterAppID(ExeName$) As Boolean
Dim sID As String
Dim myGUID As GUID
Dim hK As Long
Dim sIA As String
Dim lpData As Long
Dim lpcbData As Long

If RegOpenKey(HKCR, "AppID\" & ExeName, hK) Then
If RegCreateKey(HKCR, "AppID\" & ExeName, hK) Then Exit Function
CoCreateGuid myGUID: sID = Space(80)

sID = GuidString(myGUID)

RegSetValueEx hK, "AppID", 0, 1, sID, Len(sID)


RegCloseKey hK: hK = 0

If RegCreateKey(HKCR, "AppID\" & sID, hK) Then Exit Function
RegSetValueEx hK, "AuthenticationLevel", 0, 4, VarPtr(1&), 4
lpData = 1
lpcbData = Len(lpData)
RegSetValueExLong hK, "AuthenticationLevel", 0&, 4, lpData, lpcbData

sIA = "Interactive User"
RegSetValueEx hK, "RunAs", 0, 1, sIA, Len(sIA)
RegCloseKey hK


End If
RegisterAppID = True
End Function

Public Function GuidString(pguid As GUID) As String
Dim retVal As Long

GuidString = String$(38, 0)
StringFromGUID2 pguid, StrPtr(GuidString), 39
End Function

Schmidt

unread,
Aug 24, 2004, 5:16:10 PM8/24/04
to

"rcc" <man_...@yahoo.com> schrieb im Newsbeitrag
news:eDl6F4fi...@TK2MSFTNGP10.phx.gbl...

> In the end, it worked with exactly the same limitations it had before.
> AAARRRRGGHHHH.....

Sorry, I've not tested this as a service (only proved
Cross-Useraccount-Access).
Seems (google), that the RunAs-Entry confuses the
windows-certification-service.
Regarding this, I've cleaned up your routine a bit:

Public Function RegisterAppID(ExeName$) As Boolean
Dim sID As String
Dim myGUID As GUID
Dim hK As Long

Dim lpData As Long
Dim lpcbData As Long
If RegOpenKey(HKCR, "AppID\" & ExeName, hK) Then
If RegCreateKey(HKCR, "AppID\" & ExeName, hK) Then Exit Function
CoCreateGuid myGUID

sID = GuidString(myGUID)
RegSetValueEx hK, "AppID", 0, 1, sID, Len(sID)
RegCloseKey hK: hK = 0
If RegCreateKey(HKCR, "AppID\" & sID, hK) Then Exit Function

lpData = 1: lpcbData = Len(lpData)

RegSetValueExLong hK, "AuthenticationLevel", 0, 4, lpData, lpcbData


RegCloseKey hK
End If
RegisterAppID = True
End Function

I've tested this in a complete sample now - VB-Standard-Exe running as a
Service (NTSvc.ocx) and ROT-Registering+Access worked great.

Olaf


rcc

unread,
Aug 25, 2004, 8:45:43 AM8/25/04
to
Yes it does!

Thanks Olaf and Tony, now it's working perfectly.
In the end I prefer using Olaf's solution to Matt Curland's. Although
they do basically the same, Olaf's code is more simple and elegant. It
also allows having several singletons under different File Monikers,
which may be useful.

Sorry about the code I submitted, I didn't notice it was setting
AuthenticationLevel twice. Lame...

Best regards!

# rcc

Dave Sell

unread,
Sep 13, 2004, 11:24:53 PM9/13/04
to
I would think you cant do this:

Server.CreatObject

But instead must do this:

Server.GetObject

0 new messages