3

I have been trying to get this script to work all day!

Here are some facts about my situation...

  • I have a program named "ffmpeg.exe" in my "C:\Windows\System32\" folder.
  • I DO NOT have that program in my "C:\Windows\SysWOW64\" folder.

Currently this is the script I have...

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

If I run this script manually at a command prompt then it seems to work just fine. But if I let another app run it (for example in this case uTorrent), it runs the script as expected but when it tries to process the oShell.Run command it runs that in a 32bit environment! Then I get this... does_not_exist

If I try to open up a new command prompt (nothing special) i seems to default to a 64bit environment and then I can type "ffmpeg" and it shows me the help content as expected.

So for some reason I can't get the script to run applications (specifically CMD) in the 64bit environment. Anyone know how I can achieve this?


Update

Seems that my script is in fact being ran in 32bit mode! Even though the script title bar says "C:\Windows\System32\cscript.exe", which is a 64bit environment!!

I used the following script to determine that it was running in a 32bit environment...

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."
Arvo Bowen
  • 4,524
  • 6
  • 51
  • 109
  • Run c:\windows\sysnative\cmd.exe – Harry Johnston Jun 26 '15 at 04:40
  • The `C:\Windows\system32\cmd.exe` is 64 bit command prompt already (32 bit are in `C:\Windows\SysWOW64`). What output if you do change as `sCommand = "%comspec% /k set path"`? And what about `sCommand = "%comspec% /k where ffmpeg"`? Your `administrator` could use another environment variable pool... – JosefZ Jun 26 '15 at 09:57
  • Next should suffice: in the CLI opened by your script and the `'ffmpeg' is not recognized...` error message appears, try `where ffmpeg` and `set path` commands. All under displayed current directory `C:\Users\Administrator\Desktop`. Maybe a calling app destroyed your `path` or `pathext` environment variable(s)... – JosefZ Jun 26 '15 at 10:55

1 Answers1

5

If it is only for cmd or some file in System32 you can use sysnative as suggested by the comment. It will lead to the 64Bit System32 even from 32Bit executables. Just replace "system32" with "sysnative" for every use. (unfortunately this is not present on 32bit windows so you need to check if you use a script on systems with both architectures... )

If you have a lot of accesses or use com objects I found it easier however to just use the same method to restart your script. The following code:

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

Basically closes the script whenever it was called with 32Bit Scripting host and restarts it with the 64Bit one so everything is found where it is expected to be.

Syberdoor
  • 2,521
  • 1
  • 11
  • 14
  • Yea I found that answer somewhere else on SO. ;) But the reason I did not use it was because the script I'm running IS currently running in 64bit. It's just the call to .Run that seems to run in 32bit. Is there a way to make the .Run call choose 64bit instead? – Arvo Bowen Jun 26 '15 at 13:49
  • You were right it seems... I'm going to give this a try because (as I pointed out in my update above) it seems my script is indeed running in 32bit somehow! Thanks! – Arvo Bowen Jun 26 '15 at 14:26
  • Seems that did the trick! I still have no clue why it's running in 32bit or why the title bar does not reflect that but this answer was indeed the correct solution! Thanks! – Arvo Bowen Jun 26 '15 at 15:23
  • 1
    Great it works. The reason why it is running on 32Bit is probably WoW64 the emulation windows uses to "spoof" a 32Bit windows on 64Bit Windows installations. If your uTorrent is a 32Bit Process Windows will show all folders to the program as it is expected on a 32Bit Windows (so basically present SysWoW64 as System32 and the same with registry and program files) this leads to the 32Bit wscript.exe being used for your script and it then again gets the emulated folder presented. It's a compatibility feature (and works well) but it makes debugging and understanding what is really happening hard. – Syberdoor Jun 29 '15 at 06:29
  • Later found out that was exactly the case. ;) Forgot to update the thread here. Thanks again! – Arvo Bowen Jun 29 '15 at 15:31