Hatena::ブログ(Diary)

Asarimaの甘い考え

2010-08-25

[]Sql Express Profilerのトレースデータに列を追加する

SqlExpressProfiler(AnjLab Sql Profiler)は、SQL ServerExpress Editionでもイベントトレースができるありがたいプロファイラです。しかし、リソースロックの取得を監視するためのLock:Acquiredイベントトレースするときに、イベント固有の列(Mode, Type, ObjectID2など)を指定できません。なので、指定できるようにSqlExpressProfilerのソースを修正することにしました。

ソース

まず、SqlExpressProfilerのソースコードは以下のURLにあったので、Subversionクライアントで取得しました。私はVisual Studioプラグインとして動作するAnkhSvnを使いました。

http://code.google.com/p/sqlexpressprofiler/

修正

次に、取得した4つのプロジェクト(SqlExpressProfiler, SqlExpressProfiler.Setup, SqlServerTools, SqlServerWebTools)のうち、SqlServerToolsのData\TraceFields.csを以下のように修正しました。

    public enum TraceField
    {
        TextData        = 1,
        BinaryData      = 2,
        DatabaseID      = 3,
        TransactionID   = 4,
        NTUserName      = 6,
        NTDomainName    = 7,
        HostName        = 8,
        ClientProcessID = 9,
        ApplicationName = 10,
        LoginName       = 11,
        SPID            = 12,
        Duration        = 13,
        StartTime       = 14,
        EndTime         = 15,
        Reads           = 16,
        Writes          = 17,
        CPU             = 18,
        ObjectID        = 22,
        ServerName      = 26,
        EventClass      = 27,
        Mode            = 32, //追加
        LoginSID        = 41,
        ProviderName    = 46,
        ObjectID2       = 56, //追加
        Type            = 57  //追加
    }
ビルド

最後に、SqlServerToolsとSqlExpressProfilerをビルドしました。できた実行ファイルをそのまま起動するとMicrosoft.SqlServer.SqlClrProvider.dllが無いと怒られたため、元のSqlExpressProfilerのバイナリからコピーしました。

f:id:Asarima:20100825102340p:image

これでイベント固有の列(Mode, Type, ObjectID2など)が指定できるようになり、データを取得できるようになりました。ただ、問題があって、今回追加した列にフィルタを指定するとランタイム例外が発生して「Wuoa!」と言われてしまいます。そこも何とかしたいです。

2010-07-16

[]コントロール名と英大小が異なる同名のフィールドを宣言してはいけない

IIS 6.0 に配置した ASP.NET 2.0 アプリケーションにて、ページを開くと「あいまいな一致が見つかりました。」というアプリケーションエラーが発生する問題が起きた。例外のスタックトレースには以下の内容が記録されていた。

System.Reflection.AmbiguousMatchException: あいまいな一致が見つかりました。
   場所 System.RuntimeType.GetField(String name, BindingFlags bindingAttr)
   場所 System.Web.UI.Util.GetNonPrivateFieldType(Type classType, String fieldName)
   場所 System.Web.Compilation.BaseTemplateCodeDomTreeGenerator.BuildFieldDeclaration(ControlBuilder builder)
   場所 System.Web.Compilation.BaseTemplateCodeDomTreeGenerator.BuildSourceDataTreeFromBuilder(ControlBuilder builder, Boolean fInTemplate, Boolean topLevelControlInTemplate, PropertyEntry pse)
   場所 System.Web.Compilation.BaseTemplateCodeDomTreeGenerator.BuildSourceDataTreeFromBuilder(ControlBuilder builder, Boolean fInTemplate, Boolean topLevelControlInTemplate, PropertyEntry pse)
   場所 System.Web.Compilation.BaseTemplateCodeDomTreeGenerator.BuildSourceDataTreeFromBuilder(ControlBuilder builder, Boolean fInTemplate, Boolean topLevelControlInTemplate, PropertyEntry pse)
   場所 System.Web.Compilation.TemplateControlCodeDomTreeGenerator.BuildMiscClassMembers()
   場所 System.Web.Compilation.PageCodeDomTreeGenerator.BuildMiscClassMembers()
   場所 System.Web.Compilation.BaseCodeDomTreeGenerator.BuildSourceDataTree()
   場所 System.Web.Compilation.BaseCodeDomTreeGenerator.GetCodeDomTree(CodeDomProvider codeDomProvider, StringResourceBuilder stringResourceBuilder, VirtualPath virtualPath)
   場所 System.Web.Compilation.BaseTemplateBuildProvider.GenerateCode(AssemblyBuilder assemblyBuilder)
   場所 System.Web.Compilation.AssemblyBuilder.AddBuildProvider(BuildProvider buildProvider)

AmbiguousMatchException 例外の説明は「メンバへのバインド時に、バインディング基準に一致するメンバが複数ある場合スローされる例外。」である。さらにスタックトレースの2行目のメソッド名が「GetField」であることから、バインディングされるフィールドのメンバ名が重複していることがわかった。

問題のページにはパーシャルクラスに dataCount フィールド定義し、かつaspxファイルには同名の DataCount というLabelコントロール存在していた。「バインディング基準」について調べることは保留し、とにかく dataCount フィールド名前を _dataCount に変更すると、問題が解決した。

コンパイラによる警告がなかったので、気づかなかった。

2010-01-19

[]1ヶ月以上前に削除したファイルごみ箱から削除する

 Windows を使っていて個人的に困ることは、ごみ箱ファイルをたまに調べることがあるので「ごみ箱を空にする」のができないことだ。ときどき仕方なく手作業で最近の1ヶ月分を残して削除しているのだが、それでも長い間その作業を忘れていたりする。そうするとごみ箱ファイル数が多くなりすぎて、エクスプローラで開くとスクロールもままならないほど動きが遅くなって削除作業が嫌になってしまう。

 こうした悪循環を断ち切るため、自動的にごみ箱ファイルの洗い替え(1ヶ月保存)を行うスクリプトを作成しました。コマンドプロンプト標準出力が使える cscript.exe を自動的に呼び出すバッチプログラムとして起動できるようにしています。使いたい方は、以下のスクリプト拡張子 .bat で保存してください。

@if(0)==(0) ECHO OFF
CScript.exe //NoLogo //E:JScript "%~f0" %*
pause
goto :EOF
@end
var FileSystem = new ActiveXObject("Scripting.FileSystemObject");
var Shell = new ActiveXObject("Shell.Application");
var BucketFolder = getBucketFolder();

var trimDate = getTrimDate();
WScript.echo("ごみ箱から " + trimDate + " 以前のファイルを削除します。");
WScript.echo();

var count = 0;
var size = 0;
for (var e = new Enumerator(BucketFolder.items()); !e.atEnd(); e.moveNext()) {
	var item = e.item();
	if (getDeletedDate(item) < trimDate) {
		count = count + 1;
		size += getSize(item);
		WScript.echo(getName(item));
		deleteItem(item);
	}
}

if (count > 0) {
	WScript.echo();
	WScript.echo(count + " 件 " + formatComma(size) + " KB のファイルを削除しました。");
} else {
	WScript.echo("削除するファイルはありませんでした。");
}

// ごみ箱フォルダ
function getBucketFolder()
{
	var ssfBITBUCKET = 10;
	return Shell.namespace(ssfBITBUCKET);
}

// 削除日付の取得
function getDeletedDate(item) { return BucketFolder.GetDetailsOf(item, 2); }

// サイズの取得
function getSize(item)
{
	var size = BucketFolder.GetDetailsOf(item, 3);
	size = size.substring(0, size.indexOf(" ")); // " KB" を除去
	return parseInt(size.split(",").join("")); // "," を除去
}

// ファイル名の取得
function getName(item) { return BucketFolder.GetDetailsOf(item, 0); }

// ファイル/フォルダを削除
function deleteItem(item)
{
	var path = item.path;
	if (FileSystem.fileExists(path)) {
		FileSystem.deleteFile(path, true);
	} else if (FileSystem.folderExists(path)) {
		FileSystem.deleteFolder(path, true);
	}
}

// 1ヶ月前の日付を YYYY/MM/DD 形式で
function getTrimDate()
{
	var now = new Date();
	var y = now.getYear();
	var m = now.getMonth();
	if (m > 0) {
		m = "" + m;
	} else {
		y--;
		m = "" + 12;
	}
	var d = "" + now.getDate();
	return y
		+ "/" + ("0" + m).substring(m.length - 1, m.length + 1)
		+ "/" + ("0" + d).substring(d.length - 1, d.length + 1);
}

// カンマ編集
function formatComma(value)
{
	value = "" + value;
	for (var i = 0; i < value.length / 3; i++) {
		value = value.replace(/^([+-]?\d+)(\d\d\d)/, "$1,$2");
	}
	return value;
}

2009-03-26

[]Virtual PC コンソールウィンドウが表示されなくなったら

 Virtual PC 2007の「Virtual PC コンソール」ウィンドウデスクトップに表示されなくなった。

 タスクバーには現れているので、そのウィンドウが画面の外に移動した(なぜかは知らないが)と直感した私は、タスクバーの「Virtual PC コンソール」のコンテキストメニューから「移動」を選択した。そうするとマウスカーソルが画面左上の隅に移動したので、ウィンドウは画面左上の枠外にあるものと推測できた。さっそくカーソルの右と下を押しまくってみるが、状況は変わらなかった。

 諦めて検索してみたら、同じ現象を解決したと報告するIIJIMASさんのページを発見した。私の取った回復策と同じだったのでちょっと自信がついて、再度ウィンドウの移動を選択し、カーソルの右と下を押しまくった。

何かの拍子にVirtual PC 2007の「Virtual PC コンソール」ウィンドウが、タスクバーには表示されているのに、見えなくなりました。

クリックしても見えるところには表示されません…再起動してもだめでした…

…でもわりとすぐに解決しました。

「Virtual PC コンソール」のウィンドウが表示されなくなった…(一応解決したが…)

 しばらくすると画面左上にあったマウスカーソルが下がったので、ウィンドウの縦座標が画面の表示エリア内に入ってきたと確信し、カーソル右を押しっぱなしにして十数秒待った。そしてついにウィンドウは画面内に戻ってきた。助かった。

2009-03-20

[]Kodak Color Printをよろしく

f:id:Asarima:20090320235420j:image

先日、iPhoneiPod touch向けの写真プリント注文サービスKodak Color Print」が発表されました。

株式会社アセンディア(代表取締役社長:酒井秀夫、以下「アセンディア」)と日本ジャンボー株式会社代表取締役社長:村松潔、以下「日本ジャンボー」)、加賀ハイテック株式会社代表取締役社長高橋信佐、以下「加賀ハイテック」)の3社は、3月中旬よりiPhoneiPod touchを使用して写真プリント注文を行う「Kodak Color Printサービスを開始致します。

iPhone、iPod touchから直接写真プリントの注文が出来るいつまでもキレイな「Kodak Color Print」写真注文サービスを開始

裏方ではありますが、自分Kodak Color Printの開発に関わりました。自分の作ったものが一般に提供されるのはうれしいですし、一方で責任も感じます。

iPhoneiPod touchをお使いの皆さん、よかったら試してみてください。AppStore(下記URL)より無料ダウンロードいただけます。

http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=307508928&mt=8