ザキンコのブログ

ザキンコの日記のはてなブログ版です。

Windows10 でVHDXファイルのマウントが何らかの原因で外れる

Windowsでのディスクの仮想化はVHDXファイルを作ればできるのだが、これを外付けUSBハードディスクに入れておくとUSBのちょっとした不調(負荷がかかってリセットされてしばらくして再認識やスリープしてしまう等)があるとVHDXのマウントが外れてしまって不便。
あと、VHDXへのアクセスがないと外れてしまう気もするので、安定稼働させようすると何かしら一定期間で書き込み続ける必要も気がする。
なので、簡単なRubyスクリプトを書いた。

diskpartで自動再マウント。タスクスケジューラーに設定しておけば使える。
(2017.9.28 追記)
UTF-8だとdiskpartが非ASCIIなパスを認識しないのでCP932(SJIS)で。
auto_mount.rb

# coding: CP932

# diskpartを呼び出すので、要管理者権限
# 一度マウントしてマウントポイントを設定済みであること

require 'tempfile'

# 監視するディスク、フォルダとそのvhdxへのパス
# [['U:/', 'C:\var\test.vhd']] #後ろはWindowsパスを使う
target_aa = [['U:/', 'C:\mnt\test.vhdx']]

# マウントが外れてる?
target_aa.each do |target_a|
  unless FileTest.directory?(target_a[0])
    puts "#{target_a[0]} - Disconnected."
    # txt作成
    arg_txt = <<"EOS"
select vdisk file="#{target_a[1]}"
attach vdisk
EOS
    #puts arg_txt

    tf = Tempfile.new(['auto_mount', '.txt'])
	#p tf
	
    begin
	  tf.write arg_txt
	  tf.close
	  
	  # Windowsパスへ変換
	  winpath = tf.path.gsub(/\//, '\\')
	  
	  # diskpart呼び出し
	  p system('diskpart -s "' + winpath + '"')
    ensure
      tf.unlink # 一時ファイルを削除
    end

  else
    puts "#{target_a[0]} - Connected."
  end
  
end

exit

一定間隔でファイルを書き込み続ける。実行して最小化しておく。
loop_writefile.rb

# coding: UTF-8

require 'date'

# ファイル名
logfilename = 'datetime.log'

# 間隔(s)
sleeptime = 30

# チェックするディレクトリリスト
a = ['U:/']

# ファイル書き込み
loop do
  # 時間を取得
  t = DateTime.now
  puts t
  
  a.each do |p|
    begin
      File.open(p + logfilename, 'w') do |f|
        f.write(t.to_s)
        f.fsync
      end  

      File.open(p + logfilename, 'r') do |f|
        if f.read != t.to_s
          puts 'Read Error! - ' + p + logfilename
        end
      end

    rescue Exception => e
      # フォルダが開けなかった場合のエラー処理
      # エラーを表示して無視して次へ
      p e
    end
  end

  puts 'Completed!'
  sleep sleeptime
end

exit