[WinRT] デスクトップで閲覧しているURLをSurface RTに送る

サブノート/サブディスプレイに Surface RT を使っていると、デスクトップで見つけた Youtube を Surface で表示したい時が頻繁にあります。この場合、どうやって送るかというと…

  1. Twitter でメモ的に流してから、Surface 側で拾う
  2. SkyDrive に URL を置いてから Surface で拾ってくる。
  3. ちまちまと URL を Surface で打つ

という方法があるわけですが、どれも面倒くさい。ただし、Windows 8 同士であれば、デスクトップアプリでさっくりとできそうなのですが、片方が Windows RT なものだから、Windows ストア アプリしないといけないという制限がある。

image

で、前々から考えていた、デスクトップ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 側のクライアント

image

自動的に取ってくるのがいいのですが、ひとまず、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で閲覧

■サンプルソース

サンプルソースはこちら。適当にホスト名とかポート番号とかを変えて使ってください。

カテゴリー: WinRT パーマリンク