none
大サイズファイル内容に対してメモリに展開せずにハッシュ値計算(VBA,WSH) RRS feed

  • 質問

  • 大サイズファイル内容に対してメモリに展開せずに演算(ハッシュ値計算、OutOfMemoryException対策)
    http://social.msdn.microsoft.com/Forums/vstudio/ja-JP/1757ca69-59cb-4e25-8f45-cf5413333664/outofmemoryexception?forum=vbgeneralja

    を VBA/WSH で行いたいのですが、ComputeHash_2 の引数に Stream (ADODB.Stream) を指定するとエラーになります。 VBA/WSH ではStream を渡せないのでしょうか。 ComputeHash_2 を ComputeHash, ComputeHash_1 に変えてもエラーになります。 メモリーに展開 a_stream.Read() すれば動くのですが。

    Set hash_computer = CreateObject( "System.Security.Cryptography.MD5CryptoServiceProvider" )
    Set a_stream = CreateObject( "ADODB.Stream" )
    a_stream.Type = 1 '// adTypeBinary
    a_stream.Open
    a_stream.LoadFromFile  "a.zip"
    hash_computer.ComputeHash_2  a_stream

    2014年6月8日 15:06

回答

  • WSH(.vbs) から PowerShell を使う方法で出来ました。
    PowerShell の Set-ExecutionPolicy の設定をしなくて済むように、-command オプションを使いました。

    Set g_sh = WScript.CreateObject( "WScript.Shell" )
    system32_path = g_sh.ExpandEnvironmentStrings( "%windir%\system32" )

    If LCase( Right( WScript.FullName, 11 ) ) = "wscript.exe" Then
      CreateObject("WScript.Shell").Run _
        system32_path+"\cmd /K cscript.exe //nologo """+WScript.ScriptFullName+""""
      WScript.Quit  0
    End If
    '// ここまでが cscript の起動

    path = "C:\DVD.iso"

    command = "Write-Host  ( [System.BitConverter]::ToString( "+_
      "( New-Object System.Security.Cryptography.MD5CryptoServiceProvider )"+_
      ".ComputeHash( "+_
      "( New-Object System.IO.StreamReader( '"+ path +"' ) )"+_
      ".BaseStream ) ).Replace( '-', '' ) )"

    Set ex = g_sh.Exec( "powershell -nologo  -command "+ command )
    ex.StdIn.Close  '// for Windows7 or PowerShell v1.0
    WScript.Echo  ex.StdOut.ReadAll()
    WScript.Echo  ex.StdErr.Readall()
    • 回答としてマーク T's-Neko 2014年6月10日 16:32
    2014年6月10日 16:31

すべての返信

  • エラーの内容は確認されたのでしょうか?

    ADODB.StreamとSystem.IO.Streamとで型が一致しないことを指摘されていると思いますが。

    2014年6月8日 15:50
  • .NET ではありませんので、エラーの内容は、次のようになります。
    プロシージャの呼び出し、または引数が不正です。

    CreateObject に "Stream.IO.Stream"を渡すと次のエラーになります。
    ActiveX コンポーネントはオブジェクトを作成できません。: 'System.IO.StreamReader'

    やはり、VBA/WSHではできないのでしょうか。

    2014年6月8日 17:07
  • 少なくとも、System.Security.Cryptography.MD5CryptoServiceProviderを使う方法は多分無理じゃないですかね。

    PowerShellなら直接.NETのライブラリにアクセスできるので簡単なんですが。

    2014年6月9日 1:47
  • こんにちは。

    ・開発リソース/JScript/スクリプトから.Net Frameworkクラスを利用する(ネタ) - isla-plata.org Wiki
    http://www.isla-plata.org/wiki/pukiwiki.php?%B3%AB%C8%AF%A5%EA%A5%BD%A1%BC%A5%B9%2FJScript%2F%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8%A4%AB%A4%E9.Net%20Framework%A5%AF%A5%E9%A5%B9%A4%F2%CD%F8%CD%D1%A4%B9%A4%EB%A1%CA%A5%CD%A5%BF%A1%CB

    にもあるようにFileStreamは扱うことができないので、例として挙げられているページと同じ方法は使えないのではないかと思います。
    PowerShellを使うか、FCIV(巨大ファイルを扱えるか試したことはありませんが・・・)等の外部ツールを使ってみてはいかがでしょうか。
    2014年6月9日 3:50
  • WSH(.vbs) から PowerShell を使う方法で出来ました。
    PowerShell の Set-ExecutionPolicy の設定をしなくて済むように、-command オプションを使いました。

    Set g_sh = WScript.CreateObject( "WScript.Shell" )
    system32_path = g_sh.ExpandEnvironmentStrings( "%windir%\system32" )

    If LCase( Right( WScript.FullName, 11 ) ) = "wscript.exe" Then
      CreateObject("WScript.Shell").Run _
        system32_path+"\cmd /K cscript.exe //nologo """+WScript.ScriptFullName+""""
      WScript.Quit  0
    End If
    '// ここまでが cscript の起動

    path = "C:\DVD.iso"

    command = "Write-Host  ( [System.BitConverter]::ToString( "+_
      "( New-Object System.Security.Cryptography.MD5CryptoServiceProvider )"+_
      ".ComputeHash( "+_
      "( New-Object System.IO.StreamReader( '"+ path +"' ) )"+_
      ".BaseStream ) ).Replace( '-', '' ) )"

    Set ex = g_sh.Exec( "powershell -nologo  -command "+ command )
    ex.StdIn.Close  '// for Windows7 or PowerShell v1.0
    WScript.Echo  ex.StdOut.ReadAll()
    WScript.Echo  ex.StdErr.Readall()
    • 回答としてマーク T's-Neko 2014年6月10日 16:32
    2014年6月10日 16:31
  • 子プロセスを起動するならPowerShellにこだわらなくても、C#なりVBなり任意の言語で記述すればいいのでは?
    2014年6月10日 23:17