• Status: Solved
  • Priority: Low
  • Security: Public
  • Views: 53
  • Last Modified:

The Win 64 BIT

Hi

I have just come back from one of our depot with bad news the code below is block other code from working , we  are currently using Ms access 2016 stored as 32 BIT running on windows 64 BIT

#IF Win64 THEN
  Declare PtrSafe Function GetUserName Lib "advapi32.dll" Alias "GetUserNameA" (ByVal _
   lpBuffer As String, nSize As Long) As LongPtr
#Else
  Declare Function GetUserName Lib "advapi32.dll" Alias "GetUserNameA" (ByVal _
   lpBuffer As String, nSize As Long) As Long
#End If

For example we cannot up date depot details any more.

Any solution to this will be highly appreciated.

Regards

Chris
0
Hankwembo Christopher,FCCA,FZICA,CIA,MAAT,B.A.Sc
Asked:
Hankwembo Christopher,FCCA,FZICA,CIA,MAAT,B.A.Sc
  • 4
  • 3
  • 2
  • +1
1 Solution
 
Fabrice LambertFabrice LambertCommented:
Hi,

What do you need ?
The current user logged in windows (login name) ?

If so, rather than using troublesome APIs, you have some alternatives available:
1) Using environment variables:
Dim user As String
user = environ("USERNAME")

Open in new window


2) Using Wscript.Network object:
Dim wshNet As Object
Set wshNet = CreateObject("WScript.Network")

Dim user As String
user = wshNet.UserName
Set wshNet = Nothing

Open in new window

1
 
Hankwembo Christopher,FCCA,FZICA,CIA,MAAT,B.A.ScDirectorAuthor Commented:
What I need is to store the captured detail in login table then use the captured details on the queries so that the following can appear on the reports:

(1) The person who created the voucher
(2) The person who approved the voucher


On the code below it worked very well but for some reasons it has stopped and start blocking other code , I believe there is just one more declaration missing here:


#IF Win64 THEN
  Declare PtrSafe Function GetUserName Lib "advapi32.dll" Alias "GetUserNameA" (ByVal _
   lpBuffer As String, nSize As Long) As LongPtr
#Else
  Declare Function GetUserName Lib "advapi32.dll" Alias "GetUserNameA" (ByVal _
   lpBuffer As String, nSize As Long) As Long
#End If
Public Function GetUser() As String

   Dim strBuffer As String
   Dim lngSize As Long, lngRetVal As Long
   
   lngSize = 199
   strBuffer = String$(200, 0)
   
   lngRetVal = GetUserName(strBuffer, lngSize)
   
   GetUser = Left$(strBuffer, lngSize - 1)

End Function


Public Function GetFullName()

    Const MESSAGETEXT = "The current user is not recorded in the Users table."
    Dim strCriteria As String
    Dim varFullName As Variant
   
    strCriteria = "LoginName = """ & GetUser & """"

    varFullName = DLookup("FullName", "Users", strCriteria)
   
    If Not IsNull(varFullName) Then
        GetFullName = varFullName
    Else
        MsgBox MESSAGETEXT, vbExclamation, "Warning"
    End If
       
End Function

Public Function AddNewUser()

    Dim strCriteria As String
    Dim strLoginName As String
    Dim strFullName As String
    Dim strSQL As String
   
    strLoginName = GetUser()
    strCriteria = "LoginName = """ & strLoginName & """"
   
    If IsNull(DLookup("LoginName", "Users", strCriteria)) Then
        strFullName = InputBox("Enter new user's full name:")
        strSQL = "INSERT INTO Users(LoginName,FullName) " & _
            "VALUES(""" & strLoginName & """,""" & strFullName & """)"
   
        CurrentDb.Execute strSQL, dbFailOnError
    End If

End Function
0
 
Fabrice LambertFabrice LambertCommented:
Scratch these APIs and use one of the alternative I posted.
0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

 
Bill PrewCommented:
If you did want to stay with the existing APIs (and I agree for getting the user ID I would use a pure VBA approach rather than the older Windows API approach), this change should get you going:

   lngRetVal = CLng(GetUserName(strBuffer, lngSize))

Open in new window


»bp
0
 
Bill PrewCommented:
So you could replace all of this:

#IF Win64 THEN
  Declare PtrSafe Function GetUserName Lib "advapi32.dll" Alias "GetUserNameA" (ByVal _
   lpBuffer As String, nSize As Long) As LongPtr
#Else
  Declare Function GetUserName Lib "advapi32.dll" Alias "GetUserNameA" (ByVal _
   lpBuffer As String, nSize As Long) As Long
#End If
Public Function GetUser() As String

   Dim strBuffer As String
   Dim lngSize As Long, lngRetVal As Long
   
   lngSize = 199
   strBuffer = String$(200, 0)
   
   lngRetVal = GetUserName(strBuffer, lngSize)
   
   GetUser = Left$(strBuffer, lngSize - 1)

End Function

Open in new window

With:

Public Function GetUser() As String
    GetUser = Environ("USERNAME")
End Function

Open in new window


»bp
0
 
Jim Dettman (Microsoft MVP/ EE MVE)President / OwnerCommented:
Couple things:

1. Using an Environ variable, your opening up a security hole.   Any user that can get to the command line would then be able to circumvent security.   The API is a better approach as you are then getting a username based on authenticated credentials.

2. On this:

"#IF Win64 THEN"

   What's critical in your code is the "bitness" of Office  that is installed, not Windows.   The WIN64 constant is used to tell if your running in 64 or 32 bit VBA.    The constant VBA7 tells you if your running in VBA from Access 2010 and up, or prior.

For help with 32 vs 64 bit Access code, see the links in this comment:

https://www.experts-exchange.com/questions/27190589/GetUserName-fails-on-64bit-Access.html#a36167741

 also, you don't say what's wrong with your code, but the call for that was not modified for 64 bit..  You should be able to do:

Declare PtrSafe Function GetUserName Lib "advapi32.dll" Alias "GetUserNameA" (ByVal lpBuffer As String, nSize As Long) As Long

 and be fine in A2010 and up with 32 or 64 bit Access.

Jim.
1
 
Hankwembo Christopher,FCCA,FZICA,CIA,MAAT,B.A.ScDirectorAuthor Commented:
I have tried this in the past , this is not even reliable, it works if one is using the same computer but the moment you move your database to  another computer with runtime environment it stops working!

That is the reason why I'm not using it. For example according to your code , I was using it like like below , please follow me:

(1) Create a module:

Public Function GetUser() As String
    GetUser = Environ("USERNAME")
End Function

(2) At form level

I will create a control which I want to be inserted with the window login details

Then I will use this

Before insert event

Me. txtCreatedby = GetUser()

End sub

Please check and confirm  if I'm  I was not doing the right thing!

On the approval side

I will use  form current event

with Me.txtauthorized by = GetUser()

Regards

Chris
0
 
Hankwembo Christopher,FCCA,FZICA,CIA,MAAT,B.A.ScDirectorAuthor Commented:
also, you don't say what's wrong with your code, but the call for that was not modified for 64 bit..  You should be able to do:

Now what about doing it like below:

#If VBA7 And Win64 Then
    'x64 Declarations
    Private Declare PtrSafe Function apiGetUserName Lib "advapi32.dll" Alias _
            "GetUserNameA" (ByVal lpBuffer As String, nSize As Long) As Long
#Else
    'x32 Declaration
    Private Declare Function apiGetUserName Lib "advapi32.dll" Alias _
            "GetUserNameA" (ByVal lpBuffer As String, nSize As Long) As Long
#End If

Regards

Chris
0
 
Jim Dettman (Microsoft MVP/ EE MVE)President / OwnerCommented:
It would be this:

#If VBA7 Then
    ' A2010 and up.  Works in 32 or 64 bit Office
    Declare PtrSafe Function apiGetUserName Lib "advapi32.dll" Alias  "GetUserNameA" (ByVal lpBuffer As String, nSize As Long) As Long
#Else
    ' A2010 and prior.
     Declare Function apiGetUserName Lib "advapi32.dll" Alias "GetUserNameA" (ByVal lpBuffer As String, nSize As Long) As Long
#End If

 In that link I posted earlier was this:

Compatibility Between the 32-bit and 64-bit Versions of Office 2010
http://msdn.microsoft.com/en-us/library/ee691831(office.14).aspx

Read the section "Introducing the VBA 7 Code Base", which describes the use of VBA7 and WIN64 constants.  Very confusing at first, but what you want is:

1. Use VBA7 for code in A2010 and up vs prior versions of Access where you want to do 32 and 64 bit.  (allows you to use PtrSafe).

2. WIN64 for when the API call being made is different between 32 and 64 bit Access code.

 In this case, the call is the same call in both 32 and 64 bit.  So all you need is a statement that checks if your in A2010 and up code.  If so, then you can use PtrSafe.     PtrSafe is not required in 32 bit, but it is for 64 bit.    but if you use it in 32 bit code with A2010 and up, then it is just ignored.

Now let's say the call was different between 32 and 64 bit.   That would look like this:

#If VBA7 then
 ' Running in A2010 and up
 ' Are we running 64 bit?   Differnet call for lib if in 64 bit - needs LongLong data type.
  #if Win64 then
     Declare PtrSafe Function MyMathFunc Lib "User32" (ByVal N As LongLong) As LongLong
  #else
     ' Running 32 bit.  Using PtrSafe, but it is not really needed as it is ignored.
     Declare PtrSafe Function MyMathFunc Lib "User32" (ByVal N As Long) As Long
  #end if
#else
  ' Running in something prior to A2010
  ' Can't use PtrSafe
   Declare Function MyMathFunc Lib "User32" (ByVal N As Long) As Long
#end if
1
 
Jim Dettman (Microsoft MVP/ EE MVE)President / OwnerCommented:
Chris,

  Also note that you had "Private" in the front of your declares.   I dropped that so they work throughout the app.   not sure how you had things setup, but that might have been part of your problem.

Jim.
0
 
Hankwembo Christopher,FCCA,FZICA,CIA,MAAT,B.A.ScDirectorAuthor Commented:
Thanks very much
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

  • 4
  • 3
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now