Solved

64-bit VBA

Posted on 2011-03-03
25
7,281 Views
Last Modified: 2012-05-11
Now that I'm upgraded to 64-bit, I need to update some of my Declare statements.
However, I am also going to make sure this is backward compatible so those still on the 32-bit systems can run it.  I think I can handle that part with the #IF declaration but tell me if I'm handling that wrong.

So all I did for now is copy the 32-bit declare into the 64-bit section and changed the kernel reference.  As expected, it doesn't quite work.  What do I need to fix?

Basically, I'm opening a DOS window and monitoring it to find out when it closes so I can pop up a message box.  That all works great in the 32-bit arena.
 
Private Declare PtrSafe Function GetExitCodeProcess Lib "kernel32" ( _
        ByVal hProcess As Long, _
        lpExitCode As Long) As Long
    Private Declare PtrSafe Function OpenProcess Lib "kernel32" ( _
        ByVal dwDesiredAccess As Long, _
        ByVal bInheritHandle As Long, _
        ByVal dwProcessId As Long) As Long
    Private Const STILL_ACTIVE = &H103
    Private Const PROCESS_QUERY_INFORMATION = &H400
    Private Declare PtrSafe Function CloseHandle Lib "kernel32" ( _
        ByVal hObject As Long) As Long
#Else
    Private Declare PtrSafe Function GetExitCodeProcess Lib "kernel64" ( _
        ByVal hProcess As Long, _
        lpExitCode As LongPtr) As Long
    Private Declare PtrSafe Function OpenProcess Lib "kernel64" ( _
        ByVal dwDesiredAccess As Long, _
        ByVal bInheritHandle As Long, _
        ByVal dwProcessId As Long) As Long
    Private Const STILL_ACTIVE = &H103
    Private Const PROCESS_QUERY_INFORMATION = &H400
    Private Declare PtrSafe Function CloseHandle Lib "kernel64" ( _
        ByVal hObject As Long) As Long
#End If

Open in new window

0
Comment
Question by:rspahitz
  • 16
  • 6
  • 2
  • +1
25 Comments
 
LVL 30

Assisted Solution

by:SiddharthRout
SiddharthRout earned 100 total points
ID: 35028722
An interesting read for you.

http://msdn.microsoft.com/en-us/library/ee691831.aspx

Read the section Application Programming Interface Compatibility

Sid
0
 
LVL 85

Assisted Solution

by:Rory Archibald
Rory Archibald earned 400 total points
ID: 35028764
Also have a look here: http://www.jkp-ads.com/Articles/apideclarations.asp
Jan Karel (and RdB) have done a few conversions and there's a general guide as to what does and what doesn't need conversion.
0
 
LVL 22

Author Comment

by:rspahitz
ID: 35028876
Cool! and sure enough, the 3 I'm using aren't listed.  I suppose I could guess and see what happens...

Private Declare PtrSafe Function GetExitCodeProcess Lib "kernel64" ( _
        ByVal hProcess As Long, _ <= LongPtr***************
        lpExitCode As Long <= LongPtr***************) As Long

    Private Declare PtrSafe Function OpenProcess Lib "kernel64" ( _
        ByVal dwDesiredAccess As Long, _
        ByVal bInheritHandle As Long<= LongPtr***************, _
        ByVal dwProcessId As Long) As Long

    Private Declare PtrSafe Function CloseHandle Lib "kernel64" ( _
        ByVal hObject As Long<= LongPtr***************) As Long
0
 
LVL 85

Expert Comment

by:Rory Archibald
ID: 35028921
That looks like what I would guess too. :)
0
 
LVL 22

Author Comment

by:rspahitz
ID: 35029026
Digging into the MS help files, it looks like it should be this, but it still doesn't work:
( e.g. http://msdn.microsoft.com/en-us/library/ms724211(VS.85).aspx )

    Private Declare PtrSafe Function GetExitCodeProcess Lib "kernel64" ( _
        ByVal hProcess As LongPtr, _
        lpExitCode As LongPtr) As Boolean

    Private Declare PtrSafe Function OpenProcess Lib "kernel64" ( _
        ByVal dwDesiredAccess As Long, _
        ByVal bInheritHandle As Boolean, _
        ByVal dwProcessId As Long) As LongPtr

    Private Declare PtrSafe Function CloseHandle Lib "kernel64" ( _
        ByVal hObject As LongPtr) As Boolean
0
 
LVL 30

Expert Comment

by:SiddharthRout
ID: 35029046
Unfortunately I don't have a 64 bit system so I can't test that for you :)

This is where I gracefully retreat :)

Sid
0
 
LVL 22

Author Comment

by:rspahitz
ID: 35029080
I'm not quite sure how to test these other than to check the return code I guess...but will it tell me if it failed to find it?
0
 
LVL 85

Assisted Solution

by:Rory Archibald
Rory Archibald earned 400 total points
ID: 35029103
I think it should still be kernel32.dll not kernel64.dll (missed that in your first posting)
0
 
LVL 22

Author Comment

by:rspahitz
ID: 35029218
odd...it seemed that the 64-bit stuff is not working so I added a message box and it tells me it's running the 32-bit version!

So now the question is why it's no longer working with the 32-bit version???
0
 
LVL 22

Author Comment

by:rspahitz
ID: 35029258
and ok about kernel32...maybe it didn't complain because it's running 32-bit...
and yet computer reports 64-bit OS in my computer.

but when I run this:


    #If Win32 Then
        MsgBox "win32"
#Else
        MsgBox "win64"
#End If

It says 32-bit...is there a separate 32-bit Office, even if you run 64-bit OS?  how do I check?
0
 
LVL 85

Expert Comment

by:Rory Archibald
ID: 35029325
You only need the revised API if you are running 64 bit Office, not 64 bit windows.
0
 
LVL 22

Author Comment

by:rspahitz
ID: 35029337
hmmm...apparently work gave me the 32-bit office 2010, I guess.

so why is it not working compared to Office 2003?  those APIs shouldn't change, right? they're not office APIs...
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 22

Author Comment

by:rspahitz
ID: 35029340
(oh and office 2003 was on the XP machine, not this Win7-64 machine.)
0
 
LVL 22

Author Comment

by:rspahitz
ID: 35030032
FYI...I'll be off the board until Sunday so I'll get back to this next week and see if we can solve it, although it seems that the problem is not what I thought and may not be related to 64-bit.
0
 
LVL 85

Expert Comment

by:Rory Archibald
ID: 35030068
If you can post full code I can test on office 32 bit on win 7 64 bit.
0
 
LVL 22

Author Comment

by:rspahitz
ID: 35030154
Let me drop what I think are the relevant pieces here
'Debug.Print "running as win32"
    Private Declare PtrSafe Function GetExitCodeProcess Lib "kernel32" ( _
        ByVal hProcess As Long, _
        lpExitCode As Long) As Boolean
    Private Declare PtrSafe Function OpenProcess Lib "kernel32" ( _
        ByVal dwDesiredAccess As Long, _
        ByVal bInheritHandle As Boolean, _
        ByVal dwProcessId As Long) As Long
    Private Declare PtrSafe Function CloseHandle Lib "kernel32" ( _
        ByVal hObject As Long) As Boolean
    Private Declare PtrSafe Function GetLastError Lib "kernel32" () As Long
#Else
    'Debug.Print "running as win64"
    Private Declare PtrSafe Function GetExitCodeProcess Lib "kernel32" ( _
        ByVal hProcess As LongPtr, _
        lpExitCode As LongPtr) As Boolean
    Private Declare PtrSafe Function OpenProcess Lib "kernel32" ( _
        ByVal dwDesiredAccess As Long, _
        ByVal bInheritHandle As Boolean, _
        ByVal dwProcessId As Long) As LongPtr
    Private Declare PtrSafe Function CloseHandle Lib "kernel32" ( _
        ByVal hObject As LongPtr) As Boolean
    Private Declare PtrSafe Function GetLastError Lib "kernel32" () As Long
#End If
Private Const STILL_ACTIVE = &H103
Private Const PROCESS_QUERY_INFORMATION = &H400

Private Function WaitForCompletion(dblWindowID As Double) As Boolean
    ' see if specified window is still running
    Dim bWaitForCompletion As Boolean
    #If Win32 Then
        Dim hProcess As Long
        Dim lR As Long
    #Else
        Dim hProcess As LongPtr
        Dim lR As LongPtr
    #End If
    Dim lTimeStart As Long
    
    Const TimeOut As Long = 10000 ' 10 seconds

    bWaitForCompletion = True ' for now just assume it is done...will require a separate process check.
    
    lTimeStart = Now()

    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, False, dblWindowID)
    If hProcess <> 0 Then
        Do 'ShellExecute(dblWindowID) <> 0    ' Has Shelled program finished?
            GetExitCodeProcess hProcess, lR
            
            If lR = 0 Then
                Debug.Print GetLastError()
            Else
                Debug.Print lR;
            End If
            DoEvents
            If Now - lTimeStart > TimeOut Then
                Exit Do
            End If
        Loop While lR = STILL_ACTIVE
    End If
    Debug.Print
    
    WaitForCompletion = bWaitForCompletion
End Function

sub RunFTPBatchFile()
    Dim strFullFTPCommandLine As String
    Dim bTransferCompleted As Boolean
    Dim dblWindowID As Double
...

            strFullFTPCommandLine = "cmd /c ""C:\Temp\abc.bat"" > tempout.txt"
            dblWindowID = Shell(strFullFTPCommandLine) 
            bTransferCompleted = False
            Do Until bTransferCompleted
                bTransferCompleted = WaitForCompletion(dblWindowID)
            Loop
...
end sub

Open in new window

I hope I got all the pieces.
0
 
LVL 22

Author Comment

by:rspahitz
ID: 35030159
lost this as the first line:

#If Win32 Then
0
 
LVL 22

Author Comment

by:rspahitz
ID: 35030200
What should happen is that the VBA will wait until the window is close.  so you can change the /c to /k and it should wait until you Exit the DOS window (Exit command or close it), then maybe show a message box.

What's happening is that the GetExitCodeProcess is returning 0 in lR variable, which apparently means there was an error.  But when I check the error information with GetLastError, it also shows 0 (although I have no idea what it is supposed to give me.)

When I used to run it on XP, the code would wait until the DOS window closed, then complete the procedure.
0
 
LVL 85

Assisted Solution

by:Rory Archibald
Rory Archibald earned 400 total points
ID: 35030765
Your code works fine for me after I remove the PtrSafe parts of the #Win32 declares.
0
 
LVL 22

Assisted Solution

by:rspahitz
rspahitz earned 0 total points
ID: 35031037
If I remove PtrSafe from the 32-bit declares, my lines turn red and I get a message on compile:

"The code in this project must be updated for use on the 64-bit systems.
Please review and update Declare statements and then mark then with
the PtrSafe attribute."

:(
0
 
LVL 22

Accepted Solution

by:
rspahitz earned 0 total points
ID: 35031293
OK...I figured it out...
from this link:

http://msdn.microsoft.com/en-us/library/gg264614.aspx

I was checking for 32-bit first, and if not then using 64-bit.
Apparently the current 64-bit version is compatible with 32-bit so the win32 directive constant is set to yes...that led me to believe that I was running a 32-bit version.

by checking for win64 first, it properly used the LongPtr variables, so like this for the declares and dims:

    #If Win64 Then
        Dim hProcess As LongPtr
        Dim lR As LongPtr
    #Else
        Dim hProcess As Long
        Dim lR As Long
    #End If

Since I'm assuming it will never use 16-bit, I don't need the If Win32 check.

THANKS ALL!
0
 
LVL 22

Author Comment

by:rspahitz
ID: 35031325
Those links inspired me to find the right webpages to get the answer so I'm awarding most of the points there.
0
 
LVL 14

Expert Comment

by:Zack Barresse
ID: 35048334
As a side note, you only need to declare Long variables as LongPtr if it references memory, as it's a different structure, otherwise a Long will work just fine in 64 bit.

Also, a bit of a misguidance (at least I think so), is the Win64 compilation bit is not checking for a 64 bit OS, but for 64 bit Office.  I think it's REALLY confusing the way they did that, and I know many who have requested it either be changed or updated.
0
 
LVL 22

Author Comment

by:rspahitz
ID: 35050019
Thanks FireFytr, and welcome :)
0
 
LVL 22

Author Closing Comment

by:rspahitz
ID: 35067812
Thanks all...awarded 100 pts to Sid and rest to Rory for the extended effort :)
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

Overview: This article:       (a) explains one principle method to cross-reference invoice items in Quickbooks®       (b) explores the reasons one might need to cross-reference invoice items       (c) provides a sample process for creating a M…
A simple tool to export all objects of two Access files as text and compare it with Meld, a free diff tool.
The viewer will learn how to use a discrete random variable to simulate the return on an investment over a period of years, create a Monte Carlo simulation using the discrete random variable, and create a graph to represent the possible returns over…
This Micro Tutorial will demonstrate in Microsoft Excel how to add style and sexy appeal to horizontal bar charts.

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now