WIN1@Codename

Codename

BackgroundWorker の覚書

これまでマルチスレッド処理、非同期処理をVBで実現するには結構面倒な処理が必要でしたが、BackgroundWorker を使用することで簡単に実現できるようになりました。

Windows フォーム コントロールのスレッド セーフな呼び出し方にすこしコツがいるので以下覚書です。

・方法1
BackgroundWorker の ProgressChanged イベント内でコントロールにアクセスする。
DoWork イベント内でアクセスするとエラーになるので、ReportProgress でイベントを発生させてからコントロールにアクセスする。

・方法2
DoWork などから呼び出すプロシージャ自体をスレッドセーフにする。
Delegate Sub TestCallback()
Sub TestWork()
   If Me.InvokeRequired Then
      Dim objTestCallback As New TestCallback(AddressOf TestWork)
      Me.Invoke(objTestCallback, New Object() {})
      Exit Sub
   End If
   Form1.Text = "Test"
End Sub

・方法3
アクセスしようとするコントロールの CheckForIllegalCrossThreadCalls プロパティーを False にする。
Form1.CheckForIllegalCrossThreadCalls = False

BackgroundWorker の意味が分からないとなんのこっちゃですが、
簡単になったというものの、ちょっとばかりコツがいるようなのでその覚書でした。

参考:
http://www.atmarkit.co.jp/fdotnet/vb2005/vb2005_04/vb2005_04_01.html
http://msdn.microsoft.com/ja-jp/library/cc708906.aspx

Hyper-V をプログラムでどうにかしてみる その7 (仮想マシンの作成)

本来であれば、このシリーズ、仮想マシンの作成を一番初めに掲載すべきでしたが、いろいろありましてようやく今ごろになって掲載できるようになりました。

Hyper-Vマネージャーで新規で仮想マシンを作成する場合はウィザードに従って簡単に仮想マシンを作成できますが、これをプログラムで実現するとなるといくつかのステップを踏んでようやく完了となります。

今回はまずは骨組みとなる仮想マシンを最初に作成するところからはじめます。

Dim objConnectionOptions As New ConnectionOptions()
        objConnectionOptions.Impersonation = ImpersonationLevel.Impersonate
        objConnectionOptions.EnablePrivileges = True
        objConnectionOptions.Username = strAccount
        objConnectionOptions.Password = strPassword
Dim objManagementScope As New ManagementScope("\\" + strServer + "\root\virtualization", objConnectionOptions)
        objManagementScope.Connect()

Dim objVirtualSystemGlobalsettingData As New ManagementClass(objManagementScope, New ManagementPath("Msvm_VirtualSystemGlobalsettingData"), Nothing)
Dim objVirtualSystemGlobalsettingDataInstance As ManagementObject = objVirtualSystemGlobalsettingData.CreateInstance
        objVirtualSystemGlobalsettingDataInstance("ElementName") = "TetVM"
        objVirtualSystemGlobalsettingDataInstance("ExternalDataRoot") = "C:\Hyper-V\TestVM"
Dim strSystemsettingData As String = objVirtualSystemGlobalsettingDataInstance.GetText(TextFormat.CimDtd20)

For Each objVirtualSystemManagementService As ManagementObject In New ManagementObjectSearcher(objManagementScope, New ObjectQuery("SELECT * FROM Msvm_VirtualSystemManagementService")).Get
Dim objParams As ManagementBaseObject = objVirtualSystemManagementService.GetMethodParameters("DefineVirtualSystem")
objParams("ResourcesettingData") = Nothing
objParams("Sourcesetting") = Nothing
objParams("SystemsettingData") = strSystemsettingData
Dim objManagementBaseObject As ManagementBaseObject = objVirtualSystemManagementService.InvokeMethod("DefineVirtualSystem", objParams, Nothing)
Console.WriteLine("DefineVM=" & objManagementBaseObject("ReturnValue"))
Next

ここでは「TestVM」という名前の仮想マシンを「C:\Hyper-V\TestVM」フォルダに作成しています。

最後の部分で objManagementBaseObject("ReturnValue")) この戻り値が「0」となれば作成成功です。

次回は作成した仮想マシンにメモリの設定を行います。

Hyper-V をプログラムでどうにかしてみる その6 (差分ディスクの作成)

ちょっと間があきました。
引き続きHyper-Vのプログラム制御を少々。

今回は差分仮想ディスクを作成してみます。

Dim objConnectionOptions As New ConnectionOptions()
        objConnectionOptions.Impersonation = ImpersonationLevel.Impersonate
        objConnectionOptions.EnablePrivileges = True
        objConnectionOptions.Username = strAccount
        objConnectionOptions.Password = strPassword
Dim objManagementScope As New ManagementScope("\\" + strServer + "\root\virtualization", objConnectionOptions)
        objManagementScope.Connect()

For Each objImageManagementService As ManagementObject In New ManagementObjectSearcher(objManagementScope, New ObjectQuery("SELECT * FROM Msvm_ImageManagementService")).Get
Dim objParams As ManagementBaseObject = objImageManagementService.GetMethodParameters("CreateDifferencingVirtualHardDisk")
objParams("ParentPath") = "C:\Hyper-V\Win2008R2Parent.vhd"
objParams("Path") = "C:\Hyper-V\Win2008R2Diff.vhd"
Dim objManagementBaseObject As ManagementBaseObject = objImageManagementService.InvokeMethod("CreateDifferencingVirtualHardDisk", objParams, Nothing)
Next

こんな感じです。

ParentPath で指定するのが差分仮想ディスクの元となるvhdのパスです。
Path で指定するのが、実際に作成される差分仮想ハードディスクのパスです。

WindowFromPoint APIはx64でコンパイルするとバグる?

WindowFromPoin とうAPI関数があります。
これは、マウスカーソル座標の下のウィンドウハンドルを教えてくれる便利なものなのですが、VisualStudioでいつもどおりコードを書いてコンパイルしてみたところ、カーソルが動いているにもかかわらず、自分自身のexeのウィンドウハンドルしか返さない現象が発生。

コードはこんな感じ。

Private
 Declare Function WindowFromPoint Lib "user32" (ByVal xPoint As Integer, ByVal yPoint As Integer) As Integer
Private Declare Function GetCursorPos Lib "user32" (ByRef lpPoint As POINTAPI) As Integer
Private Declare Function GetAncestor Lib "user32" Alias "GetAncestor" (ByVal hWnd As Integer, ByVal gaFlags As Integer) As Integer
Private Structure POINTAPI
    Public x As Integer
    Public y As Integer
End Structure

Sub Test()
    Dim objPOINTAPI As POINTAPI
    Call GetCursorPos(objPOINTAPI)
    Dim intWhd As Integer = WindowFromPoin(objPOINTAPI.x, objPOINTAPI.y)
End Sub


intWhd に目的のウィンドウハンドルが返ってくるはずなのですが・・・。
何度か新規にプロジェクトを作成してコンパイルしてみても結果は変わらず。
以前同様のコードで作成したプロジェクトでは問題なく動いていたので、コードをそのままコピーしてみてもやはりおかしい。

以前作成したプロジェクトを何がちがうのか、あぁ、OSがちがいました。
以前hVistaのx86、今回はWindows7のx64。
なので、VisualStudioはデフォルトの"Any Cpu"でコンパイルされいます。

そういえば、ちょっとまえにこんな記事を自分で書いていました。
http://codename2010.blog11.fc2.com/blog-entry-123.html
と、いうことでターゲットCPUを "x86" にしてコンパイルしてみたらあっさり解決。
ためしにターゲットCPU "x64" でコンパイルしてみると、やはり同じ問題が発生でした。
これは、バグなんでしょうか??

Windows Server 2008 R2 のバックアップは暗号化が使えません

ファイル単位でバックアップできるようになった Windows Server 2008 R2 のバックアップですが、バックアップファイルの保存先が暗号化されているとバックアップを保存できないようです。

イベントログでこんなエラーになってます。
20100605010320

Windows Server 2008 R2 のバックアップって暗号化されてないですよね。
確かパスワードのロックもなかったような気がしますが、どうやってセキュリティー保ちましょうか・・・。

FC2Ad