2012年5月30日水曜日

ASP.NET IIS で cron 的なジョブ処理を実行する

IISではcronのような機能はない。なので、代わりの方法についてご紹介します。

<検討案>
以下の手法が考えられる。今回推奨するのは、③。
1.普通にコンソールアプリケーションを作成し、タスクスケジューラーで実行
一番無難だが、Webサイト内の(App_Codeの)Entityやクラスなどは使えない。
プリコンパイルして参照を通すか、Webアプリケーションにしてしまうなどの対応があるが、特に前者の場合同期を取るのが面倒。

2.キャッシュの有効期限とコールバック関数を使用する
こちらで紹介されている手法。よく考えたな・・・と感嘆せずにはいられない。

ASP.NETでWindowsサービスのような機能を実装する方法

ただ、記事に書いてる通りちょっと危なっかしい。キャッシュクリアによるJOBの中断と、マルチスレッドによる複数回実行の危険性を考慮しておく必要がある。

3.Webサービスを作成して、VBScript/JScript Windows Power Shell からキックする
今回推奨案。直接サイト内に作成できるためApp_Codeのクラスが使用できるのと、起動自体はVBScript/JScriptから行うため、JOB実行はタスクスケジューラーで監視できる。

※Windows Power Shellを使用するとMSSOAP無しに実行できることが判明したので、推奨方法をこちらに切替(2012/6/21)


<推奨案:Webサービスを作成して、WindowsPowerShellからキックする方法>

以下のようなコードでサイトのWebサービスをキックできるので、これをタスクスケジューラーから実行すればよい。

<JOB用Windows Power Shellコードサンプル>
$web = New-WebServiceProxy -uri http://xxxx/yyyyy/サービス名.asmx?wsdl
$exe =  $web.サービスメソッド("引数",・・・)

参考 Windows PowerShell を使用して株価をすばやく確認する方法はありますか


<JOB用VBSコードサンプル(一応掲載)>
'Soap Toolkit 3.0を使用する場合"MSSOAP.SoapClient30"にする
Set SC = CreateObject("MSSOAP.SoapClient")

SC.ClientProperty("ServerHTTPRequest") = True
SC.MSSoapInit("http://xxxx/yyyyy/サービス名.asmx?wsdl")

'EndPointURLを指定しないとタイムアウトのエラーになることがある
SC.ConnectorProperty("EndPointURL") = "http://xxxx/yyyyy/サービス名.asmx"

SC.サービスメソッド(引数・・・)

Set SC = Nothing


※1 イントラネットから外部にアクセスする場合などで、プロキシを超える必要があるときはこれではNGになるので注意(色々なサイトで言われているConnectorPropertyによるプロキシ設定は、サービスにアクセスする前のプロキシに対して無力)。MSSOAP.HttpConnectorを使用してガチで書く必要がある。以下サイトをご参照ください。

Microsoft SOAP Toolkitを使ってJScriptでSOAP - 低レベルAPI (1) SoapConnector, SoapReader

上記サイトの補足となるが、呼び出すメソッドに引数を渡す場合は以下のようにしてやる。
soapSerializer.startElement("引数名",サービス名称空間,"","SOAPSDK1")
   soapSerializer.writeString("値")
  soapSerializer.endElement()

※2 MSSOAP.SoapClientはWindows7には入っていない?と思われる(Windows7 64bitでコードが動かないことを確認)。そのため、以下サイトからSOAP ToolKitをダウンロードする必要がある(コードを"MSSOAP.SoapClient30"にするのを忘れずに)。

Soap Toolkit 3.0

なお、64bitの場合vbsを作成するとデフォルト64bitで動作するため、32bitのdllであるこのツールを読み込むことができなくてエラーになる。
これを回避するには、32bit用のwscript/cscriptで実行をしてやる必要がある。場所は以下。

  C:\Windows\SysWOW64\wscript.exe / cscript.exe

ファイルのプロパティにあるプログラムの指定で32bitのほうを設定してやればよい。。。のだが、wscriptの方は何度指定してやっても64bitのほうになってしまうので(プログラム名が同名のため?)、32bit cscriptの方を指定してやるとうまくいく(実行できることに差はない)。

※3 windows7にこのtoolkitが入っていないのは、「これからは.NET Frameworkの方を使用してくれ」というお達しが出ているためである。そのため本ツールキットも開発が中止されているが、どうやらVB6が死に絶えるまでは大丈夫な模様。

開発ツール ライフサイクル Q&A

.NET FrameworkでのSOAPClientは事前にWeb参照を登録することが前提の開発のようで、VBScriptなどのスクリプト系言語にはかなりなじまずちょっと・・・という感じである(VBScriptから.NET Frameworkを使うこと自体は可能)

Hey.Scripting Guys

コンストラクタに引数あるときどうするの?という気もするが、渡せるのだろうか。


なお、本方式はWebサービスにアクセスする形態なので、当然サイトが生きていないとNGである点、またコネクションタイムアウトの時間を調整する必要がある点は要注意。
しかし、App_Codeとの連携と開発にVisual Studioが使えるメリットは大きいはず。



2012年5月24日木曜日

ASP.NET サイト/アプリを 無償クラウド AppHarbor にて公開する

.NETで作ったアプリを公開したい!という場合、公式クラウドAzureに無償枠はないため、作ったアプリはいつかお金を払わなければ捨て去る以外にありません。
もっと自由にアプリを作りたいが金はない、という場合.NETのPaaSであるAppHarborの使用をお勧めします。

AppHarborは.NETアプリケーション用のクラウド環境で、無料から使用できSQLServerなどのDBもつかえます。また、Azureのように「Azure専用」にアプリケーションを作成する必要がなく、いつもどおり作ったアプリケーションを配置することが出来ます(Azureをxxしているわけでは、ない)。

<AppHarborの使用手順>
1.Windows用Gitのインストール
以下サイトを参考にインストールを行います。
Set Up Git

途中で”コマンドプロンプト(cmd)からも使えるようにするか”と聞いてきますので、これはYesにしておいたほうが便利です。

2.Webサイト/Webアプリケーションを作る
いつもどおりWebサイトやWebアプリケーションを作ります。
※Webアプリケーションでないと駄目だという情報が幾つかありましたが、少なくともASP.NETの通常のWebサイト(MVCでない)はデプロイ可能でした。

3.ローカルリポジトリを作成する
コマンドプロンプトでWebサイト/Webアプリケーションのフォルダに移動し、
git init
を実行します。

~いろいろファイルを編集~

4.変更内容をローカルにコミットする
以下コマンドで、変更をローカルにコミットします。
git add .
git commit -m "my first commit"

※このあたりの詳細は、Gitの使い方を参照してください。

5.ローカルのコミットをAppHarborに反映する
AppHarborでは、事前にアカウントをつくりアプリケーションを作っておきます。
アカウントを作った後のトップ画面で、Create new application の箇所にアプリケーション名を入れてCreateボタンを押せばOKです。名前は2で作成したものと同名にしておいたほうが懸命と思われます。

AppHarborでアプリケーションが作られると、以下のようなメニューが表示されると思います。
一番下にある「REPOSITORY URL」をクリックすると作成したアプリケーションのリポジトリがクリップボードにコピーされます。その内容を、

 git remote add appharbor xxxx

のxxxxの部分と置き換えてコマンドを実行してください。



現時点でのイメージは以下のようになっています。
AppHarbor上にリポジトリをつくり、そのremote宛先をaddで登録したところです。

 宛先の登録が終わったら、以下コマンドで発行を行います。

git push appharbor master


このコマンド後コンパイルが走り、しばらくするとWebサイトが発行されます。先ほどのメニューのHostnamesというところから、作成されたWebサイトのアドレスが参照できます。

発行後ファイルに変更を加えた場合は、手順4からの作業(登録除く)の繰り返しになります。
Gitのコマンド的には以下の通りです。
~ファイル変更~

git add .
git commit -m "my second commit"
git push appharbor master

※commit時のメッセージ内容は自由です。


※その他※
・PreCompileについて
AppHarbor上でプリコンパイルがデフォルトオンになっているせいか、App_Codeのフォルダがサイトに含まれているとエラーになります。
これを回避する場合、SettingsにあるBuildの箇所で、プリコンパイルをオフにしてください。

・SqlServer/EntityDataFrameworkの使用について
アドオンを追加することで可能になります(20MまでフリーのDBあり)。
接続文字列はConfiguration Variableを使用するか、SqlServerの詳細画面から確認可能です。


Entity Frameworkを使用する場合は、Entity Framework metadata:のところにEntityDataFrameworkを使用するとweb.configに勝手に挿入されるconnectionStringの"res:~.msl"の部分を設定するとEntityFramework用の接続文字列を作成してくれるので、それをweb.configに設定すればきちんと動きます(自動で変換してくれるといううわさも聞いたが、そんなことはなかった)。

動作は.NetFramework4.0/EntityDataFramework4.0で確認しました。


・Git Hubについて
せっかくGitを使っているので、Git Hubに登録するのはアリだと思います。Git Hubはソースコードを共有するためのサービスで、Rubyなどのプロジェクトではかなり良く使われています。
Git HubからAppHarborにつなぐことも出来るようなので、これを機会に試してみても良いと思います。



GIMP 2.8

GIMPが、3年半ぶりにメジャーバージョンアップ!

シングルウィンドウモードへの対応はうれしいですね ^^

http://www.gimp.org/release-notes/gimp-2.8.html


2012年5月8日火曜日

NUnit で ASP.NET WebForm のサイトをテストする

前回の記事でまとめた内容を、プロジェクトテンプレートとして使えるようにしました。

前回:ASP.NET WebFormでNUnitによるUnitTest環境を構築する

プロジェクトテンプレート ※Visual Studio拡張機能からもインストール可能

NUnitWebForm


苦労したのは、自動的にNUnitを起動する箇所と、対象サイトをコンパイルするバッチ。
カレントフォルダの取得に相当苦しめられたが何とかこれでいけると思う。

コンパイルオプション以外でもちゃんとマクロを使えるようにしてほしい今日この頃。

Windows バッチファイルでカレントディレクトリを取得する

ようやく取得できた・・・ので、方法を記載しておきます。

@echo off
setlocal
REM バッチファイル実行パス取得(カレントディレクトリの場合、%CD%に変更)
SET STR="%~dp0"
if %STR%=="" exit

REM パス中の空白を#に変換
SET STR_NO_BLANK=%STR: =#%
REM パス区切り文字(\)を空白に変換
SET STR_TOKENS=%STR_NO_BLANK:\= %

REM 空白パスのためにつけていた二重引用符を削除(しないとforがうまくいかない)
for %%i in (%STR_TOKENS:"=%) do (
  SET TOKEN=%%i
)

REM 最終フォルダ=カレントディレクトリを取得(#にしていた空白を再変換)
echo %TOKEN:#= %

endlocal


※2012/05/14追記
jak-sanよりコメントを頂き、上記内容を修正すると共にもっと簡単な方法を追記します。

@echo off
setlocal

set x=%~dp0
REM パス末尾の\を除去し終端ディレクトリをファイル名のようにする(C:\hoge\ -> C:\hoge)
set x=%x:~0,-1%

REM ファイル名部分を取得する~nで末端ディレクトリを取得する
for /F "delims=" %%a in ('echo "%x%"') do echo %%~na

endlocal

え?~nとかってどういう意味?という場合下記のサイトを参考にしてみてください(jak-sanさんのサイトでなくてすみません・・・なかなか見つからなかったもので・・・)。

2012年5月3日木曜日

Visual Studio 2010 express に SQLite を統合する

すばらしく時間がかかったがようやく設定が終わったため、メモ。おそらくこんなに苦労したのはx64環境だからで、x32なら普通にできる可能性大。

1.SQLite ADO.NET Providerのダウンロード/インストール
最近のリリースにはなぜかProviderが入っていないので、昔のバージョン(1.0.66)をまずダウンロードする(公式サイトのリンクが切れているのでsource forgeから落とす)。
ver 1.0.66

2.最新版のSystem.Data.SQLiteのダウンロード/インストール
x32(x86)とx64両方落とす必要がある点に注意する(パソコンがx32ならx64はいらないかもしれない)。ダウンロードはこちらから。Setup for xxx となっているものを、それぞれダウンロードする。

※ダウンロードするのはbundleとついているほう。System.Data.SQLiteにはネイティブのコードが含まれており、ネイティブ分をマージした版(bundle)か切り出した版(Interop.dllに分かれている?)か選ぶことができる。
VisualStudioから使う際、分割版はどうもうまくいかないのでbundleで行う。

インストール時、スタートアップにメニューを追加するかどうかの後に、インストール後の作業として global assembly へ追加するかどうかなどのチェックボックスを入れる画面になる。ここで、x86のインストール時は全てチェックを入れておき、x64のときは初期提案のままとした。
これに意味があるかはわからないが、Visual Studio 2010 Expressがそもそもx86で稼動しているので、x86側の設定を優先するようにした。


3.最新版dllの移行
後は引越し作業が待っている。Providerをインストールしたフォルダ(C:\Program Files (x86)\SQLite.NET)のbinを、最新版のx86 System.Data.SQLiteのbinで上書きする。そして、bin/x64のフォルダを同じく最新版のx64 System.Data.SQLiteのbinで上書きする。
※念のためbinフォルダのバックアップを取っておくことを推奨。

これで作業は完了。Visual Studioを起動すればサーバーエクスプローラーからSQLiteを追加できるようになっているはず。
ただ、データソースの追加としたときにConnectionStringの設定画面しか出てこないような場合は設定がおかしい。ここから先は色々試したので何が正解かわからないが、とりあえず以下を試せば何とかなると思われる。

 3.1 デザイナのリフレッシュ?
 C:\Program Files (x86)\SQLite.NET\bin\Designer内のSQLite.Designer.dllをx86側の最新版に置き換え、install.exeを実行する。
途中System.Data.SQLite.dllの場所を何度も聞かれるが、恐らく永久に聞いてくるので一回入力したらキャンセルする。


 3.2 machine.configのDbProviderFactoriesセクションへの接続文字列の追加
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Configにあるmachine.configにSqliteの接続文字列を追加する(test.exe.configの設定をコピーすればよい)。x64の場合、64bit版.NET Frameworkの側にも設定を追加しないといけない点に注意。


3.2 /resetskippkgs オプションでVisual Studioを起動する
 パッケージのキャッシュが残ることがあるらしいので、これでリフレッシュ。

逆に、machine.configへのDataProviderFactoryの追加・C:\Windows\assemblyへの追加を試みる、といったことは意味がなかった。そして、1.0.66のインストールだけではうまく動かないことも確認済み。やはり最新版をインストールして対応させる必要がある。


これでうまくいく・・・と思う。


なお、これはあくまでSQLiteを.NETから使えるようにしただけなので、実際にテーブルを作ったりデータを入れたりという操作は別途行う必要がある。
サーバーエクスプローラーが使えればそこからでも可能だが、他のツールとしてはSQLiteAdminが有名なようだ。


4.プロジェクトでの使用
System.Data.SQLite/System.Data.SQLite.Linqをコピーしてきて参照設定をし、使う。
コピーしてくるのが面倒、という場合はまずインストールフォルダへ参照設定を行い、その後参照設定のプロパティでローカルコピーをTrueにする。
参照は64bitと32bitどちらなの?というのはPCの環境に合わせるのが吉か。少なくとも、NUnitで動かす際はPC環境とあったdllに参照を通していないと例外が発生した(x86.exeの方で動かせば動くかもしれないが)。
エンティティデータモデルでもきちんと使うことが可能。


参考サイト

SQLite on Visual Studio 2010 Setup Instructions

2012年4月24日火曜日

Windows Developer Days サマリ

Windows Developer Dayに参加してきたので、その内容をまとめます。
※1日目+2日目で、新しいメトロアプリの内容を中心にマージしました

○Topics
Windows8 Release Preview が6月第1週に公開される。


○Windows8の特徴
Windows7で培った基盤の上に、メトロスタイルと呼ばれるデザインを実装したというイメージ。
Windows8では、これまでのアプリも、新しいメトロスタイルのアプリも両方動く。
メトロアプリはWinRT(Windows Runtime)という.NET Frameworkとは異なるアーキテクチャで動く。
メトロスタイルには細かいガイドラインがあり、このためデザインがしやすくなっている。
クラウドとの統合が行われ、例えばマイピクチャとSkyDriveの画像は区別がない。


○メトロアプリについて
Windows8から新登場した、いわゆるタブレットアプリ。

1..実行環境
Windows Runtime(WinRT)という新しい実行環境で動く。
WinRTはネイティブの実装であるため、C++では直接コールできる。VB.NET/C#ではCLR、JavaScriptではChacra(IEのJavaScriptエンジン)を通じてアクセスが可能だが、この動作は裏で各ランタイムのAPIとWinRTのAPIをマッピングするWindowsメタデータと呼ばれる機構が働いていることによる(言語プロジェクション)。

2..開発言語・コーディング
上述のとおり、各種言語で開発可能。
VB.NET/C# + XAMLが素直だが、C++を使うこともできるしJavaScript+HTML5でも可能。パフォーマンスの差異は特にないとのこと。

メトロアプリは基本的に非同期で動くため、データ抽出など完了を待ってから処理を行いたい場合は新シンタックスである await をつける必要がある。

非同期処理を行うメソッドはasyncで宣言を行う。返り値はvoidかTaskのみだが、Taskはジェネリクスで型が指定できるため、実質制限はあまりない。なお、await処理が可能なのは返り値がTaskのメソッドのみ(これは、返り値を待つという風に考えれば当然か)。

3.動作プロセス
メトロアプリの状態は、起動中->サスペンド->破棄という流れで遷移する。
起動中からサスペンドに移るのは他アプリの背後に隠れたときであり、サスペンドから破棄されるのはメモリなどのリソースが枯渇した時となる。
サスペンド->破棄の際イベント検知はできないため、サスペンドになった際必要なデータは保存しておく必要がある。

制約として、起動は5秒以内、サスペンド状態でのデータ保管も5秒以内に行う必要がある(この時間はデバイスの性能に依存するため、実際は2秒程度が好ましい)。

動作はサンドボックスで行われるため、OSアクセスには制限有り。また他アプリとの通信はクリップボードに似たコンテキストと呼ばれる仕組みで行う。

4.配布形態
Windowsストアから配布、となる。インストーラーは作成できず、パッケージ内に格納したマニュフェストファイルに基づきOSが自動でインストールする。
マニュフェストファイルにはアプリがアクセスするリソース(カメラ・GPSなど)が宣言されており、ここで宣言されていないリソースはアプリで使用できない(インストールする際の目安にもなる)。

購入はユーザー単位であり、同じ端末でもユーザーが異なれば共有はできない。ただ、一度購入したアプリはクラウド経由で他端末と共有が可能(ローミング)。ただ、5台までなので注意。


○メトロスタイルについて
細かいガイドラインがあるため、詳細はそちら参照 Metroスタイルの設計原則
1.起動前
アイコンは2種類用意する。縮小表示された際の1:1正方形サイズのものと、通常表示の1:2長方形サイズのもの。
起動していなくても裏側で通信が可能なため、例えばメールなら1:2表示の際、アイコン以外に新着メッセージを問い合わせその件数を表示するといったことが可能(ライブタイル)。

2.表示時
通常起動時・スナップ(画面の端に表示)・ポートレイト(タブレットの縦置き)の主に3種類の表示スタイルがあり、それぞれに対応しておく必要がある。

表示コンセプトとしては、ダッシュボードのように必要な情報を1画面でまとめるようなスタイルが良い(と言っているように思う)。
検索してコンテンツにたどり着くというよりは、コンテンツをまず前に出す。検索はチャームかアプリバーに移し、画面から外す。
※チャーム:右から出るメニューバーで、コンテキストメニュー的なもの。アプリバーは下から出るメニューバーで、アプリケーション固有のメニューをまとめられる。

レイアウトは方眼紙を意識し、そこに配置するようなイメージで行う。
ボタンは(押せるのが)7mmがだいたい下限のため、それ以上でデザインする。また、hoverのようなアクションを返すことが望ましい。

3.動作時
スクロールは1方向に統一し、1アプリ内で縦と横のスクロールが混在することを避ける。
アクションに意味を持たせる。スクロールなら左に概要・右に行くにつれ詳細、ズームなら縮小した場合カテゴリ別表示、拡大した場合詳細表示にするなど(セマンティックズーム)。


○ストアについて
開発者登録料は個人49$企業99$、売上は25000$を越えるまで70%、以降80%が手取りとなる。アプリの価格は開発者が1.49~999.99$の間で決定可。

アプリの配布に当たっては試用版配布がサポートされており、期間限定はデフォルト、機能制限はコード内で試用か否かが判定できる。

ストアのエミュレータを使用することでアプリ購入をシミュレート可能だが(=試用版/購入版の動作確認が可能)、本番とクラス名?が異なるためアップ前には書き換える必要あり。
広告はAdvertising SDK により数行で追加可、収益確認及び広告設定はpubCenterより可

審査はプロセスが公開されており、いま審査のどの段階か、どこで止められたかなどが確認できる。


○その他トピック
WebSocket、SqlServer2012について。
WebSocketは、要するにまだ実装しない方がいいと感じた。Windows8でないとNGなのだが(IIS8・.NET Framework4.5も必要)Azureでまだ提供されておらず、またAzureではWebsocketを行う場合定期的にpingをうつ必要があり結局Long Porling方式と変わらないため。

SqlServer2012はFileTableというフォルダ構造をまとめて格納したようなデータを持てるようになったらしい。GUIが伴えば、スケール可能なファイルサーバーとして使えるかもしれない。
SqlServerToolという便利なツールも提供され、Azure/SqlServer/ローカルDBが簡単に複製・同期できるようになっている。Azure開発はこれでかなり楽になりそう(その前に無償枠がないと使う気が・・・という気もするが)


内容に誤りなどあったらご指摘願いますm( _ _ )m。