サブノート/サブディスプレイに Surface RT を使っていると、デスクトップで見つけた Youtube を Surface で表示したい時が頻繁にあります。この場合、どうやって送るかというと…
- Twitter でメモ的に流してから、Surface 側で拾う
- SkyDrive に URL を置いてから Surface で拾ってくる。
- ちまちまと URL を Surface で打つ
という方法があるわけですが、どれも面倒くさい。ただし、Windows 8 同士であれば、デスクトップアプリでさっくりとできそうなのですが、片方が Windows RT なものだから、Windows ストア アプリしないといけないという制限がある。
で、前々から考えていた、デスクトップPCのほうに簡易HTTPサーバー、タブレットPCにWindows ストア アプリのクライアント、というパターンで実装してみます。
■簡易HTTPサーバー
/// <summary> /// フォームロード時 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Form1_Load(object sender, EventArgs e) { listener = new HttpListener(); listener.Prefixes.Add("http://*:8090/url/"); listener.Start(); // 受信待ちタスク Task tsk = new Task( () => { while (true) { var cont = listener.GetContext(); var req = cont.Request; var res = cont.Response; Debug.WriteLine(string.Format("req {0}", req.RawUrl)); var tw = new StreamWriter(res.OutputStream); tw.Write(_text); tw.Close(); res.Close(); } }); tsk.Start(); } HttpListener listener; private string _text = ""; /// <summary> /// ドロップされた時 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Form1_DragDrop(object sender, DragEventArgs e) { var text = ""; var obj = e.Data; foreach (var fmt in obj.GetFormats()) { Debug.WriteLine( fmt ); if (fmt == "text/uri-list") { var sr = (MemoryStream)obj.GetData("text/uri-list"); text = Encoding.Unicode.GetString(sr.ToArray()); break; } } textBox1.Text = text; _text = text; } private void Form1_DragEnter(object sender, DragEventArgs e) { e.Effect = DragDropEffects.All; }
簡易サーバーは HttpListener で作れば ok です。今回はポート番号を 8090 にして待ちにします。URLはFirefox からドラッグ&ドロップします。何故かIE10の場合はできないのですが…まあ、自分専用なのでFirefoxで。これは後で調査。
■Surface RT 側のクライアント
自動的に取ってくるのがいいのですが、ひとまず、Get ボタンで URL を取得、その後 IE10 で開くという処理を続けてやります。
private async void GetClick(object sender, RoutedEventArgs e) { string url = "http://mars:8090/url"; HttpClient cl = new HttpClient(); var res = await cl.GetAsync(new Uri(url)); var text = await res.Content.ReadAsStringAsync(); text1.Text = text; // 起動 await Windows.System.Launcher.LaunchUriAsync(new Uri(text)); }
■サーバーの設定
実は Winodows 8 では、ポートの制限が厳しくて、単純に HttpListener を作っただけでは動きません。管理者のコマンドラインから、次のコマンドを実行します。
netsh http del urlacl url=http://*:8090/ -user=masuda
Community Open Day 2012 の補足その1 – Moonmile Solutions Blog
Community Open Day 2012 の補足その2 – Moonmile Solutions Blog
に、netsh の使い方が書いてあります。
あとは、ファイアーウォールで、8090 のポートを開けることです。ポート絡みがややこしいので、本格的にツールにするとしたらインストーラが必須ですね。
■で、何につかうのか?
iSteve from Justin Long, Jorge Garcia, James_Urbaniak, Michaela Watkins, Steve Tom, John Ross Bowie, Paul Rust, Ryan Perez, Juzo Yoshida, Brian Huskey, Art Evans, jill_donnelly, Anthony Gioe, Ally Hord, iSteve, Funny Or Die, Charles Ingram, NickCorirossi, Joe Farrell, and Katy Walker を Surface に送ってみたかったんですよ…って、動かしてみたら、ああ、Surface RT の IE10 だと Flash が動かないタイプな模様 orz 、結局デスクトップPCで閲覧
■サンプルソース
サンプルソースはこちら。適当にホスト名とかポート番号とかを変えて使ってください。