强制 vbscript 以 64 位而不是 32 位打开命令提示符
Force a vbscript to open command prompt in 64bit instead of 32bit
我一整天都在努力让这个脚本正常工作!
以下是关于我的情况的一些事实...
- 我的 "C:\Windows\System32\" 文件夹中有一个名为 "ffmpeg.exe" 的程序。
- 我的 "C:\Windows\SysWOW64\" 文件夹中没有该程序。
目前这是我的脚本...
Option Explicit
Dim oFSO, oShell, sCommand
Dim sFilePath, sTempFilePath
Set oFSO = CreateObject("Scripting.FileSystemObject")
sFilePath = "C:\test\in_video.mkv"
sTempFilePath = "C:\test\out_video.mp4"
sCommand = "%comspec% /k ffmpeg -n -i """ + sFilePath + """ -c:v copy -c:a copy """ + sTempFilePath + """"
WScript.Echo sCommand
Set oShell = WScript.CreateObject("WScript.Shell")
oShell.Run sCommand, 1, True
Set oShell = Nothing
Set oFSO = Nothing
如果我 运行 在命令提示符下手动执行此脚本,那么它似乎工作正常。但是,如果我让另一个应用程序 运行 它(例如在本例中为 uTorrent),它会按预期 运行 执行脚本,但是当它尝试处理 oShell.Run 命令时,它 运行 是在 32 位环境中!然后我得到这个...
如果我尝试打开一个新的命令提示符(没什么特别的),我似乎默认为 64 位环境,然后我可以键入 "ffmpeg",它会按预期显示帮助内容。
因此,出于某种原因,我无法在 64 位环境中获取 运行 应用程序(特别是 CMD)的脚本。有谁知道我怎样才能做到这一点?
更新
看来我的脚本实际上是 运行 32 位模式!即使脚本标题栏显示 "C:\Windows\System32\cscript.exe",这是一个 64 位环境!!
我使用下面的脚本来确定它是运行在32位环境中...
Dim WshShell
Dim WshProcEnv
Dim system_architecture
Dim process_architecture
Set WshShell = CreateObject("WScript.Shell")
Set WshProcEnv = WshShell.Environment("Process")
process_architecture= WshProcEnv("PROCESSOR_ARCHITECTURE")
If process_architecture = "x86" Then
system_architecture= WshProcEnv("PROCESSOR_ARCHITEW6432")
If system_architecture = "" Then
system_architecture = "x86"
End if
Else
system_architecture = process_architecture
End If
WScript.Echo "Running as a " & process_architecture & " process on a " _
& system_architecture & " system."
如果仅用于 cmd 或 System32 中的某些文件,您可以按照评论的建议使用 sysnative。它甚至会从 32 位可执行文件生成 64 位 System32。只需将 "system32" 替换为 "sysnative" 即可。 (不幸的是,这在 32 位 windows 上不存在,因此您需要检查是否在具有两种体系结构的系统上使用脚本...)
如果您有很多访问权限或使用 com 对象,我发现使用相同的方法重新启动脚本会更容易。以下代码:
If fso.FileExists("C:\Windows\SysWOW64\wscript.exe") Then ' very basic check for 64bit Windows, you can replace it with a more complicated wmi check if you find it not reliable enough
If InStr(1, WScript.FullName, "SysWOW64", vbTextCompare) <> 0 Then ' = case insensitive check
newFullName = Replace(WScript.FullName, "SysWOW64", "Sysnative", 1, -1, vbTextCompare) ' System32 is replaced by Sysnative to deactivate WoW64, cscript or wscript stay the same
newArguments = "" ' in case of command line arguments they are passed on
For Each arg In WScript.Arguments
newArguments = newArguments & arg & " "
Next
wso.Run newFullName & " """ & WScript.ScriptFullName & """ " & newArguments, , False
WScript.Quit '32 Bit Scripting Host is closed
End If
End If
只要用 32 位脚本主机调用它,基本上就会关闭脚本,然后用 64 位脚本主机重新启动它,这样一切都可以在预期的位置找到。
我一整天都在努力让这个脚本正常工作!
以下是关于我的情况的一些事实...
- 我的 "C:\Windows\System32\" 文件夹中有一个名为 "ffmpeg.exe" 的程序。
- 我的 "C:\Windows\SysWOW64\" 文件夹中没有该程序。
目前这是我的脚本...
Option Explicit
Dim oFSO, oShell, sCommand
Dim sFilePath, sTempFilePath
Set oFSO = CreateObject("Scripting.FileSystemObject")
sFilePath = "C:\test\in_video.mkv"
sTempFilePath = "C:\test\out_video.mp4"
sCommand = "%comspec% /k ffmpeg -n -i """ + sFilePath + """ -c:v copy -c:a copy """ + sTempFilePath + """"
WScript.Echo sCommand
Set oShell = WScript.CreateObject("WScript.Shell")
oShell.Run sCommand, 1, True
Set oShell = Nothing
Set oFSO = Nothing
如果我 运行 在命令提示符下手动执行此脚本,那么它似乎工作正常。但是,如果我让另一个应用程序 运行 它(例如在本例中为 uTorrent),它会按预期 运行 执行脚本,但是当它尝试处理 oShell.Run 命令时,它 运行 是在 32 位环境中!然后我得到这个...
如果我尝试打开一个新的命令提示符(没什么特别的),我似乎默认为 64 位环境,然后我可以键入 "ffmpeg",它会按预期显示帮助内容。
因此,出于某种原因,我无法在 64 位环境中获取 运行 应用程序(特别是 CMD)的脚本。有谁知道我怎样才能做到这一点?
更新
看来我的脚本实际上是 运行 32 位模式!即使脚本标题栏显示 "C:\Windows\System32\cscript.exe",这是一个 64 位环境!!
我使用下面的脚本来确定它是运行在32位环境中...
Dim WshShell
Dim WshProcEnv
Dim system_architecture
Dim process_architecture
Set WshShell = CreateObject("WScript.Shell")
Set WshProcEnv = WshShell.Environment("Process")
process_architecture= WshProcEnv("PROCESSOR_ARCHITECTURE")
If process_architecture = "x86" Then
system_architecture= WshProcEnv("PROCESSOR_ARCHITEW6432")
If system_architecture = "" Then
system_architecture = "x86"
End if
Else
system_architecture = process_architecture
End If
WScript.Echo "Running as a " & process_architecture & " process on a " _
& system_architecture & " system."
如果仅用于 cmd 或 System32 中的某些文件,您可以按照评论的建议使用 sysnative。它甚至会从 32 位可执行文件生成 64 位 System32。只需将 "system32" 替换为 "sysnative" 即可。 (不幸的是,这在 32 位 windows 上不存在,因此您需要检查是否在具有两种体系结构的系统上使用脚本...)
如果您有很多访问权限或使用 com 对象,我发现使用相同的方法重新启动脚本会更容易。以下代码:
If fso.FileExists("C:\Windows\SysWOW64\wscript.exe") Then ' very basic check for 64bit Windows, you can replace it with a more complicated wmi check if you find it not reliable enough
If InStr(1, WScript.FullName, "SysWOW64", vbTextCompare) <> 0 Then ' = case insensitive check
newFullName = Replace(WScript.FullName, "SysWOW64", "Sysnative", 1, -1, vbTextCompare) ' System32 is replaced by Sysnative to deactivate WoW64, cscript or wscript stay the same
newArguments = "" ' in case of command line arguments they are passed on
For Each arg In WScript.Arguments
newArguments = newArguments & arg & " "
Next
wso.Run newFullName & " """ & WScript.ScriptFullName & """ " & newArguments, , False
WScript.Quit '32 Bit Scripting Host is closed
End If
End If
只要用 32 位脚本主机调用它,基本上就会关闭脚本,然后用 64 位脚本主机重新启动它,这样一切都可以在预期的位置找到。