Windowsストアアプリでの配置ターゲットとしては次の3つがあります。
- ローカルコンピューター
- シミュレーター
- リモートコンピューター
最初の2つはなじみがあると思いますが、最後の1つはあまり使う機会もないかもしれません。
しかし、Windows RT機のテストやデスクトップで開発していて手元の色々なタッチデバイスでテストしたい時などにはリモートコンピューターを配置先としてデバッグ実行を行う「リモートデバッグ」がとても便利です。
リモートデバッグの準備
前提条件
-
リモート デバイスと Visual Studio のコンピューターがネットワークに接続、またはイーサネット ケーブルを通じて直接接続する必要があります。 インターネットにデバッグはサポートされていません。
-
リモート デバイスのリモート デバッガーをインストールする管理者である必要があります。 リモート デバッガーと通信するには、リモート デバイスへのユーザー アクセスできる必要があります。
ダウンロードとインストール
リモートデバッグを行うには、リモート側(つまりVisual Studioを実行していない側)に「Remote Tools for Visual Studio 2012」をインストールする必要があります。
Remote Toolsには、x64用、x86用、ARM用があるので、例えばSurface RT上でリモートデバッグしたいときは「Remote Tools for Visual Studio 2012 (ARM)」をインストールします。
Remote Tools for Visual Studio 2012はVisual Studio 2012のダウンロードサイトから入手できます。
http://www.microsoft.com/visualstudio/jpn/downloads
構成
インストールが終わったら構成が必要なのですが、ローカルとリモートで同じMicrosoftアカウントでログイン(管理者権限をつけておきます)しておき、それを同じサブネットのLAN内で接続してるならば特に難しい設定も不要です。
詳しい設定は「http://msdn.microsoft.com/ja-jp/library/vstudio/hh441469.aspx」を参照してください。
リモートデバッグの実行
- リモート側でRemote Debuggerを起動します。
- ローカル側で配置先を「リモートコンピューター」にしてデバッグ実行します。
- 初回のみリモートデバッガー接続ダイアログがでてくるのでリモート側のPCを選択します。
- 自動的にリモート側にアプリが転送されて、Visual Studioとアプリが接続されてリモートデバッグ実行が開始されます。
リモートデバッグでもブレークポイントや変数の値の確認/変更などができます。
今回、リモートデバッグだけで発生した事象
次のようなコードを作成して、ローカルコンピューター、シミュレーター、リモートコンピューターをそれぞれ配置先にして実行してみました。
コンパス機能を取得するクラス
Imports System.ComponentModel
Imports System.Runtime.CompilerServices
Imports Windows.Devices.Sensors
Public Class CompassModel
Implements INotifyPropertyChanged
Private WithEvents CompassWatcher As Compass
Private _MagneticHeading As Double
Public Property MagneticHeading As Double
Get
Return -Me._MagneticHeading
End Get
Set(value As Double)
Me._MagneticHeading = value
Call NotifyPropertyChanged()
End Set
End Property
Public ReadOnly Property IsSupported As Boolean
Get
Return True
End Get
End Property
Public Sub StartWatch()
Try
If Me.CompassWatcher Is Nothing Then
Me.CompassWatcher = Compass.GetDefault
Me.CompassWatcher.ReportInterval = 50
End If
Catch ex As Exception
End Try
End Sub
Private Sub CompassWatcher_ReadingChanged(sender As Compass,
e As CompassReadingChangedEventArgs) _
Handles CompassWatcher.ReadingChanged
Me.MagneticHeading = e.Reading.HeadingMagneticNorth
End Sub
Public Sub StopWatch()
Try
If Me.CompassWatcher IsNot Nothing Then
Me.CompassWatcher = Nothing
End If
Catch ex As Exception
End Try
End Sub
Public Event PropertyChanged(sender As Object,
e As PropertyChangedEventArgs) _
Implements INotifyPropertyChanged.PropertyChanged
Protected Sub NotifyPropertyChanged(<CallerMemberName> Optional propertyName As String = Nothing)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub
End Class
コンパスクラスとXAMLクラスを接続するクラス
Imports System.ComponentModel
Imports System.Runtime.CompilerServices
Imports Windows.Media.Capture
Public Class MainViewModel
Implements INotifyPropertyChanged
Private WithEvents VmCompassModel As New CompassModel
Public ReadOnly Property MagneticHeading As Double
Get
Return Me.VmCompassModel.MagneticHeading
End Get
End Property
Public Async Function Start() As System.Threading.Tasks.Task
Me.VmCompassModel.StartWatch()
End Function
Public Sub [Stop]()
Me.VmCompassModel.StopWatch()
End Sub
Public Event PropertyChanged(sender As Object,
e As PropertyChangedEventArgs) _
Implements INotifyPropertyChanged.PropertyChanged
Private Sub VmCompassModel_PropertyChanged(sender As Object,
e As ComponentModel.PropertyChangedEventArgs) _
Handles VmCompassModel.PropertyChanged
RaiseEvent PropertyChanged(Me,
New PropertyChangedEventArgs(e.PropertyName))
End Sub
End Class
発生事象
リモートコンピューターを使っている時だけこのコードを実行時に次のようなエラーが発生します。
内容としては
型 'System.Runtime.InteropServices.COMException' の例外が System.dll で発生しましたが、ユーザー コード内ではハンドルされませんでした
追加情報: アプリケーションは、別のスレッドにマーシャリングされたインターフェイスを呼び出しました。 (HRESULT からの例外: 0x8001010E (RPC_E_WRONG_THREAD))
ということです。
もちろん、コンパス付の実機でローカル実行してもエラーになりません。ちょっと不思議な現象ですね。