Type Library Reference Problem

P

Pete

I have a problem involving type library versions I hope somebody can help me
with.

I develop applications using Access 2003 running on Windows XP Professional.
The finished applications are published to a Windows 2003 Server where they
run (users connect via Citrix).

I have recently added some functionality that uses the Active Directory
Services type library (activeds.tlb; activeds.dll). However, whilst this
works fine on my PC it fails on the server. I noticed that the dll versions
differ and are newer on the server – re-referencing the dll and building the
mde on the server fixes this, but it then will not work on my PC.

My first attempt at a solution was to copy the server version of the
activeds.tlb; and activeds.dll files to my PC, but they are protected by
Windows System File protection so I haven’t found a way to do this.

Second thought was to use ‘late binding’, but as far as I am aware the code
I am using is already doing this?! See code below.

Any help appreciated.

Regards

Peter


Option Compare Database
Option Explicit

'*** Get Current Users Login Name ***
Private Declare Function GetUserNameEx Lib "secur32.dll" Alias
"GetUserNameExA" (ByVal NameFormat As Long, ByVal lpNameBuffer As String,
ByRef nSize As Long) As Long

Public Function GetUserInfo()
Dim sBuffer As String, Ret As Long, strAlias As String
sBuffer = String$(256, 0)
Ret = Len(sBuffer)
If GetUserNameEx(3, sBuffer, Ret) <> 0 Then
strAlias = Left$(sBuffer, Ret)
End If

'*** Lookup Details In Active Directory ***
Dim oRootDSE As IADs
Dim varDomainNC As Variant
Dim oUser As IADsUser
Set oRootDSE = GetObject("LDAP://RootDSE")
varDomainNC = oRootDSE.Get("defaultNamingContext")
Set oUser = GetObject("LDAP://CN=" & strAlias & ",CN=Users," &
varDomainNC)
strFirstName = oUser.Get("FirstName")
strLastName = oUser.Get("LastName")
End Function
 
J

John Nurick

Hi Pete,

For late binding, declare the objects As Object, and remove the
references to the libraries that contain them.
 
J

John Nurick

<pedantry>
It's not necessary to remove the references in order to use late
binding, just to avoid getting reference problems on other systems.
</pedantry>
 
T

TC

And add declarations for any symbolic constants that you use from the
(removed) library refrence(s) :)

So, OP, the symbolic constant acEdit is defined by Access. But if you
were late binding to Access, eg. from VBScript, where there is no
reference to the Access libraries, you'd need to define that constant
explicitly:

const acEdit = 1

Similarly if you are using any symbolic constants from the (now
unreferenced) AD libraries.

HTH,
TC [MVP Access]
 
P

Pete

Thanks for your responses. I am new to the technique of late binding so
forgive me for being a little slow...

I have removed the reference to the ActiveDS type library and updated my
declarations to generic objects, but still can't get it to work. I think the
oUser object is not instantiating correctly - when it is declared as an
IADsUser I can view its properties, but when it is just declared as an object
I cannot. Do I need an extra line of code to tell it what type of object it
is and if so what would the syntax be?

My code currently reads:

Option Compare Database
Option Explicit
'*** Get Current Users Login Name ***
Private Declare Function GetUserNameEx Lib "secur32.dll" Alias
"GetUserNameExA" (ByVal NameFormat As Long, ByVal lpNameBuffer As String,
ByRef nSize As Long) As Long

Public Function GetUserInfo()
Dim sBuffer As String, Ret As Long, strAlias As String
sBuffer = String$(256, 0)
Ret = Len(sBuffer)
If GetUserNameEx(3, sBuffer, Ret) <> 0 Then
strAlias = Left$(sBuffer, Ret-1)
End If

'*** Lookup Details In Active Directory ***
Dim oRootDSE As Object
Dim varDomainNC As Variant
Dim oUser As Object
Set oRootDSE = GetObject("LDAP://RootDSE")
varDomainNC = oRootDSE.Get("defaultNamingContext")
Set oUser = GetObject("LDAP://CN=" & strAlias & ",CN=Users," &
varDomainNC)
strFirstName = oUser.Get("FirstName")
strLastName = oUser.Get("LastName")
End Function
 
T

TC

Three things.

(1) When you use late binding, the code editor will not know what
methods & properties each late-bound object has. This is expected when
using late binding. It is only with /early/ binding, that the code
editor will know what methods & properties each object has.

(2) I notice you are using GetObject to set the oRootDSE and oUser
objects. GetObject is used when the object in question already exists.
The alternative is CreateObject, which creates a new instance of the
specified object. Personally, I don't know which one you should use in
this case. I'm just mentioning this, in case it is significant. You'd
use the same one (GetObject or CreateObject) that you should use when
early binding.

(3) You say you "can't get it to work". That is not enough to go on. In
what way does it "not work"?

HTH,
TC [MVP Access]
 
P

Pete

I was getting a variety of errors which was I wasn’t more specific, but have
finally cracked it.

I found that as well as de-referencing the type library and changing the
object declarations I had to do a decompile/recompile

I was then getting the following error on the line:

strFirstName = oUser.Get("FirstName")

“Error -2147463155 (8000500d)
The directory property cannot be found in the cacheâ€

It appears that when you use the type library it aliases some of the
properties. When you late bind they are known by a different name so
FirstName=givenname and LastName=sn!

For the benefit of the group I have put the working code below (I actually
read a lot more data so, Full Name = displayname, Email = mail, Telephone No
= telephonenumber) .

Thanks for your help.

Option Compare Database
Option Explicit
'*** Get Current Users Login Name ***
Private Declare Function GetUserNameEx Lib "secur32.dll" Alias
"GetUserNameExA" (ByVal NameFormat As Long, ByVal lpNameBuffer As String,
ByRef nSize As Long) As Long

Public Function GetUserInfo()
Dim sBuffer As String, Ret As Long, strAlias As String
sBuffer = String$(256, 0)
Ret = Len(sBuffer)
If GetUserNameEx(3, sBuffer, Ret) <> 0 Then
strAlias = Left$(sBuffer, Ret-1)
End If

'*** Lookup Details In Active Directory ***
Dim oRootDSE As Object
Dim varDomainNC As Variant
Dim oUser As Object
Set oRootDSE = GetObject("LDAP://RootDSE")
varDomainNC = oRootDSE.Get("defaultNamingContext")
Set oUser = GetObject("LDAP://CN=" & strAlias & ",CN=Users," &
varDomainNC)
strFirstName = oUser.Get("givenName")
strLastName = oUser.Get("sn")
End Function
 
P

Pete

I have actually cut the code down even more by changing the API Call and
getting the domain info returned:

Peter

Option Compare Database
Option Explicit

'*** Get Current Users Login Name ***
Private Declare Function GetUserNameEx Lib "secur32.dll" Alias
"GetUserNameExA" (ByVal NameFormat As Long, ByVal lpNameBuffer As String,
ByRef nSize As Long) As Long

Public Function GetUserInfo()
Dim sBuffer As String, Ret As Long, strAlias As String
sBuffer = String$(256, 0)
Ret = Len(sBuffer)
If GetUserNameEx(1, sBuffer, Ret) <> 0 Then
strAlias = Left$(sBuffer, InStr(sBuffer, Chr$(0)) - 1)
End If

'*** Lookup Details In Active Directory ***
Dim oUser As Object
On Error Resume Next
Set oUser = GetObject("LDAP://" & strAlias)
cCurrentUserFullName = Nz(oUser.Get("displayname"),"")
cFirstName=Nz(oUser.Get("givenname"), "")
cSurname=Nz(oUser.Get("sn"), "")
cCurrentUserTelExt = Nz(oUser.Get("TelephoneNumber"), "")
cCurrentUserEmail = Nz(oUser.Get("mail"), "")
End Function
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top