Printable Version of Topic

Click here to view this topic in its original format

UtterAccess Forums _ Access Knowledgebase / FAQ _ Finding The Mscomctllib On Windows 64 Bit

Posted by: GlenKruger Oct 20 2015, 01:19 PM

Finding the MSComctlLib on a 64 Bit version of Windows and setting the reference with code.

What this code does is open the database check which version of Access computer is running (32 or 64 Bit), then checks what version of Windows (32 or 64 Bit) then removes the reference to the MSComctlLib (MSCOMCTL.OCX), then sets the reference to the MSComctlLib (MSCOMCTL.OCX) from the correct location. Why would anyone need to do this is because the reference is located in different folders depending on which version of Windows the computer is running. You need to check which version of Access so you use the proper code to call the APIís used. This will eliminate errors on different computer configurations saving confusion and the need to fix the missing reference manually.
I have attached the code in a text document used to create a demo.

I hope you find this may come in handy.

 SetReferenceFromCode_.txt ( 5.78K ): 291
 

Posted by: ScottGem Mar 25 2016, 09:46 AM

Hey Glen,

I'm having a problem with this but its an Excel workbook, not an Access db. would the code work? Do the same issues apply?

Posted by: GlenKruger Apr 5 2016, 12:27 PM

Hi Scott,
I am not sure if this will work for Excel but the same issues would apply.
The reason is that the oxc isn't in the system 32 folder on a Windows 64 bit machine.

Posted by: JohnvanSomeren Aug 5 2016, 10:11 AM

Hi GlenKruger
This code is exactly what I need. The office PCs are all 32-bit Windows 7 and I have recently changed my domestic laptop to 64-bit Windows 10. Amazingly enough I almost completely understand what the code does!
I am in the office (Windows 7 32-bit running on a 32-bit computer) and I have added your code to the version I last compiled at home. However, I couldn't test it until I had manually replaced the ref to
MSCOMCTL.OCX in the VBA project unter Tools|References.

Except that it fails in Sub CheckWhetherIts64

CODE
Public Sub CheckWhetherIts64()

    Dim Its64 As Variant
    Dim handle As Variant

    handle = GetProcAddress(GetModuleHandle("kernel32"), _
                   "IsWow64Process")
  
    If handle > 0 Then
        ' IsWow64Process function exists
        ' Now use the function to determine if
        ' we are running under Wow64

        IsWow64Process GetCurrentProcess(), Its64
      
    End If
    
    If Its64 = 0 Then
        Call CheckRefereces
        Application.References.AddFromFile "c:\windows\SysWOW64\MSCOMCTL.OCX"
        Call GetRefereces
      Else
        Call CheckRefereces
        Application.References.AddFromFile "c:\windows\System32\MSCOMCTL.OCX"
        Call GetRefereces
    End If
End Sub
The code [ handle = GetProcAddress(GetModuleHandle("kernel32"), _
"IsWow64Process")] returns a handle and the code [IsWow64Process GetCurrentProcess(), Its64] returns 0.

Consequently the code looks to add the MSCOMCTL.OCX from SysWOW64. I have checked (sight-checked) that I have cut-and-pasted the module correctly and it does compile.

Have you any idea why this is not working the way I expected?

Regards
John

Posted by: GlenKruger Aug 6 2016, 08:42 AM

Hi John,

QUOTE
However, I couldn't test it until I had manually replaced the ref to
MSCOMCTL.OCX in the VBA project unter Tools|References.


The Call to CheckReferences should have removed the reference before adding it to the database.
It has to be removed before you can add it from file. I have tested this in both W7 32bit andAccess 2007 32bit and W10 64bit and Access 2013 64 bit. Can you put a break point in the module at the CheckReferences and step through the code an see if any errors are poping up and get back to me.

Posted by: GlenKruger Aug 6 2016, 12:31 PM

Hi John,
You tell me you are using Access 2010 32 bit on both home and office set ups so possibly there is something happening when checking if Access is 64 bit. I have adjusted the code I believe you will need. See the attached .txt file. I have not experienced what you are saying is happening so I would like you to try this code out in a newly created demo database and see if it eliminates the error. Let me know how you make out.

 For_John.txt ( 2.49K ): 18
 

Posted by: ADezii Aug 6 2016, 01:06 PM

@Glen:

  1. First and foremost, great piece of Code! It is my understanding that if a Value = 1 is returned in Its64, then it is a 64-Bit System, but the Code seems to indicate otherwise. I apologize if I am incorrect in my thinking.
    CODE
    If handle > 0 Then
      ' IsWow64Process function exists
      ' Now use the function to determine if
      ' we are running under Wow64

       IsWow64Process GetCurrentProcess(), Its64    
    End If
        
    If Its64 = 0 Then
    Call CheckRefereces
       Application.References.AddFromFile "c:\windows\SysWOW64\MSCOMCTL.OCX"
         Call GetRefereces
    Else
       Call CheckRefereces
          Application.References.AddFromFile "c:\windows\System32\MSCOMCTL.OCX"
             Call GetRefereces
    End If
  2. Shouldn't it be:
    CODE
    If Its64 = 1 Then
    Call CheckRefereces
       Application.References.AddFromFile "c:\windows\SysWOW64\MSCOMCTL.OCX"
         Call GetRefereces
    Else
       Call CheckRefereces
          Application.References.AddFromFile "c:\windows\System32\MSCOMCTL.OCX"
             Call GetRefereces
    End If

Posted by: GlenKruger Aug 6 2016, 08:52 PM

If Its64 should return a 0 if the OS is 64 bit and 1 if OS is 32 bit.
I just tested the code on Windows 10 64 Bit and Access 2013 64 Bit and all runs fine. I can't understand why John is getting different results. When I first put this together I tested it on both 32 bit Windows 7 and Windows 8 64 Bit and all worked just fine.

Posted by: ADezii Aug 7 2016, 08:48 AM

@Glen:
Thanks for the clarification. The only reason that I ask is that I am running 64-Bit Windows 10 and the returned Value is exactly the opposite, namely: 32-Bit Windows (Its64=1). Very strange, will let you know if I can figure this out.

Posted by: JohnvanSomeren Aug 7 2016, 10:37 AM

Hi GlenKruger and Dezii

EDIT:
I am now totally confused as to whether ts64 contains 1 or 0 on a 64 bit machine. Wait 2 minutes while I retest!
EDIT after retest: Its64 is DEFINITELY = 1 on my 64-bt machine. I just wrote it up wrongly on the last line of the next paragraph.

Thanks for the revised module code, Glen. I used it in the attached zip of my test program. I have to say that my two laptops (Windows10 64-bit and Windows10 32-bit) agree with Dezii in that Its64 contains 1 for W10 32-bit and 0 for W10-64-bit. I changed the IF statement to accommodate that and the code now works: it selects the correct folder as the location of MSCOMCTL.OCX

 MSCOMCTLTEST.zip ( 43.32K ): 37


Glen: my application will be open all day for some people and, things being what they are, may not be closed gracefully every day. Therefore it will not execute the sub RemoveRefToOCX. Next time they start the application the "AddFromFile command will report an error because the reference is already present. I can see an advantantage in calling RemoveRefToOCX to immediately before the AddFromFile command. Does this have any disadvantages, from your knowledge and experience?

Anyway, thanks for your help and the others ho contributed.

Regards
John

Posted by: GlenKruger Aug 7 2016, 11:46 AM

@Dez
This is strange indeed, maybe the version of Windows 10 has something to do with it. I am running Windows 10 Enterprise 1511.

Posted by: GlenKruger Aug 7 2016, 11:51 AM

John the Call to CheckReferences looks to see if you have the reference and if so then calls RemoveRefToOCX. So you shouldn't need a separate call to it.

Posted by: JohnvanSomeren Aug 7 2016, 12:11 PM

Thanks for that update, Glen.

I am using Windows 10 Home, with Office Professional 2010. The system type is "64-bit operating system, x64-based processor"

Regards
John

Posted by: GlenKruger Aug 7 2016, 12:36 PM

Hi guys I just tested it out on a Home version of Windows 10 64 Bit also and I get the same results as you. My conclusion is that the Enterprise version somehow returns different values. I don't think my neighbor was to happy I woke him up to borrow his Laptop but too bad it was time he got up.

Posted by: ADezii Aug 7 2016, 03:34 PM

QUOTE
My conclusion is that the Enterprise version somehow returns different values.

I think you hit the nail on the head. I also tested my Windows 10 - 64-Bit Installation with the #If Win64 Compilation Constant and it returned False indicating that my 64-Bit Windows is NOT 64-Bit. Very strange indeed.

Posted by: GlenKruger Aug 8 2016, 09:38 AM

@ADezil
I have updated the Module code to get the version of Windows to see if it is Windows 10 Enterprise and if it is set Its64 to zero haven't tested it out on a regular Home version yet though. See the attached text document.

 Updated_Set_Reference_From_Code_Module.txt ( 4.02K ): 14
 

Posted by: GlenKruger Aug 8 2016, 11:20 AM

@ADezil
Not sure if Windows 10 Enterprise Comes in a 32 bit version more checking need but I thought I had better do a check to see if the achritexture is 64-bit before changing Its64 to zero. Attached new module code. I think I maybe trying to make this too complicated so I am going to try and simplify this as we know that if the OS is 64 bit where the ocx will be located so don't really need half the code.

 NewestUpdateModule.txt ( 4.09K ): 23
 

Posted by: ADezii Aug 8 2016, 11:31 AM

It doesn't appear that the Value returned in Its64 is reliable for certain Operating Systems. Very puzzling.

A quick check on MSDN revealed that if the

CODE
IsWow64Process GetCurrentProcess(), Its64

Function succeeds (<> 0), then the Return Value will be 1, indicating a 64-Bit System. Now, really confused. The following works for a couple of my PCs:
CODE
If Its64 = 1 Then
  Call CheckRefereces
    Application.References.AddFromFile "c:\windows\SysWOW64\MSCOMCTL.OCX"
Else
  Call CheckRefereces
    Application.References.AddFromFile "c:\windows\System32\MSCOMCTL.OCX"
End If

Posted by: GlenKruger Aug 8 2016, 12:57 PM

Exactly it is too unreliable so I simplified it too just check the bit value of OS. No API calls no check needed for 64 or 32 bit Access.
I think this will work better as the Enterprise version is not the only one that returns false values Server 2012 does also. I have attached a demo.

 SimplifiedSetReferenceFromFile_2K13.zip ( 94.69K ): 49
 

Posted by: JohnvanSomeren Aug 8 2016, 04:46 PM

Hi GlenKruger and IDezii, I have just spent a mind-bending half hour reading some of the bits of MSDN that refer to WMI. I have learnt that I can ask Windows if the user is sitting at a mini-tower or a laptop or whatever. Who knew?

Anyway, Glen, your implementation of this arcane black magic does the job for me and I am now ready to catch up on the user's change requests whose arrival rate hasn't slowed down just because I have spent a week working out how I can work in my own time, at home, on company business and then carry on working eight hours later on company time in the office on slightly dated hardware and software without having to point Access to MSCOMCTL.OCX manually.

Just a final thought...what would we (I mean you) do if WMI calls needed an OCX which was held in a folder whose location depended on the OS's architecture?

Thanks both of you for taking up my problem as if it was your own and worrying at it until it was sorted. That's what sets this board head and shoulders above all the others.

John

Posted by: GlenKruger Aug 8 2016, 08:58 PM

QUOTE
Just a final thought...what would we (I mean you) do if WMI calls needed an OCX which was held in a folder whose location depended on the OS's architecture?


It has been an integral part of windows for like ever so I am not to worried about it.
Forgot how much I liked using WMI!

Not sure if you downloaded the demo I posted but it is even simpler code which by the way works on all OS's. I reformatted an old laptop with Windows 7 32 bit to test code and worked like a charm.

There are no API's no need to test Access bit value just need a small function to check for using WMI to get OS architecture value.

Posted by: GlenKruger Aug 9 2016, 02:39 PM

John I forgot you were using Access 2010 so find attached a text document of the simplified code.

 Demo_Code.txt ( 2.94K ): 12
 

Posted by: JohnvanSomeren Aug 9 2016, 02:58 PM

That was a nice thought.

All is well now and an old friend of mine, now 80, who last put code through a compiler in the days when everybody was looking for COBOL programmers to solve Y2000 issues, suggested a that it was an idiot who put MSCOMCTL.OCX in a folder whose named changed with the version of the OS. He suggested that the idiot, and those above him, should be made to push peas uphill with their noses because they were too shortsighted to be good at anything else. I like the idea.

John