解析エンジニアの自動化 blog

コツコツと自動化した方法を残す blog

C# から VBScript を実行する C# ソースコードを自動生成する



こんにちは。
仕事の自動化にやりがいと達成感を感じるガッくんです。



この記事の目次



目的


リンクの記事で既存の VBScript から VBScript ファイルの作成、実行、削除する関数を作成する事に成功しました。
既存の VBScript を関数化する VBScript を作成する - 解析エンジニアの自動化 blog

せっかくなんで既存の VBScript から VBScript ファイルの作成、実行、削除する C#ソースコードを生成する VBScript を作成します。



関数

ソースコード


ForReading = 1   ' OpenTextFile 引数用変数
ForWriting = 2   ' OpenTextFile 引数用変数
ForAppending = 8 ' OpenTextFile 引数用変数
 
'-------------------------------------------------------------------------------------------------------
' 引数が無かった時の処理
If WScript.Arguments.count = 0 then
   WScript.Echo "引数が無いため、実行できません。" & vbNewLine & _
                "ファイルをドロップしてください。"
   WScript.Quit
End If
 
'-------------------------------------------------------------------------------------------------------
' ファイルシステムオブジェクト作成
Set objFileSys = CreateObject("Scripting.FileSystemObject")
 
'-------------------------------------------------------------------------------------------------------
' ドロップされた引数がファイル以外ならアラートして終了する
For each args In WScript.Arguments
  
   '----------------------------------------------------------------------------------------------------
   ' ドロップされた引数がフォルダかファイルかを判定する
   If objFileSys.FolderExists(args) then
      '-------------------------------------------------------------------------------------------------
      ' is folder.
      ' ファイルシステムオブジェクトの破棄
      Set objFileSys = Nothing
      WScript.Echo "フォルダがドロップされました。" & vbNewLine & _
                   "処理を終了します。"
      WScript.Quit
   ElseIf objFileSys.FileExists(args) then
      '-------------------------------------------------------------------------------------------------
      ' is file.
      If Instr(1, args, ".vbs") = 0 Then
         '----------------------------------------------------------------------------------------------
         ' is not VBScript file.
         ' ファイルシステムオブジェクトの破棄
         Set objFileSys = Nothing
         WScript.Echo "VBScript では無いファイルがドロップされました。" & vbNewLine & _
                      "処理を終了します。"
         WScript.Quit
      End If
   Else
      '-------------------------------------------------------------------------------------------------
      ' is unknown.
      ' ファイルシステムオブジェクトの破棄
      Set objFileSys = Nothing
      WScript.Echo "フォルダ 及び ファイル とも認識できないデータがドロップされました。" & vbNewLine & _
                   "処理を終了します。"
      WScript.Quit
   End If
  
Next
 
'-------------------------------------------------------------------------------------------------------
' VBScript ファイルを作成するパスの作成
WrapperVBSDir = SelfPath()
 
'-------------------------------------------------------------------------------------------------------
' ファイルシステムオブジェクト作成
Set objFileSys = CreateObject("Scripting.FileSystemObject")
 
'-------------------------------------------------------------------------------------------------------
' 引数の VBScript ファイルの読み込み
For each args In WScript.Arguments
  
   ' 引数の VBScript ファイルオープン
   Set InputFile = objFileSys.OpenTextFile(args, ForReading, False)
  
   ' ファイル名のみ抽出
   InputFileName = objFileSys.getFileName(args)
  
   ' コード格納用変数
   code = ""
  
   ' 引数の VBScript ファイルを最終行まで読み込む
   Do Until InputFile.AtEndOfStream
     
      ' 1行読み込む
      strLine = InputFile.ReadLine
     
      ' 「\」を「\\」に置換する
      strLine = Replace(strLine, "\", "\\")
 
      ' 「"」を「\"」に置換する
      strLine = Replace(strLine, """", "\""")
     
      ' 読み込んだ文字列を「"」で囲む
      strLine = """" & strLine & """"
      
      ' コード格納用変数が空なら
      If code = "" Then
        
         ' 配列変数の文字列と合わせて代入する
         code = "   string[] arrCode = new string[] {" & """" & "Wrapped" & InputFileName & """" & ", " & strLine
        
      ' コード格納用変数が既に代入済みなら
      Else
        
         ' 「, 」文字列で区切って代入する
         code = code & ", " & strLine
        
      End If
     
   Loop
  
   ' 配列変数の最後の「)」を代入する
   code = code & "};" & vbcrlf & vbcrlf
  
   ' Function コードの追加
   code = "// using System.Diagnostics;" & vbcrlf & "private int Wrapper_" & Left(InputFileName, InstrRev(InputFileName, ".") - 1) & "()" & vbcrlf & "{" & vbcrlf & code
  
   ' パス取得コードの追加
   code = code & "   //自分自身の実行ファイルのパスを取得する" & vbcrlf
   code = code & "   string appPath = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase;" & vbcrlf & vbcrlf
  
   ' VBScript 作成コードの追加
   code = code & "   // VBScript 作成コード" & vbcrlf
   code = code & "   // ストリームライターのオープン(第二引数 => true:追記 false:削除・上書き)" & vbcrlf
   code = code & "   StreamWriter swVBS = new StreamWriter(appPath + arrCode[0], false, Encoding.GetEncoding(""Shift_JIS""));" & vbcrlf
   code = code & "   // コード書き込み" & vbcrlf
   code = code & "   for (int i = 1; i < arrCode.Length; i++)" & vbcrlf
   code = code & "   {" & vbcrlf
   code = code & "      swVBS.WriteLine($""{arrCode[i]}"");" & vbcrlf
   code = code & "   }" & vbcrlf
   code = code & "   // ストリームライターのクローズ" & vbcrlf
   code = code & "   swVBS.Close();" & vbcrlf & vbcrlf
  
   ' 作成した VBScript ファイルの実行コードの追加
   code = code & "   // VBScript の実行" & vbcrlf
   code = code & "   Process proc = new Process();" & vbcrlf
   code = code & "   proc.StartInfo.FileName = arrCode[0];" & vbcrlf
   code = code & "   proc.Start();" & vbcrlf
   code = code & "   proc.WaitForExit();" & vbcrlf
   code = code & "   int ret = proc.ExitCode;" & vbcrlf & vbcrlf
  
   ' 作成した VBScript ファイルの削除コードの追加
   code = code & "   //作成した VBScript を削除する" & vbcrlf
   code = code & "   File.Delete(appPath + arrCode[0]);" & vbcrlf
  
   ' 戻り値を返すコードの追加
   code = code & "   // 戻り値を返す" & vbcrlf
   code = code & "   return ret;" & vbcrlf
  
   ' Function コードの追加
   code = code & "}"
  
   ' 出力ファイルオープン
   Set OutputFile = objFileSys.OpenTextFile(WrapperVBSDir & "\C#Wrapper-" & InputFileName, ForWriting, True)
  
   ' 出力
   OutputFile.WriteLine code
  
   ' 引数の VBScript ファイルクローズ
   InputFile.Close
  
   ' 出力ファイルクローズ
   OutputFile.Close
  
Next
 
'-------------------------------------------------------------------------------------------------------
' ファイルシステムオブジェクトの破棄
Set objFileSys = Nothing
 
 
Function SelfPath()
  
   ' ファイルシステムオブジェクト作成
   Set objFileSys = CreateObject("Scripting.FileSystemObject")
  
   ' 自分のパスの取得
   SelfPath = objFileSys.getParentFolderName(WScript.ScriptFullName)
  
   ' ファイルシステムオブジェクトの破棄
   Set objFileSys = Nothing
  
End Function

使い方

既存の VBScript ファイルをドラッグ&ドロップすると、『C#Wrapper-[ドロップしたファイル名].vbs』という VBScript ファイルを作成します。

ファイルの中身は『Wrapper_ [ドロップしたファイル名]』という関数名の C# コードが記述されています。

この関数を C# にコピペして、関数を使用すればドラッグ&ドロップした VBScript が実行出来ます。

ソースコード
〜ドロップした VBScript


msg = "c:\test\test.txt"
msg = msg & "これは Sample2.vbs です。"
MsgBox msg
WScript.Quit(101) ' 戻り値


ソースコード
〜関数化した VBScript


C#Wrapper-Sample2.vbs
// using System.Diagnostics;
private int Wrapper_Sample2()
{
   string[] arrCode = new string[] {"WrappedSample2.vbs", "msg = \"c:\\test\\test.txt\"", "msg = msg & \"これは Sample2.vbs です。\"", "MsgBox msg", "WScript.Quit(101) ' 戻り値"};
 
   //自分自身の実行ファイルのパスを取得する
   string appPath = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
 
   // VBScript 作成コード
   // ストリームライターのオープン(第二引数 => true:追記 false:削除・上書き)
   StreamWriter swVBS = new StreamWriter(appPath + arrCode[0], false, Encoding.GetEncoding("Shift_JIS"));
   // コード書き込み
   for (int i = 1; i < arrCode.Length; i++)
   {
      swVBS.WriteLine($"{arrCode[i]}");
   }
   // ストリームライターのクローズ
   swVBS.Close();
 
   // VBScript の実行
   Process proc = new Process();
   proc.StartInfo.FileName = arrCode[0];
   proc.Start();
   proc.WaitForExit();
   int ret = proc.ExitCode;
 
   //作成した VBScript を削除する
   File.Delete(appPath + arrCode[0]);
   // 戻り値を返す
   return ret;
}



コメント

VBScriptC# の関数化する事が出来ましたが、引数を必要とする VBScript には対応出来ません。

完全に関数化出来るようにしたいです。

まぁ、 Excel の操作とか引数のいらない簡単な設定の処理を VBScript で書いて C# に組み込めれば良いのかなと思っています。



以上