0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Windows Vista Later VBScript Boot 64 bit Or 32 bit with Cscript or WScript Which you want to VBScriptを64bit 32bitのCscript Wscriptの起動を使い分ける

Last updated at Posted at 2019-02-19

#32Bitに切り替えることが必要な場合

  • BASP21を使用する
  • JScript
  • Jet4.0でCSVに接続

#標準的な配置:System32が標準(64bitOsなら64bit 32 bit Osなら32 Bit)、64 bitの場合SysWowが32bit
Standard Location of Win 64 bit OS Wscript and Cscript is following
Const Wsct6432 ="%systemroot%\sysnative\wscript.exe" 'LCaseを使うため、小文字 '64bit OS なら64bit 32bit OS なら32bit
Const Csct6432 ="%systemroot%\system32\cscript.exe" 'LCaseを使うため、小文字 '64bit OS なら64bit 32bit OS なら32bit
Const Csct6432 ="%systemroot%\sysnative\cscript.exe" 'LCaseを使うため、小文字 '64bit OS なら64bit 32bit OS なら32bit
Const Csct6432 ="%systemroot%\system32\cscript.exe" 'LCaseを使うため、小文字 '64bit OS なら64bit 32bit OS なら32bit
Const WSct32 ="%systemroot%\syswow64\wscript.exe" 'LCaseを使うため、小文字
Const CSct32 ="systemroot%\syswow64\cscript.exe" 'LCaseを使うため、小文字

##この手法の欠点 AMD64が帰らない場合
極稀にAMD64ではない場合があり、その場合はAMD64を書き換える必要がある。
32bitは例外がないので、確実だが、32bitから64bitに切り替えるときが極稀に動かない。

###Sysnative はVista以降

####WOW64でリダイレクトされる特殊フォルダ/パス名

パス リダイレクトの内容
%windir%\System32 Win32アプリケーションからこのパスへアクセスすると、実際には%windir%\SYSWOW64フォルダへリダイレクトされる
このため6432のような表現になる。
%windir%\lastgood %windir%\lastgood\SYSWOW64にリダイレクトされる
%windir%\regedit.exe %windir%\SysWOW64\regedit.exeにリダイレクトされる。regeditは常にSYSWOW64フォルダのものを使うようにするための措置
%windir%\system32\catroot 下記参照
%windir%\system32\catroot2 %windir%\system32\driversstore
%windir%\system32\drivers\etc
%windir%\system32\logfiles
%windir%\system32\spool
これらは%windir%\SYSWOW64ディレクトリにリダイレクトされない。同じファイルを2カ所に作らせないための措置。
注:ただしWindows Server 2008、Windows Vista、Windows Server 2003および Windows XPの64bit版では、%windir%\system32\driversstoreフォルダはリダイレクトされる
%windir%\Sysnative これは仮想的なフォルダ名。 これを利用すると、リダイレクトされずに(リダイレクト機能をパスして)、直接%windir%\system32フォルダへアクセスできる。この仮想的なフォルダはWindows Vista以降で追加された。ただし仮想フォルダなので、64bitのネイティブ・アプリケーションからは利用できない

ということで以下のVBSCriptはVISTA以降が前提

Run Method の確認

.Run(strCommand, [intWindowStyle], [bWaitOnReturn])

  • bWaitOnReturn 省略可能です。スクリプト内の次のステートメントに進まずにプログラムの実行が終了するまでスクリプトを待機させるかどうかを示すブール値です。 bWaitOnReturn に TRUE を指定すると、プログラムの実行が終了するまでスクリプトの実行は中断され、Run メソッドはアプリケーションから返される任意のエラー コードを返します。bWaitOnReturn に FALSE を指定すると、プログラムが開始すると Run メソッドは即座に復帰して自動的に 0 を返します (これをエラー コードとして解釈しないでください)。

    ##注意

    • 以下のコードはConstとグローバル変数より下の最上位に置く必要がある。VBSは上から読んでいるらしく、上で起動しなおしが必要になるため。
    • また、再起動に失敗すると無限に再起動したり、プロセスが残る。
    • このためTaskManagerでCscriptやWscript、Cmdが起動もしていないのに残っていないか確認した方がよい。
    • Wshshell Runで起動するものは1を0にするとウィンドウが非表示になる。しかし、それでもプロセスは残る。

    0.基本

    ということはSyswow64を入れ替えてやると64bitになり、SysWow64だと32bitになる。さらにCscriptかWscriptを書き換えればよい。
    32BitのCscriptに再起動しなおす例
    これに引数がある場合、ない場合を加える

    WSHで64/32bitを区別する。起動する。
    WSHスクリプトを64/32bitが違っていたら起動し直す。

    VBScript
    Wscript.Echo WScript.FullName
    If InStr(LCase(WScript.FullName),"system32") Then 
    If CreateObject("Scripting.FileSystemObject").FileExists(Replace(LCase(WScript.FullName),"system32","syswow64")) Then
      CreateObject("WScript.Shell").Run """" & replace(Replace(LCase(WScript.FullName),"system32","syswow64"),"wscript.exe","cscript.exe") & """ """ & WScript.ScriptFullName & """"
      WScript.Quit
    End If
    End If
    

    ###64Bitの判定に環境変数を使う

    1.Cscript引数なし

    1)絶対64bit Cscript

    VBScript
    'もし、64bit OS Wscript Or 32bit CScipt Wscript で起動されたら、自身を64bit cscript.exeで起動し直す。
    
    IF LCase(CreateObject("WScript.Shell").Environment("Process").Item("PROCESSOR_ARCHITECTURE"))="amd64" Then
       If InStr(LCase(WScript.FullName),"syswow64") OR InStr(LCase(WScript.FullName),"wscript.exe") Then
          CreateObject("WScript.Shell").Run """" &  Replace(Replace(LCase(WScript.FullName),"syswow64","sysnative"),"wscript.exe","cscript.exe") & """ //Nologo """ & WScript.ScriptFullName & """"
          WScript.Quit
       End If
    Else
    '32bit OSの場合はCscriptにする
       If InStr(LCase(WScript.FullName),"wscript.exe") Then
         CreateObject("WScript.Shell").Run """" & Replace(LCase(WScript.FullName),"wscript.exe","cscript.exe") & """ //Nologo """ & WScript.ScriptFullName & """"
         WScript.Quit
       End If
    End If
    

    2)絶対32bit Cscript

    VBScript
    IF LCase(CreateObject("WScript.Shell").Environment("Process").Item("PROCESSOR_ARCHITECTURE"))="amd64" Then
       If InStr(LCase(WScript.FullName),"system32") OR InStr(LCase(WScript.FullName),"wscript.exe") Then
          CreateObject("WScript.Shell").Run """" &  Replace(Replace(LCase(WScript.FullName),"system32","syswow64"),"wscript.exe","cscript.exe") & """ //Nologo """ & WScript.ScriptFullName & """"
          WScript.Quit
       End If
    Else
    '32bit OSの場合はCscriptにする
       If InStr(LCase(WScript.FullName),"wscript.exe") Then
         CreateObject("WScript.Shell").Run """" & Replace(LCase(WScript.FullName),"wscript.exe","cscript.exe") & """ //Nologo """ & WScript.ScriptFullName & """"
         WScript.Quit
       End If
    End If
    

    2.Wscript引数なし

    1)絶対64bit Wscript

    ####Wscriptは基本パターンでないと無限に起動する
    なぜか単純な書き換えではだめです。

    VBScript
    'もし、64bit OS Cscript Or 32bit CScipt Wscript で起動されたら、自身を64bit Wscript.exeで起動し直す。
    'Vista Later Version
    If InStr(LCase(WScript.FullName),"syswow64")  Or InStr(LCase(WScript.FullName),"cscript")Then 
    If CreateObject("Scripting.FileSystemObject").FileExists(Replace(LCase(WScript.FullName),"system32","syswow64")) Then
      CreateObject("WScript.Shell").Run """" & replace(Replace(LCase(WScript.FullName),"syswow64","sysnative"),"cscript.exe","wscript.exe") & """ """ & WScript.ScriptFullName & """"
      WScript.Quit
    End If
    End If
    

    2)絶対32bit Wscript

    VBScript
    'もし、64bit OS Cscript Or Wscript 32bit CScipt  で起動されたら、自身を32bit Wscript.exeで起動し直す。
    If InStr(LCase(WScript.FullName),"system32") OR InStr(LCase(WScript.FullName),"cscript") Then
      If CreateObject("Scripting.FileSystemObject").FileExists(Replace(LCase(WScript.FullName),"system32","syswow64")) Then
      Wscript.Echo """" & Replace(LCase(WScript.FullName),"system32","syswow64") & """ """ & WScript.ScriptFullName & """"
      CreateObject("WScript.Shell").Run """" & Replace(LCase(WScript.FullName),"system32","syswow64") & """ """ & WScript.ScriptFullName & """ //Nologo"
      WScript.Quit
      End If
    End If
    '''実行するプログラム
    WScript.Quit 'これを入れないと無限にループする
    

    ##3.Cscript 引数あり
    http://scripting.cocolog-nifty.com/blog/2007/05/cscriptexe_8312.html
    どうもこれを使わないと危ないようだ
    これについてはSub Prosdureを用いる

    1)絶対64bit Cscript

    下のやつを逆にする。

    2)絶対32bit Cscript

    たとえば

    VBScript
    Wscript Cboot32arg.vbs "nyao","myu"
    

    とすると
    21 nyao,myu
    という文字が入ってくる
    つまり、文字列は引数が1つだけとして分解されずに入る。
    このため、複数の引数はSplitで分解した。Accessの時に似ている。
    しかし、つねにこうだとは言えない
    この辺は引数の入り方に注意しなければならないようだ。
    ファイルを3つほどドラッグアンドドロップするとこんどは3つに分かれており、Ar Splitは必要がなかった。

    VBScript"Cboot32Arg.vbs"
    Option Explicit
    Sub RerunCScript64 'ここから
    Dim Args
    Dim Arg
    Dim i
    If LCase(Right(WScript.FullName,11))="wscript.exe" Or Instr(LCase(Wscript.fullname),"syswow64") Then
      Args=Array("cmd.exe /k CScript.exe",""""&WScript.ScriptFullName&"""")
      For Each Arg In WScript.Arguments
        ReDim Preserve Args(UBound(Args)+1)
        Args(UBound(Args))=""""&Arg&""""
      Next
      WScript.Quit CreateObject("WScript.Shell").Run(Join(Args),1,True)
    End If
    End Sub
    RerunCScript64 'ここまで
    Dim objArgs, oArg , ar, i1
    Set objArgs=Wscript.Arguments
    If objArgs.Count > 0 Then
    for each oArg in objArgs
    Wscript.Echo  21, oArg
    Next
    'ファイルのDrug & Drop では Split は不要 For Each Nextで分解される。
    ar=split(objArgs(0),",")
    Wscript.Echo 23, ar(1)
    End If
    End If
    
    '以下は既存コードのサンプル
    WScript.StdOut.WriteLine WScript.FullName
    WScript.StdOut.WriteLine WScript.ScriptFullName
    WScript.StdOut.WriteLine WScript.Arguments.Count
    Dim k
    For k=1 To WScript.Arguments.Count
      WScript.StdOut.WriteLine WScript.Arguments.Item(k-1)
    Next
    Wscript.Echo 25
    Wscript.Quit
    

    ##4.Wscript 引数あり

    1)絶対64bit Wscript 引数あり

    VBScript
    '64 bit wscriptで再起動する
    'Windows Vista Later
    Dim CommandLine 'As String
    If InStr(LCase(WScript.FullName),"syswow64") OR InStr(LCase(WScript.FullName),"cscript") Then
      CommandLine="""" & Replace(Replace(LCase(WScript.FullName),"syswow64","sysnative"),"cscript","wscript") & """ """ & WScript.ScriptFullName & """"
      For Each Arg In WScript.Arguments
        CommandLine=CommandLine & " """ & Arg & """"
      Next
      CreateObject("WScript.Shell").Run CommandLine
      WScript.Quit
    End If
    

    2)絶対32bit Wscript 引数あり

    VBScript
    Dim CommandLine 'As String
    If InStr(LCase(WScript.FullName),"system32") OR InStr(LCase(WScript.FullName),"cscript") Then If CreateObject("Scripting.FileSystemObject").FileExists(Replace(LCase(WScript.FullName),"system32","syswow64")) Then
      CommandLine="""" & Replace(LCase(WScript.FullName),"system32","syswow64") & """ """ & WScript.ScriptFullName & """"
      For Each Arg In WScript.Arguments
        CommandLine=CommandLine & " """ & Arg & """"
      Next
      CreateObject("WScript.Shell").Run CommandLine
      WScript.Quit
    End If
    

    #参考
    QiitaにおいてHTML要素の属性指定ができなくなりました
    InStr 関数
    HOME VBScript関数リファレンス TOP 文字列操作 InStr 関数

    InStr([lngStart, ] strString, strSearch [, lngCmp])
    ある文字列の中から指定された文字列を検索し、最初に見つかった文字位置を返す文字列処理関数です。
    WScript.exe および CScript.exe のオプション
    コマンド プロンプトからスクリプトを実行する

    VBScript
    CScript //logo c:\"sample scripts"\chart.vbs
    CScript //Nologo c:\"sample scripts"\chart.vbs
    

    #参考文献と補足

    第2回 WSHスクリプト・コーディングの第1歩 (2/2)2004年01月15日 00時00分 公開

    スクリプトの実行方法とコマンドライン・オプション

     冒頭で述べたとおり、スクリプト・ホストにはGUIベースのWScriptとコマンドライン(CUI)ベースのCScriptの2種類が存在する。これらは必要に応じて使い分ければよいのだが、次のような理由から、管理者はCScriptによるコマンドラインでの実行を好むだろう。
    情報の出力時にインタラクティブな確認操作を伴わない(これについては前回詳しく述べた)。
    出力をリダイレクトすることで、スクリプトの実行結果を簡単にログ・ファイルに残すことができる。
    スクリプトに対するパラメータの指定が容易。スクリプトの起動時に、操作対象やオプションなどをパラメータとして指定できる。
    スクリプトの実行を途中でキャンセルするのが容易。コマンド・プロントからスクリプトを実行している場合、途中でスクリプトの実行を停止したければ、Ctrl+Cキーを押すだけでよい(あるいは、スクリプトを実行しているコマンド・ウィンドウを強制的に閉じてもよい)。これに対しWScriptスクリプト・ホストを利用してスクリプトを実行している場合、スクリプトを中断するにはwscript.exeの実行プロセスを強制終了するしか方法がない。
    CScriptでスクリプトを実行するには、コマンド・プロンプトから次のように指定する。

    CScript スクリプト・ファイル名 [オプション] [パラメータ]

    使用しているWindowsが32bitか64bitかを確認する方法
    ##Batファイルで切り替えるタイプ
    ###環境変数を使うもの
    VBSのCScriptを32bit/64bitで呼び分ける

    bat
    @echo off
    if "%PROCESSOR_ARCHITECTURE%" EQU "x86" (
    rem x86環境なので特に気にせずCScript呼び出しでOK 
    \CScript サンプル.vbs 
    )
    if "%PROCESSOR_ARCHITECTURE%" NEQ "x86" (
     rem ここではx86用のCScriptを指定して実行 
     C:\Windows\SysWOW64\CScript.exe サンプル.vbs 
    )
    pause
    

    ###環境変数 Processor Architectureを使わない
    https://www.366service.com/jp/qa/93f06434aa60bc29341e0fca846d0eae

    https://stackoverflow.com/questions/191873/determining-64-bit-vs-32-bit-windows)

    Jon's link is a total hack because it relies upon no new processor architectures being added.
    See: http://support.microsoft.com/kb/556009 for the "official" batch file method.

    上記2つで紹介されているhttp://support.microsoft.com/kb/556009のバッチを使う。現存しないが次のようなものであるらしい。

    BAT
    @echo OFF
    reg Query "HKLM\Hardware\Description\System\CentralProcessor " | find /i "x86" > NUL && set OS=32BIT || set OS=64BIT
    
    if %OS% EQU 32BIT (
    \CScript サンプル.vbs 
    )
    
    if %OS% EQU 64BIT (
    C:\Windows\SysWOW64\CScript.exe サンプル.vbs 
    )
    
    pause
    
0
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?