MS Access Forum / Modules / DAO / VBA / January 2006
Type Library Reference Problem
|
|
Thread rating:  |
Pete - 16 Jan 2006 12:27 GMT 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
 Signature Peter Schmidt Ross-on-Wye, UK
John Nurick - 16 Jan 2006 20:05 GMT Hi Pete,
For late binding, declare the objects As Object, and remove the references to the libraries that contain them.
>I have a problem involving type library versions I hope somebody can help me >with. [quoted text clipped - 49 lines] > strLastName = oUser.Get("LastName") >End Function -- John Nurick [Microsoft Access MVP]
Please respond in the newgroup and not by email.
John Nurick - 16 Jan 2006 21:40 GMT <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>
>Hi Pete, > [quoted text clipped - 54 lines] >> strLastName = oUser.Get("LastName") >>End Function -- John Nurick [Microsoft Access MVP]
Please respond in the newgroup and not by email.
TC - 17 Jan 2006 02:38 GMT 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]
Pete - 17 Jan 2006 11:27 GMT 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
 Signature Peter Schmidt Ross-on-Wye, UK
> And add declarations for any symbolic constants that you use from the > (removed) library refrence(s) :-) [quoted text clipped - 11 lines] > HTH, > TC [MVP Access] TC - 17 Jan 2006 12:27 GMT 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]
Pete - 17 Jan 2006 14:51 GMT 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
 Signature Peter Schmidt Ross-on-Wye, UK
> Three things. > [quoted text clipped - 16 lines] > HTH, > TC [MVP Access] Pete - 18 Jan 2006 08:50 GMT 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
 Signature Peter Schmidt Ross-on-Wye, UK
> Three things. > [quoted text clipped - 16 lines] > HTH, > TC [MVP Access] John Nurick - 18 Jan 2006 20:56 GMT Thanks for posting that, Pete. It may come in handy one day.
>I have actually cut the code down even more by changing the API Call and >getting the domain info returned: -- John Nurick [Microsoft Access MVP]
Please respond in the newgroup and not by email.
|
|
|