だるろぐ

明日できることは、今日しない。

Azure Web App+Job+Table Storage :Twitter の位置情報を拾ってマッピングする

f:id:daruyanagi:20170415163622p:plain

以前 WebMatrix+SQL CE で作っていたものを Visual Studio 2017 で編集したら、ランタイムだかライブラリのバージョンの食い違いで起動不能になった&いろいろ試行錯誤したけど Visual Studio 2017 から SQL CE(WebMatrix.Data)がうまく扱えなかったので、データを Azure Table Storage へ保存するように書き換えた。

ぶっちゃけよくわかっていないのだけど、ちゃんと動いているみたいなのでよしとする(ぉ

Twitter の位置情報

f:id:daruyanagi:20170415163522p:plain

Twitter の位置情報は

  • Place:大まかな位置を共有(矩形)
  • Coordinates:経度・緯度を正確に共有(点)

の2つがあるみたい。

面倒な話だが Coordinates はアプリで明示的に・共有する都度[正確な位置情報を共有]オプションを有効にしなければ共有されない(Foursquare/Swarm などのチェックインアプリでは共有されることもあるみたいだが、それはアプリの意図した動作だと思うので問題ない)。今回ほしいのは Coordinates なので、これを定期的に収集することにした。

public static void CollectCheckIns()
{
    // CONNECTION_STRING は Azure Table Storage の接続文字列
    //
    // Web Jobs プロジェクトを作成
    // ・単なるコンソールアプリみたい
    //
    // NuGet で
    // ・CoreTweet:Twitter のライブラリ
    // ・WindowsAzure.Storage
    // なんかをインストールしておく

    try
    {
        var account = CloudStorageAccount.Parse(CONNECTION_STRING);
        var client = account.CreateCloudTableClient();
        var table = client.GetTableReference("checkins");
        table.CreateIfNotExists();

        // めいいっぱいツイートをかき集めてくる
        var tweets = tokens.Statuses
            .UserTimeline(count: 200)
            .Where(_ => _.Coordinates != null);

        foreach (var tweet in tweets)
        {
            var entity = new CheckinEntity(tweet);

            var operation = TableOperation.InsertOrReplace(entity);

            table.Execute(operation);

            Console.WriteLine($"{entity.Url} is collected");
        }
    }
    catch (Exception exception)
    {
        System.Diagnostics.Debug.WriteLine(exception.Message);
    }
}

基本的な流れは簡単だと思った。Table Storage に保存するデータ(モデル?)を TableEntity の派生クラスとして定義し、InsertOrReplace 操作にそのインスタンスをわたし、実行するだけ。

モデルの定義には、引数のないコンストラクター(必須)と、使いやすいように引数を設定したコンストラクターを作り、後者で PartitionKey と RowKey(いずれも string 型、必須)を設定する。この二つのキーでデータを特定・範囲指定・並び替えするみたいだけど、よくわからんかったのでツイートの Id と CreatedAt をキーにしておいた。

public class CheckinEntity : TableEntity
{
    public CheckinEntity() { }

    public CheckinEntity(Status status)
    {
        this.PartitionKey = status.Id.ToString();
        // RowKey にスラッシュは含められない
        this.RowKey = status.CreatedAt.UtcDateTime.ToString("u");

        Id = status.Id;
        Text = status.Text;
        ScreenName = status.User.ScreenName;
        Latitude = status.Coordinates.Latitude;
        Longitude = status.Coordinates.Longitude;
        CreatedAt = status.CreatedAt.UtcDateTime;
    }

    public long Id { get; set; }

    public string Text { get; set; }

    public string ScreenName { get; set; }

    public double Latitude { get; set; }

    public double Longitude { get; set; }

    public DateTime CreatedAt { get; set; }

    public string Url { get { return $"https://twitter.com/{ScreenName}/status/{Id}"; } }
}

ちょっとハマったのは、RowKey にスラッシュを含められないこと。table.Execute() が 400 という HTTP ステータスコードを返して失敗するときは、このあたりを疑ってみるといいのかも。今回はスラッシュを含まず、並び替えにも使える書式 "u" で ToString() しておいた。

成功すると、こんな感じで Table Storage にデータが格納される。

f:id:daruyanagi:20170415165656p:plain

データを読み出す場合は、こんな感じ。

public static IEnumerable<CheckinEntity> Get()
{
    var account = CloudStorageAccount.Parse(CONNECTION_STRING);
        
    var client = account.CreateCloudTableClient();

    var table = client.GetTableReference("checkins");

    var rangeQuery = new TableQuery<CheckinEntity>();
        
    return table.ExecuteQuery(rangeQuery).OrderByDescending(_ => _.CreatedAt);
}

データが多くなってきたら、ちゃんと範囲を絞ってクエリしたほうがいいのかもしれない。

f:id:daruyanagi:20170415170111p:plain

あとはこれを JSON で吐くようにして――

var map_element = document.getElementById("daru_map");
var map;
    
var markerData;

var xhr = new XMLHttpRequest();

xhr.open("get", "/map/checkins", false);
xhr.onload = function(){
    markerData = JSON.parse(this.responseText);
}
xhr.send(null);

function initMap() {
    map = new google.maps.Map(map_element, { center: markerData[0], zoom: 15, });

    for (var i = 0; i < markerData.length; i++) {
        (function () {
            //マーカーの設定と作成
            var marker = new google.maps.Marker({
                position: {
                    lat: markerData[i].lat,
                    lng: markerData[i].lng
                },
                // title: markerData[i].title,
                icon: "/Assets/Marker.png",
                map: map
            });

            //情報ウインドウの設定と作成
            var infoWindow = new google.maps.InfoWindow({
                content: markerData[i].content
            });
                        
            //情報ウインドウのオープンをマーカーのクリックイベントに登録
            marker.addListener('click', function () {
                infoWindow.open(map, marker);
                setTimeout(function () { infoWindow.close(); }, 1000 * 3)
            });
        }());
    }
}

Google マップにプロットしてみた(情報ウィンドウは一つ開いたら一つ閉じるようにしたかったけど、なんかうまくいかんのでタイマーで閉じた)。

f:id:daruyanagi:20170415170311p:plain

テキトーだけど、今回はこのぐらいで。

追伸

Web Job の話をするのを忘れたけど、単に作った Job をアップロードしてスケジューリング実行するだけなので割愛。今は 3 時間おきにデータを収集するようにしている。

Visual Studio 2017 で Windows サービスを作った

f:id:daruyanagi:20170310210104p:plain

まぁ、この程度のことであれば、今までとあんまり変わらんと思うけどね。ちょこちょこ便利になってる感じはある。

今回の目標

実行ファイルが書き換わったら、トーストで通知してほしい。

プロジェクトを作成する

f:id:daruyanagi:20170310210338p:plain

[テンプレート]-[Visual C#]-[Windows クラシック デスクトップ]を開いて、“Windows サービス(.NET Framework)”を選択。すると、Windows サービス プロジェクトのスケルトンがブリブリっと吐かれる。

Service1.cs では味気ないので、今回は MihariService.cs という名前にした。“見張り”やね(以前にもそういう名前のアプリを作って放置してたっけ)。

f:id:daruyanagi:20170310210613p:plain

次に MihariService.cs のデザイナー画面を開き、コンテキストメニューの[インストーラーの追加]コマンドを実行。

f:id:daruyanagi:20170310210915p:plain

すると ServiceInstaller.cs というのが作成されます。このデザイン画面で ServiceInstaller1 を探し、プロパティ画面からいい感じにプロパティを設定。今回はこんな感じにした。

  • ServiceName:MihariService(アプリ ID のノリでどこでも使っていくやで)
  • DisplayName:Mihari サービス(WIndowsの「サービス」からはこれが見えるらしい。日本語にした)
  • Description:システム内で EXE ファイルが変更されるのを監視します
  • StartType:Automatic(これでたぶん自動実行されるはず)

最低限の準備はこれでいいみたい。まだ中身はないけれど、ソリューションをビルドする。

サービスの登録とデバッグ

f:id:daruyanagi:20170310211757p:plain

このままデバッグ実行をしても、エラーが出る。ビルドした Windows サービスをシステムに登録しなきゃいけない。

f:id:daruyanagi:20170310211520p:plain

まず、ツールの類にパスの通ったコマンドプロンプトを起動(よくわかんないけど Developer Command Prompt for VS 2017 というのでいいみたい)。

f:id:daruyanagi:20170310211358p:plain

Debug フォルダーに移動してパスをコピーしておき、コマンドプロンプトで移動。installutil で MihariService.exe をシステムに登録する。

**********************************************************************
** Visual Studio 2017 Developer Command Prompt v15.0.26228.4
** Copyright (c) 2017 Microsoft Corporation
**********************************************************************
> cd (Debug フォルダー)

> installutil MihariService.exe

f:id:daruyanagi:20170310212252p:plain

ログインを求められたら、ユーザー名とパスワードを入力。ユーザー名はコンピュータ名から始まる完全な奴じゃないとダメみたい。

> whoami

で取得したのをコピーして使うといい。

f:id:daruyanagi:20170310212519p:plain

あとは「サービス」に移動して、登録したサービスを開始する。

デバッグ

f:id:daruyanagi:20170310212629p:plain

デバッグを行うには Windows サービスのプロセスにアタッチすればよい。

f:id:daruyanagi:20170310212806p:plain

[すべてのユーザーからのプロセスを表示する]オプションを有効化し、フィルターで Mihari を探すと早い。あとはブレークポイントを仕掛けるなりなんなりご自由に。

リビルドのときは サービスを止める → ビルド → サービスを開始する(→再びアタッチする)みたいな作業フローで。ちょっと面倒くさいけど仕方ない(もしかしたら自動化できるのかもだけど、そこまではいいや)。

ファイルを監視する

f:id:daruyanagi:20170310213029p:plain

めんどくさくなった。MihariService.cs に FileSystemWatcher を追加して、いろいろコードを書けばおっけ。

完成してから気づいたんだけど、サービスから通知トーストを出しても、クリックに反応してくれないんだな(フォルダーを開いたりしてほしい)。単にログだけ出力し、そのログを監視してトーストを出すクライアントを別途作った方がよかった。

rinta.hatenablog.com

iseebi.hatenablog.com

先人たちのおかげですんなり完成しました。

WebMatrix とおさらばして、Visual Studio 2015 で ASP.NET Web Pages をはじめる

f:id:daruyanagi:20170212020533p:plain

長年愛用してきた「WebMatrix」ですが、昨年10月に2017年11月1日 でのサポート終了がアナウンスされました。

Hi everyone

After a long and successful run, Microsoft has decided to end formal support of WebMatrix. Formal support will end on November 1st, 2017. Community support will continue on the WebMatrix forums

Please take a look at Visual Studio Code, our new, free, open source, multi-platform editor! VS Code support git integration, extensions and a whole bunch of other great features!

Thanks!

The WebMatrix team

WebMatrix formal support ends November 1st, 2017 : The Official Microsoft IIS Forums

f:id:daruyanagi:20170212020959p:plain

すでにテンプレートをダウンロードする際に 404 が発生することが多くなったほか、拡張機能のダウンロード提供が終了しており、第一線で使うにはつらい状況になっています。そろそろ乗り換えを検討すべきでしょう。

Microsoft は後継ソフトとして「Visual Studio Code」を推奨していますが、これは統合ターミナルでバリバリとコマンドを打つ感じなので、GUI に甘やかされた僕にはしんどい感じ(最近「Express」を少し触っているのですが、そっちの文化にあわせるなら割と使いやすいですけどねー)。いずれ慣れないといけないなーとは思うんですが、APS.NET Web Pages を使うならば、当面の間は「Visual Studio 2015」が一番楽かなーって感じです。

1. 「Visual Studio 2015」で ASP.NET プロジェクトを作成

f:id:daruyanagi:20170212021454p:plain

まず「Visual Studio 2015」で ASP.NET プロジェクトを作成します。

f:id:daruyanagi:20170212021543p:plain

プロジェクトタイプは“Empty”でよいです。というか、「WebMatrix」でいうところのスターターテンプレートの類は「Visual Studio」に用意されていないので、“Empty”が無難な気がします。

2. プロジェクトに Razor ページを追加

f:id:daruyanagi:20170212021735p:plain

このテンプレートは本当にほぼ空なので、プロジェクトのコンテキストメニューなどから Web ページ(Razor)を追加する必要があります。

f:id:daruyanagi:20170212021905p:plain

“Razor”などのキーワードで探すと簡単。いろいろあるけど、わかんなかった“Web ページ(Razor v3)”でいいと思います。

f:id:daruyanagi:20170212022148p:plain

最初のページを追加すると、ASP.NET Web Pages に必要な参照が勝手に追加されます。すごーい!

3. [F5]キーを押して実行

とりあえずなんか書いて実行してみましょう。

<!DOCTYPE html>
@{ 
    var message = "Hello! World";
}
<html>
    <head>
        <title></title>
    </head>
    <body>
        <p>@message</p>
    </body>
</html>

[F5]キーを押すとサーバー&ブラウザーが立ち上がります。

f:id:daruyanagi:20170212022322p:plain

message を変えてブラウザーをリロードすると、即座に反映されまっする。なんとなく気軽で「WebMatrix」を使い続けてきましたが、機能面では「Visual Studio」のほうがずっと強力(ブレークポイントとかもしかけられるやで。入力補完はちょっと緩いところあるけど)です。……で、「Visual Studio Code」ではこの手順をどうやるんだ? 

最後に「WebMatrix」さん、長いことありがとうございました。

忘れてる人がいるっぽいので言っとくけど、 アップグレード版 Visual Studio Professional 2013 がお安く買えるのは明日までらしいで。わしは忘れかけていた。

f:id:daruyanagi:20140130182153p:plain

Visual Studio Professional 2013アップグレードは、2013 年 11 月 1 日から 2014 年 1 月 31 日まで、または在庫のある限り有効です。特定の市場の Microsoft オンライン ストア内で注文することができます。Visual Studio Professional 2012からVisual Studio Professional 2013へのアップグレードをするお客様に限定されるプランです。

¥12,383! 自分はさっき買えた*1ので、まだ「在庫」はあるのだと思う*2。急げ!

あと、よくわからなかったのだが、「定価 : ¥37,590」って書いてあるのだけど、2月以降も定価でなら買えるのだろうか。それとも「アップグレード版は1月末で終わり! ほんとは ¥37,590 で売るつもりだったけど、¥12,383 にしてあげるんだから許しなさいよねっ!」ってことなんだろうか。自分は日本語が不自由なのでよくわからなかった。ちなみに、素で買う*3¥62,790! チロルチョコが 3139.5 個も買える。こんなに食ったら鼻血止まらへんな。

*1:ダウンロード版

*2:在庫って DVD パッケージのことなのかな

*3:アップグレード版ではなく通常版

Visual Studio 2013 向け VSCommands、Productivity Power Tools などなど

VSCommands for Visual Studio 2013

f:id:daruyanagi:20131122214618p:plain

12.3.0.2(2013/11/20)

大人気拡張機能の Visual Studio 2013 版。

  • CODE BLOCK END TAGGER
  • FILE STRUCTURE
  • SOLUTION BADGES
  • SOLUTION BADGES - TOOLBAR
  • SOLUTION BADTES - START PAGE
  • ATTACH TO IIS
  • MAIN MENU - HIDE
  • MAIN MENU - CHANGE CASE
  • OUTPUT WINDOWS COLORING
  • SYNCHRONIZE SETTING BETWEEN MACHINES
  • ZIP SOLUTION
  • TOUCH SUPPORT

そういえば Visual Studio 2013 のメインメニューって、英語版は大文字なんだよね(2012 もだったかな?)。あれは割りと気に入らないっていう人いそう。

Productivity Power Tools 2013

f:id:daruyanagi:20131122214649p:plain

12.0.21109.0(2013/11/16)

Visual Studio Platform Team 謹製の Visual Studio 拡張機能。いずれ次世代 Visual Studio に搭載されるであろう機能を一足早く試せる(といった立ち位置の拡張機能だったと思う)。

New additions to Productivity Power Tools 2013:

  1. Peek Help
  2. Solution Explorer Errors
  3. Structure Visualizer
  4. Double click to maximize windows
  5. Timestamp margin
  6. Quick tasks – Edit Present On
  7. Ctrl + Click to Peek Definition
  8. HTML Copy improvements
  9. Recently Closed Documents
  10. Match Margin
  11. Power Commands context menu cleanup

ASP.NET and Web Tools 2013.1 for Visual Studio 2012

f:id:daruyanagi:20131122214134p:plain

Visual Studio 2012において、Visual Studio 2013で追加された以下の機能について有効にするもののようです。上リンクはリリースノート。

  • Bootstrapテンプレート
  • ASP.NET MVC 5
  • ASP.NET Web API 2
  • Entity Framework 6
  • ASP.NET Scaffolding
  • Razor Editor / Razor 3
  • NuGet 2.7

インストールは今のところWeb Platform Installerに項目が出てこないので、出てくるまでもう少し待つか、以下のBlogの記事中のDownloadをクリックしてみて下さい。

ASP.NET and Web Tools 2013.1 for Visual Studio 2012 | OPC Diary - No Code, No Life.

Visual Studio 2013 をさっそくインストールしてみたった。

f:id:daruyanagi:20131018004352p:plain

Windows 8.1 をさっそく入れてみた。 - だるろぐ ので、Windows 8.1 と同じく RTM だか GA だかした Visual Studio 2013 もインストールしてみた。VS 2013 の詳細については、すっかりお馴染みとなったソマセガー氏のブログでも読んでけれ。

I’m excited to announce that the final releases of Visual Studio 2013, .NET 4.5.1, and Team Foundation Server 2013 are now available for download! MSDN subscribers can download from the MSDN Subscriber Downloads page.

Visual Studio 2013 is the best tool for developers and teams to build and deliver modern, connected applications on all of Microsoft’s platforms. From Windows Azure and SQL Server to Windows 8.1 and Windows Phone 8, Visual Studio 2013 supports the breadth of Microsoft’s developer platforms.

Visual Studio 2013 available for download - Somasegar's blog - Site Home - MSDN Blogs

ふと気づいたけど、OS と開発環境が同時リリースって今まであったっけ? なかったっけ。

ダウンロードはこちらから。僕は貧乏なので Professional をインストールした。そう遠くないうちに Visual Studio 2012 のユーザーには優待アップグレードパッケージが提供される予定なので、それまでは試用版で過ごすつもり。

続きを読む

プロ生ちゃんのボイスで Visual Studio のビルド通知を行う

というわけで、この度、IT系コミュニティ「プログラミング生放送」のキャラクター、プロ生ちゃんこと暮井 慧(くれい けい)のシステムボイスを無償公開します! PC やスマホの一般的なサウンド設定、そして Visual Studio など開発用ツールのサウンド設定としても使える内容です。

プロ生ちゃんこと暮井 慧(CV 上坂すみれ)のシステムボイス無償公開のお知らせ! | プログラミング生放送

プロ生ちゃん(CV: 上坂すみれ(https://twitter.com/Uesakasumire)さん)のシステムボイスが公開されました! 個人的にちょっと面白いなぁと思ったのは、「Visual Studio」用のサウンドが用意されていること。これを使うと、プロ生ちゃんがビルド通知してくれるようになるっぽい。

使い方

「Visual Studio 2012」*1がインストールされている環境で[サウンド]プロパティ画面の[サウンド]タブを開くと、“プログラム イベント”リストの下の方に Visual Studio のイベントが登録されているはず。

f:id:daruyanagi:20130823225537p:plain

Express エディションでもいいみたい。ここにサウンド(WAVファイル)を割り当てるだけ。うちの環境では

  • ビルドが取り消されました
  • ビルド失敗
  • ビルド正常終了

という3つのイベントが登録されてた。これはエディションによって少し差異があるみたい。たとえば、上位エディションではブレークポイントでもイベントが発生する。

注意

f:id:daruyanagi:20130823225909p:plain

配布されているシステムサウンドは長すぎるのかな? うちの環境ではそのままでは使えなかった。なので“cut”フォルダに収められた短いセリフ(MP3形式)を「foober2000」で WAV 形式に変換して使っています(追記:現在は“cut”フォルダ内のサウンドも WAV 形式になっています)。

あと Visual Studio はシステムサウンドを設定した後に起動しなきゃいけないみたい。起動したままサウンド設定を行ったのだけど、ビルドしても音声が再生されず「なんでや」と思った次第。

最後に

WebMatrix にもプログラム イベントがほしい!

*1:「Visual Studio 2008」まではおそらくないと思う。「Visual Studio 2010」は未検証

Highlight.js を NuGet パッケージにしてみました

WebMatrix で Markdown を少しだけ拡張してみる - だるろぐApp_Code でサブフォルダーを利用する - だるろぐ で扱った Highlight.js を NuGet パッケージにしてみました。

最初は Highlight.js の NuGet パッケージは存在しないと思い込んでいたのですが、ただ検索のやり方が悪かったようで、「Highlight」というパッケージがあったり、似たような機能を実現できそうな「ColorCode」というパッケージもみつけたのですが、見なかったふりをします。 nuget.org はまだちょっと検索機能がイケてないような気がしますね(責任転嫁)。

準備

nuget.org のアカウントを作成

NuGet Gallery | Home でアカウントを作成してください。だいぶ前にやったのでやり方は忘れましたが、難しくはないはずです。

f:id:daruyanagi:20120817024658p:plain

アカウントページで API キーが取得できるので、それをローカル環境に登録します。

nuget.exe setApiKey ********-****-****-****-************
nuget.exe push MyPackage.1.0.nupkg

NuGet.exe を入手(http://nuget.codeplex.com/releases NuGet.exe Command Line)して、1行目を実行すればOKです*1

パッケージに含めるファイルを用意

今回パッケージに含めるファイルは以下のとおりです。

Highlight.js/

    Highlight.js.nuspec <-- あとで作りましょう!

    content/
        ( ~/ 以下に展開されます)
        App_Code/
            Highlight/
                Highlight.cs
                Lisence Files
        Content/
            Highlight/
                Theme Skins
        Scripts/
            Highlight/
               hilight.pack.js
        web.config.transform <-- あとで説明します!

    tools/
        (セットアップなどに利用するスクリプトなどを含めます)

    lib/
        (必要な参照アセンブリを格納しておきます)

今回は tools と lib が空ですけど、それなりに大規模なパッケージを作るときは必要になるのだと思います。ほかにも .NET やら Silverlight やら、ターゲットによってフォルダー構成を変えなきゃダメみたいだけれど、今回はまぁ、いいかな。その代わり、 NuSpec (後述)のタグに「asp.net」と対象ターゲットを書いておくことにします。

web.config.transform の内容はこんな感じです。 App_Code のサブフォルダーに格納した Highlight.cs のコンパイルを有効にするための設定が記述されています。

<?xml version="1.0"?>
<configuration>
    <system.web>
      <compilation debug="false">
         <codeSubDirectories>
           <add directoryName="Highlight"/>
         </codeSubDirectories>
      </compilation>
   </system.web>
</configuration>

.transform という拡張子をつけて content フォルダーに置いておくだけで、勝手にインストール先の Web アプリの web.config とマージしてくれるみたいですね。あらまー、簡単!

NuGet パッケージ(NuPack)の作成

では、 NuGet のパッケージを作成します。手順は NuSpec ファイルに名前やバージョンなどのメタデータを記述して、 NuPack へ Pack(パッケージング)し、 nuget.org へ push (公開)するといった感じ。

NuSpec の作成

f:id:daruyanagi:20120817031210p:plain

nuget.exe spec

で雛形を出力します。内容はこんな感じになっているので、てけとーに編集します。

<?xml version="1.0"?>
<package >
  <metadata>
    <id>Package</id>
    <version>1.0.0</version>
    <authors>Hidetoshi Yanagi</authors>
    <owners>Hidetoshi Yanagi</owners>
    <licenseUrl>http://LICENSE_URL_HERE_OR_DELETE_THIS_LINE</licenseUrl>
    <projectUrl>http://PROJECT_URL_HERE_OR_DELETE_THIS_LINE</projectUrl>
    <iconUrl>http://ICON_URL_HERE_OR_DELETE_THIS_LINE</iconUrl>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>Package description</description>
    <releaseNotes>Summary of changes made in this release of the package.</releaseNotes>
    <copyright>Copyright 2012</copyright>
    <tags>Tag1 Tag2</tags>
    <dependencies>
      <dependency id="SampleDependency" version="1.0" />
    </dependencies>
  </metadata>
</package>

自分の場合はこんな感じになりました(v1.0.4 の場合)。

<?xml version="1.0"?>
<package >
  <metadata>
    <id>Highlight.js</id>
    <version>1.0.4</version>
    <authors>Ivan Sagalaev</authors>
    <owners>daruyanagi</owners>
    <projectUrl>http://softwaremaniacs.org/soft/highlight/en/</projectUrl>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>Syntax Highlighter written by JavaScript and CSS (and C# Helper)</description>
    <releaseNotes>Package for v7.1 release.</releaseNotes>
    <copyright>Copyright 2012 Hidetoshi Yanagi (@daruyanagi)</copyright>
    <tags>webmatrix javascript css syntax asp.net .net40</tags>
  </metadata>
</package>

NuPack の作成

f:id:daruyanagi:20120817031339p:plain

コマンドを実行して、 NuPack を作成します。

nuget.exe pack Highlight.js.nuspec

すると、 nuget.exe のフォルダーに(パッケージ名).(バージョン).nupaack(今回なら Highlight.js.1.0.4.nupack)が作成されます。解凍ソフトでバラして中身を確認してみると面白いかも。

NuPack の公開

コマンドを実行して、 NuPack を公開します。

nuget.exe push Highlight.js.1.0.4.nupack

これで、 nuget.org にパッケージが公開されるはず。

f:id:daruyanagi:20120817031425p:plain

https://nuget.org/packages/Highlight.js

もしよかったら使ってみてくださいね!

パッケージのテスト

アップロードしたパッケージは、パッケージマネージャーでインストール・アンインストールしてちゃんと動くか確かめましょう*2。あと、「WebMatrix 2」で動くからといって「Visual Studio」でもそのまま動くかというとそうでもないみたいです。今回躓いたところを何点か補足しておきます。

パッケージが見つからない……

f:id:daruyanagi:20120817032039p:plain

アップロードしたばかりのパッケージは「WebMatrix 2」の検索で引っかかりにくいです。

f:id:daruyanagi:20120817032125p:plain

そんなときは、フルネームでの検索を試みたり、パッケージのソースを変えてみるといいかもしれません。「Visual Studio」で利用する場合もそうですが、既定の検索結果が「ダウンロード数」順になっているみたいで、新参者はなかなか見つけにくい。「Visual Studio」の場合は、 CUI でインストールしてしまうのが手っ取り早いかもしれませんね。「WebMatrix 2」でも簡単に CUI で NuGet パッケージをインストールできるといいのですけど。

.NET Framework のターゲット

WebMatrix 2」のプロジェクトを「Visual Studio 2012」で開いたのですが、そのままではヘルパー(自作の静的クラス)がうまく動きませんでした。

f:id:daruyanagi:20120817032540p:plain

「パラメーター初期化子を使うな」だの「System.Web.HtmlString なんてないよ!」だの言われるのでちょっと変だなと思っていたのですが、どうも .NET 2.0 でコンパイルしようとしているみたい。

<?xml version="1.0"?>
<configuration>
    <system.web>
      <compilation targetFramework="4.0" debug="false">
         <codeSubDirectories>
           <add directoryName="Highlight"/>
         </codeSubDirectories>
      </compilation>
   </system.web>
</configuration>

web.config.transform を少し書き換えて、 .NET 4 を利用するようにしてみたら(targetFramework="4.0")ちゃんと動きました。ついでに、 NuSpec のタグに「.net 40」を追加して「.NET 4 用ですよ!」とわかるようにしておくと*3いいんじゃないでしょうか。

おわり!

f:id:daruyanagi:20120817034817p:plain

これまでの3つのエントリー

で使ってきたサンプルプロジェクトでも、既存の Highlight.js 関連のコードをバッサリ消して NuGet パッケージに置き換えてみました。入れたり消したり、好き放題だ!

おまけ

f:id:daruyanagi:20120817033216p:plain

「NuGet Package Explorer」ってなんだよ! 最初から知ってたらこっちを使ってたかもしれない(くっそくっそ!

なんかしらんけどプラグインでカスタマったりできるらしいゼ?

ダウンロードは nuget.exe と同じところから。

*1:初回起動時に実行ファイルのアップデートが行われます

*2:ごめんなさい、今までめんどくさくてだいたい動いていればOKかなって思ってました!

*3:周りのパッケージをみていると、そうしているのが多いように思います