59

I have a text file that ends with .vbs that I have written the following in:

Set Conn = CreateObject("ADODB.Connection")
Conn.Provider = "Microsoft.ACE.OLEDB.12.0"
Conn.Properties("Data Source") = "C:\dummy.accdb"
Conn.Properties("Jet OLEDB:Database Password") = "pass"
Conn.Open
Conn.Close
Set Conn = Nothing
  • When I execute this on a Windows 32-bit machine it runs and ends without any notion (expected).
  • When I execute this on a Windows 64-bit machine it gets the error

    Provider cannot be found. It may not be properly installed.

But it is installed. I think the root of the problem is that the provider is a 32-bit provider, as far as I know it doesn't exist as 64-bit.

If I run the VBScript through IIS on my 64-bit machine (as a ASP file) I can select that it should run in 32-bit mode. It can then find the provider.

How can I make it find the provider on Windows 64-bit? Can I tell CScript (which executes the .vbs text file) to run in 32-bit mode somehow?

General Grievance
  • 4,555
  • 31
  • 31
  • 45
Peter
  • 1,543
  • 3
  • 13
  • 9
  • Please note that even using 32-bit Cscript not all database providers gonna work. If the provider is a driver (example: SQLite) it does not work. You need to install 64-bit SQLite drivers on Windows 64-bit instead, so the provider will work in cscript 64-bits (and 32-bit cscript on 64-bit). – eduardomozart Jan 27 '14 at 13:30
  • ODBC Drivers are not OLEDB Providers at all. These are normally used with ADO via the shim Provider `MSDASQL` which is the default Provider for compatibility. Of course if you bring the even more obsolete System DSNs into the mix things get dicey due to registry visibility issues. – Bob77 Sep 16 '16 at 21:22

7 Answers7

83

follow http://support.microsoft.com/kb/896456

To start a 32-bit command prompt, follow these steps:

* Click Start, click Run, type %windir%\SysWoW64\cmd.exe, and then click OK.

Then type

cscript vbscriptfile.vbs
volody
  • 6,946
  • 3
  • 42
  • 54
25

WScript.exe exists in two versions, one in C:\Windows\System32\ and the other in C:\Windows\SysWOW64\ directories. They run respectively in 64 bits and 32 bits (against immediate logic but true).

You may add the following code at the beginning of your script so that it automatically starts again in 32 bits if it detects that it's called in 64 bits.

Note that it transmits the arguments if it calls itself to switch to 64 bits.

' C:\Windows\System32\WScript.exe = WScript.exe
Dim ScriptHost : ScriptHost = Mid(WScript.FullName, InStrRev(WScript.FullName, "\") + 1, Len(WScript.FullName))

Dim oWs : Set oWs = CreateObject("WScript.Shell")
Dim oProcEnv : Set oProcEnv = oWs.Environment("Process")

' Am I running 64-bit version of WScript.exe/Cscript.exe? So, call script again in x86 script host and then exit.
If InStr(LCase(WScript.FullName), LCase(oProcEnv("windir") & "\System32\")) And oProcEnv("PROCESSOR_ARCHITECTURE") = "AMD64" Then
    ' rebuild arguments
    If Not WScript.Arguments.Count = 0 Then
        Dim sArg, Arg
        sArg = ""
        For Each Arg In Wscript.Arguments
              sArg = sArg & " " & """" & Arg & """"
        Next
    End If

    Dim sCmd : sCmd = """" &  oProcEnv("windir") & "\SysWOW64\" & ScriptHost & """" & " """ & WScript.ScriptFullName & """" & sArg
    'WScript.Echo "Call " & sCmd
    oWs.Run sCmd
    WScript.Quit
End If
Sandra Rossi
  • 11,934
  • 5
  • 22
  • 48
Vozzie
  • 251
  • 3
  • 2
  • 4
    Add a little explanation please – Ed Heal Mar 10 '13 at 09:48
  • 2
    The above actually works extremely well. Just add your script to the bottom of it (after the End If) and it will run on a 64 bit OS the same as it runs on a 32 bit OS and do so transparently. My thanks. – Obi Wan Mar 11 '15 at 15:42
  • 2
    This is a golden nugget. Wrap it up in a `VerifyArchitecture` sub, toss the sub at the bottom of your script and call it on the first line. Deserves way more love than it's gotten! – jleach Sep 02 '16 at 16:00
15

If you have control over running the cscript executable then run the X:\windows\syswow64\cscript.exe version which is the 32bit implementation.

tyranid
  • 13,028
  • 1
  • 32
  • 34
5

We can force vbscript always run with 32 bit mode by changing "system32" to "sysWOW64" in default value of key "Computer\HKLM\SOFTWARE]\Classes\VBSFile\Shell\Open\Command"

Ronie Do
  • 61
  • 1
  • 1
  • That is not correct at all. I see under MS Windows 7 64bit following `"%SystemRoot%\System32\WScript.exe" "%1" %*` in place of the value for `Command`. – NoWar Nov 23 '15 at 15:43
  • 2
    (@ Academy of Programmer): Just to clarify 2.5 years later... Changing the registry key on a 64-bit computer from "System32" to "SysWow64" will indeed lead VBScript to run GUI scripts in 32-bit. You are correct that the default registry key points to System32\WScript.exe which is the 64-bit binary. Thank you Ronie Do for the contribution. – Page2PagePro Jan 22 '18 at 16:54
  • 2
    I think this is dangerous because then **any** VBS script will be executed in 32-bit. This might not be your intention. – Wernfried Domscheit May 11 '18 at 06:56
2
   ' ***************
   ' *** 64bit check
   ' ***************
   ' check to see if we are on 64bit OS -> re-run this script with 32bit cscript
   Function RestartWithCScript32(extraargs)
   Dim strCMD, iCount
   strCMD = r32wShell.ExpandEnvironmentStrings("%SYSTEMROOT%") & "\SysWOW64\cscript.exe"
   If NOT r32fso.FileExists(strCMD) Then strCMD = "cscript.exe" ' This may not work if we can't find the SysWOW64 Version
   strCMD = strCMD & Chr(32) & Wscript.ScriptFullName & Chr(32)
   If Wscript.Arguments.Count > 0 Then
    For iCount = 0 To WScript.Arguments.Count - 1
     if Instr(Wscript.Arguments(iCount), " ") = 0 Then ' add unspaced args
      strCMD = strCMD & " " & Wscript.Arguments(iCount) & " "
     Else
      If Instr("/-\", Left(Wscript.Arguments(iCount), 1)) > 0 Then ' quote spaced args
       If InStr(WScript.Arguments(iCount),"=") > 0 Then
        strCMD = strCMD & " " & Left(Wscript.Arguments(iCount), Instr(Wscript.Arguments(iCount), "=") ) & """" & Mid(Wscript.Arguments(iCount), Instr(Wscript.Arguments(iCount), "=") + 1) & """ "
       ElseIf Instr(WScript.Arguments(iCount),":") > 0 Then
        strCMD = strCMD & " " & Left(Wscript.Arguments(iCount), Instr(Wscript.Arguments(iCount), ":") ) & """" & Mid(Wscript.Arguments(iCount), Instr(Wscript.Arguments(iCount), ":") + 1) & """ "
       Else
        strCMD = strCMD & " """ & Wscript.Arguments(iCount) & """ "
       End If
      Else
       strCMD = strCMD & " """ & Wscript.Arguments(iCount) & """ "
      End If
     End If
    Next
   End If
   r32wShell.Run strCMD & " " & extraargs, 0, False
   End Function

   Dim r32wShell, r32env1, r32env2, r32iCount
   Dim r32fso
   SET r32fso = CreateObject("Scripting.FileSystemObject")
   Set r32wShell = WScript.CreateObject("WScript.Shell")
   r32env1 = r32wShell.ExpandEnvironmentStrings("%PROCESSOR_ARCHITECTURE%")
   If r32env1 <> "x86" Then ' not running in x86 mode
    For r32iCount = 0 To WScript.Arguments.Count - 1
     r32env2 = r32env2 & WScript.Arguments(r32iCount) & VbCrLf
    Next
    If InStr(r32env2,"restart32") = 0 Then RestartWithCScript32 "restart32" Else MsgBox "Cannot find 32bit version of cscript.exe or unknown OS type " & r32env1
    Set r32wShell = Nothing
    WScript.Quit
   End If
   Set r32wShell = Nothing
   Set r32fso = Nothing
   ' *******************
   ' *** END 64bit check
   ' *******************

Place the above code at the beginning of your script and the subsequent code will run in 32bit mode with access to the 32bit ODBC drivers. Source.

2

Alternate method to run 32-bit scripts on 64-bit machine: %windir%\syswow64\cscript.exe vbscriptfile.vbs

1

In the launcher script you can force it, it permits to keep the same script and same launcher for both architecture

:: For 32 bits architecture, this line is sufficent (32bits is the only cscript available)
set CSCRIPT="cscript.exe"
:: Detect windows 64bits and use the expected cscript (SysWOW64 contains 32bits executable)
if exist "C:\Windows\SysWOW64\cscript.exe" set CSCRIPT="C:\Windows\SysWOW64\cscript.exe"
%CSCRIPT% yourscript.vbs
Guilhem Hoffmann
  • 962
  • 5
  • 13