2012-01-20

Windows 64bit scripting host forced into 32bit

Error: [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified
Code: 80004005

Using Windows Script Host (WSH, CScript, VBS) to access Microsoft Access database files will bring this error up in 64 bit Windows. You need to force your script to run in 32 bit mode. The following code attached to the top of your script should detect if you are in a 64 bit Windows OS and will attempt to run the 32 bit cscript.
(Update 2014-02-28: Aborts when there are spaces in the path, added quotes to fix this) (Update 2016-01-28: fix for 64bit office vs 32bit office)

' ***************
' *** 64bit check
' ***************
' check to see if we are on 64bit Windows OS with 32bit MS Office -> re-run this script forcing 32bit mode cscript

Dim r32OSbit, r32Officebit
r32OSbit = CPUbitness()
r32Officebit = OfficeBitness()
WScript.Echo "OS mode " & r32OSbit & " with Office " & r32Officebit
If r32OSbit = "AMD64" AND r32Officebit= "x86" Then
 If MatchAnyArg("restart32") = 0 Then RestartWithCScript32 "restart32" Else MsgBox "Cannot find 32bit version of cscript.exe or unknown OS type " & r32OSbit
 WScript.Quit
End If

' Function to determine bitness of the installed Microsoft Office
FUNCTION OfficeBitness ()
' Returns x64 or x86, or "?" if no office found
CONST MaxOfficeVer = 20 ' currently 15 (2015-08-04)
CONST MinOfficeVer = 10
DIM objShell, i, Found, thisNode, regNode
Set objShell = WScript.CreateObject("WScript.Shell")
On Error Resume Next
i = MaxOfficeVer + 1
Found = False
DO
 i = i - 1
 thisNode = "HKLM\Software\Microsoft\Office\" & i & ".0\Outlook\Bitness"
 regNode = objShell.RegRead (thisNode)
 IF Err.Number <> 0 THEN
  Err.Clear
 Else
  Found = True
 End If
LOOP UNTIL i = MinOfficeVer OR Found
IF Found THEN
 OfficeBitness = regnode
 'WScript.Echo regnode & " for office version " & i & ".0"
ELSE
 OfficeBitness = "?"  'No office found in registry range
END IF
END FUNCTION

FUNCTION CPUbitness()
' AMD64 IA64 x86
Dim r32wShell, r32env1
Set r32wShell = WScript.CreateObject("WScript.Shell")
r32env1 = r32wShell.ExpandEnvironmentStrings("%PROCESSOR_ARCHITECTURE%")
CPUbitness = r32env1
Set r32wShell = Nothing
End Function

Function MatchAnyArg(thisArg)
Dim FoundArg, r32i
FoundArg = FALSE
IF WScript.Arguments.Count <> 0 THEN
 r32i = 0
 thisArg = lcase(thisArg)
 DO
  IF lcase(WScript.Arguments(r32i)) = thisArg THEN FoundArg = True
  r32i = r32i + 1
 LOOP Until FoundArg OR r32i >= WScript.Arguments.Count
END IF
MatchAnyArg = FoundArg
End Function

Function RestartWithCScript32(extraargs)
Dim strCMD, iCount, r32wShell, r32fso
SET r32fso = CreateObject("Scripting.FileSystemObject")
SET r32wShell = WScript.CreateObject("WScript.Shell")
strCMD = r32wShell.ExpandEnvironmentStrings("%SYSTEMROOT%") & "\SysWOW64\cscript.exe"
If NOT r32fso.FileExists(strCMD) Then strCMD = "cscript.exe"
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
Set r32wShell = Nothing
SET r32fso = Nothing
End Function

' *******************
' *** END 64bit check
' *******************

1 comment:

Cert Killer said...

In my point of view You sure did put a new twist on something that Ive heard so much about. And How did you manage to make a blog that as smart as it is sleek?