So-net無料ブログ作成

XNA:DirectXのアニメーションその3 [.net]

さてさて、前回の猿ロボですが、どうやらアニメーションの座標の変換がうまくいってないんでしょうね、コレ・・・



これでは解り辛いのでシンプルなモデルをLightWave3Dで作成し、DirectXに変換。
こんなの。

回転しつつ移動しつつみたいなの。
オブジェクト(メッシュ)は順番に親子関係になってます。

さて、こいつをXNAで動かすと・・・
むぅ?


なんじゃこりゃ。
案の定、崩れてますね・・・
これでは猿ロボも動かんわな。

しかもなぜかオブジェクトの色がXNAでは出てきませんね。
DirectXViewerを見るとわかりますが赤がホントの色です。
XNAではなぜかテクスチャーだけという・・・
この辺も調べなければな。


さてさて「SkinningSample」のソースコードをしばしにらめっこ。
しかし、たいして処理は無いな・・・
むぅ・・・

しかし動きをよく見るとオブジェクト親子間の相対位置が反映されていないような。
全て原点基準で動いてるんじゃないですかね?これ。


ソースコードを変更しましょ。

FuelCarrierクラスの変更です。
ところで前回、ワールド座標の計算を追加したのですが、どうやらanimationPlayer.Updateの第3パラメータにワールド座標を渡せばよいみたいです。

前回まではUpdate内で呼んでましたが、ワールド座標はDrawで算出してるのでその中に移動しました。

で、問題の親子関係の相対位置ですが、meshのParentを次々追っていってトップの親Transformから順番に演算するメソッドを作りました。
メソッド名がいい加減なのは気にしない・・・

        static Matrix GetParentTransform(ModelBone parentBone)
        {
            List<Matrix> parentTransforms = new List<Matrix>();
            ModelBone parent = parentBone;
           
            while (parent != null)
            {
                parentTransforms.Add(parent.Transform);
                parent = parent.Parent;
            }
            Matrix ret = Matrix.Identity;
            for (int i = parentTransforms.Count - 1; i >= 0; i--)
            {
                ret = ret * parentTransforms[i];
            }

            return ret;
        }

続いでDrawメソッドの修正です。

            animationPlayer.Update(gameTime.ElapsedGameTime,
                true, worldMatrix);
            Matrix[] bones = animationPlayer.GetSkinTransforms();
            Matrix[] meshBones = new Matrix[bones.Length];

            foreach (ModelMesh mesh in Model.Meshes)
            {
                bones.CopyTo(meshBones,0);
                if (mesh.ParentBone != null)
                {
                    for (int i = 0; i < bones.Length; i++)
                    {
                        meshBones[i] = GetParentTransform(mesh.ParentBone)
                                            * bones[i];
                    }
                }
                foreach (Effect effect in mesh.Effects)
                {
                     ~~以下略~~

データの構造がよく解らないのでこれでいいのかどうかアレですが、ループに無駄がありそうですね・・・
mesh毎に毎回計算する必要はあるんでしょうか?
しかしこのbones、シーン毎の変換座標なんでしょうが具体的に何がはいっているのかよく解らなかったです・・・


おお、なんかそれっぽい動きになったぞ!!!
ちと移動距離が大き目な気がするが気のせいか?

よし、これで猿ロボも・・・!

・・・
・・・
前回と変わりなく・・・
なんで?


さて困ったな。
オブジェクトは親子関係になってるみたいだし、DirectXViewerでは見れるんだから問題ないと思うのだが・・・
親子の相対位置でもないとすると・・・
てかそもそも何も変化ないのはもっと致命的なミスか?

今日はここまで・・・
(半歩前進・・・)

あとコンテンツプロセッサでスケールを変えた時の対応もしないと・・・
移動する座標とかもスケール数倍にしないといけないのでは?


nice!(0)  コメント(1) 

XNA:DirectXのアニメーションその2 [.net]

さてさて、前回はXNAで自前で用意した.xファイルからアニメーションさせることができましたが、フレームが超高速で何が何やら。

で、修正しようと調べると原因がわかりました。
どうやらLightWave3DからDirectXにエクスポートする時に時間の設定をしなければならないようで。
xna3d07.png
Time Scale Factorで何倍の時間をかけて再生するか指定するみたいです。
600にしてみました。

で、DirectX Viewerで再生したのがコレ。

ずいぶんスローになりました。

よし、これでゲームに取り込めば・・・
ちなみにこのモデルはコンテンツプロセッサのスケールを変えるとオブジェクトの位置がずれてしまうので倍率は1.0のままでカメラの位置を少し下げました。


おやぁ?

動きは遅くなりました。
成功です。
ぱちぱち。

しかし・・・
なんか描画されない部分があるな?
今度は何だ?

う~ん?
なんか手前に来た部分が描画されないみたいですかね?
足の裏とか。

今日はここまで。
nice!(1)  コメント(0) 

XNA:DirectXのアニメーションに挑戦 [.net]

先日も使ったXNAチュートリアルの「FuelCell」。
前回はXBox360以外のコントローラーを使えるようにしましたが、今回は自前で用意した3Dモデルをゲームに使いたいと思います。

ところで3Dモデリングは色々なアプリケーションがありますが、私は結局LightWave3D(LW3D)を使うことにするです。
ま、ネットで検索してもLW3Dを使ってるやつってもうほとんど見かけないけどな。
私が持ってるのはこれなのでしかたない。

ModToolは使い方がわからんなりよ・・・


=======================
まずLightWave3Dで簡単なモデルを作ります。
それをLayoutの新規シーンに追加。
DirectXのプラグインで.xファイルに出力。
DirectX8のText形式にしました。
ファイル名:Car1.x
Modelerから出力してもいいんですがね、後でアニメーションもやるのでLayoutから。

「FuelCell」のプロジェクトでContents\Modelsの下にCar1.xを。
コンテンツロードのモデル名を変更。
fuelCarrier.LoadContent(Content, "Models/Car1");

で、実行。
xna3d01.png
おお、出てきた。
箱に車輪を4個付けただけ。

よし、いよいよ以前から気になっていたアニメーションの表示に挑戦。

ここでいうアニメーションとは、何ていいますかね、ゲームのキャラクター単独の動きみたいな。
たとえばRPGで自キャラクターが走ったりする手足を振る動作とか。
それを3Dモデリングツールから動き付きでDirectXファイルに吐き出して、ゲームでは只それを使うだけ。

なので走っている動作はプログラムで動かしているわけではなくて、あらかじめそういう動きのデータを取り込んで使っているだけということ。
解りますかね?

ま、私も3Dゲーム作りは全くの素人で、ただ今勉強中なわけですが・・・


さて、LW3Dではシーンなんぞいうものを作ってDirectXに吐き出せばよいのですが、ゼロからシーンを作るのもめんどくさいので今回はあらかじめLW3Dにインストールされているサンプルを使います。
xna3d06.png
\LightWave_8\Scenes\Robots\ApeBot\ApeRun13.lws
猿ロボットのサンプルシーンです。
13フレームですね。(後でこのフレーム数が大失敗だったという・・・)

これをそのままDirectXファイルに吐き出して「FuelCell」のプログラムに先ほどと同様に組み込み。
コンテンツプロセッサのスケールを0.5くらいに調整。
xna3d02.png
お、出てきたぞ。
いいじゃん、LW3D使えるじゃん。
まだアニメーションの動きはありません。
アニメーションはどうやら自分でプログラムを書かなければいけないようです。
XNAではそこまでやってくれないのかと不満に思いましたが、どうやらDirectXだけでもバージョンによりフォーマットが違ったり、使う3Dモデリングツールによって吐き出す内容も違ったりという問題があるみたいです。
3Dモデリングツールは各自好きなものを使ってということなので、実装も自分の使うものに合わせてカスタマイズが必要になるってことでしょうかね。

まだアニメーションの無い止まっているだけのキャラです。
フィールド上の移動はできますが。

が・・・!
動かすとモデルが崩れる・・・!?
xna3d03.png
むぅ?
なんじゃこりゃ。

しかし何度も見てみるとどうやら座標の変換の順番に問題がありそう。
3Dモデルは回転とか移動とかの座標を変換する順番を考えてやらないとモデルが明後日の方向にすっ飛んで行きます。

これは「FuelCel」のコードに問題がありましたね。
誤)
effect.World = worldMatrix * transforms[mesh.ParentBone.Index];

正)
effect.World = transforms[mesh.ParentBone.Index] * worldMatrix;

「FuelCell」では元々1つのメッシュのモデルしか使ってませんが、コードは複数のメッシュを想定しています。
が、どうやらこいつの場合はメッシュの親子関係とワールド座標の変換が逆の方がよいようで。
それともサンプルコードが最初から間違ってるのかな?
(素人の私には判断できんわいな。)

とにかく何とか正常にモデルが表示されました。
xna3d04.png
床の升目を見ればわかりますが、先ほどと違って方向を変えても各部が正しい位置にあります。

===========================
いよいよアニメーションに挑戦だ!

調べてみるとXNAのサンプルに「SkinningSample」というのがあります。
私は3.1で作ってるので「SkinningSample_3.1.zip」をダウンロードしました。

その中の以下の2つのプロジェクトを自分のゲームのソリューション(FuelCell)に追加します。
SkinnedModelPipeline
SkinnedModelWindows

ゲームのFuelCellプロジェクトの参照にSkinnedModelWindowsを追加します。
また、FuelCell内のContentプロジェクトには参照にSkinnedModelPipelineを追加します。
一旦ソリューションのリビルド。

Content\Modelsの先ほどの猿ロボットのプロパティを開き、コンテンツプロセッサにSkinnedModelPipelineを指定します。

ここからはプログラムの修正です。
FuelCarrierクラスの中を書き換えていきます。
LoadContentメソッドの中にアニメーションの情報を読み込む部分を追加します。
サンプルコードを参照しましょ。

Model = content.Load<Model>(modelName);
// =================================
//  カスタム スキニング情報
SkinningData skinningData = Model.Tag as SkinningData;
if (skinningData == null)
    throw new InvalidOperationException("This model does not contain a SkinningData tag.");
// アニメーション プレイヤーを作成し、アニメーション クリップの
// デコードを開始します。
animationPlayer = new AnimationPlayer(skinningData);
AnimationClip clip = skinningData.AnimationClips["AnimationSet_ApeRun13"];
animationPlayer.StartClip(clip);
// ================================


AnimationClipの"AnimationSet_ApeRun13"という名前は猿ロボの.xファイルをテキストエディタで開いて調べたもの。
AnimationSetの名前です。



Updateメソッドの最後でアニメーションのUpdateを呼びます。
恐らく次のフレームの情報に座標を変換するんでしょうね?

animationPlayer.Update(gameTime.ElapsedGameTime, true, Matrix.Identity);


DrawメソッドではMeshのEffectを設定する部分を書き換えます。
また、サンプルはカメラが移動するだけだったのでワールド座標でのキャラクタ移動の計算を最初に追加してます。

Matrix[] bones = animationPlayer.GetSkinTransforms();
for (int i = 0; i < bones.Length; i++)
{
    bones[i] = bones[i] * worldMatrix;
}

foreach (ModelMesh mesh in Model.Meshes)
{
    foreach (Effect effect in mesh.Effects)
    {
        effect.Parameters["Bones"].SetValue(bones);

        effect.Parameters["View"].SetValue(view);
        effect.Parameters["Projection"].SetValue(projection);
    }
    mesh.Draw();
}



これで完成。
が、実はここまで来るのにかなり苦労したんですがね・・・


実行しようとするとコンテンツパイプラインでエラーが発生します。
Input skeleton not found.

猿ロボにはボーンが入ってませんが、どうやらこのXNAのサンプルでは1つはボーンが入ってないとだめっぽいです。
というか、ボーンを使ったアニメーションが前提なんでしょう・・・

LW3Dでボーンを1個追加して、DirextXに吐き出し。
そして実行。
xna3d05.png
おやぁ?
何ねコレ?

どうやら猿ロボの顎の部分だけみたいです。
そういうことか!?
オブジェクト1つに1個のボーンが必要なのか!?

ということでまたまたLW3D上で全てのオブジェクトにボーンを追加していく。
ピボットには要らないみたいですが。


で、何とかできたものがコレ。



アニメーションが動いた!!!
が・・・!

は、早い・・・
キャプチャーもまともに取れてねぇ・・・

そういうことか。
この猿ロボは13フレームしかありません。
通常は1秒間に60フレームくらいですか?

なのでかなり高速で走ってますね・・・

ま、とにかくこれで後はフレームスピードの調整さえできれば自分で作った3Dモデルがゲームに組み込めるということだな。

おお、何かだいぶ本格的になってきた気がするぞ。
俺にもゲームが作れるな!

気のせいとか無理とか言うな。


nice!(0)  コメント(0) 

XNA:XBox360以外のコントローラーを使ってみる [.net]

さてさて、XNAではXBox360用のコントローラーしか使えません。
Windows用ゲームでも。

しかし何とか他のコントローラーが使えないものかやってみました。

以前、XNAのチュートリアルで「FuelCell」なる3Dゲームを作ったのでこれを利用します。
http://msdn.microsoft.com/ja-jp/library/dd254702(v=XNAGameStudio.31).aspx
これからXNAを始める人はココのチュートリアルもお勧めですね。

xnahid01.png
こんなゲームです。


さてさて、何から探せばよいのか半日ほどネットを彷徨って疲れましたが・・・
ここでとっかかりを発見。
http://www10.atwiki.jp/taziro/pages/52.html

ほうほう。
SlimDXかXBOX360 Controller Emulatorを使えばできるとのこと。
しかしXBOX360 Controller Emulatorの方はコントローラーをエミュレートして渡すものっぽいので、XNAで作られたゲームなら何にでも対応できそうですが、プログラムの方でやってみたいのでSlimDXを使ってみました。

ところがこのSlimDX、.NET Framework上でDirectXのゲームを作るためのライブラリとフレームワークらしく、コレを使うのであればXNAがいらないんですね・・・

しかしせっかくXNAの勉強をしているので今回はSlimDXのDirectInputを使ってXBox360以外のコントローラーでFuelCellが動くようにしたいと思います。


===============================
SlimDXのサイトからDeveloperSDKをダウンロードしてインストールします。
http://slimdx.mdxinfo.com/download.php

参照の追加で.NETライブラリにSlimDXのver.2とver.4が出てくると思います。
たぶんver.4はVS2010(.NET Framework4.0)用だと勝手に思いますが、XNAは今のところFramework2.0用なのでVer.2でしょうね。

早速サンプルソースを解凍してみましょ。
「SlimDX Samples (June 2010)」というフォルダができるはずです。

サンプルのソリューションを開くとDirectInput\Joystickというプロジェクトがあります。
ところでSlimDXの参照エラーになりますが、これは一旦削除してSlimDXのVer.2を指定すればよいです。
VS2008のXNAでは。

実行してみるとコントローラーのボタン等の状態が確認できます。
一番最初のデバイスに接続するようですが、自分のPCに何個付いてるか調べてインデックスで直接指定すれば目的のコントローラーにアクセスできるかと。
void CreateDevice()内のdinput.GetDevicesのところです。

xnahid03.png
こんな感じ。

このサンプルを参考に、自分のPCに付いてるデバイスを調べるプログラムを作ってみました。
xnahid02.png
ほうほう、なるほど。

Inter Linkという名前が多いですが、どれがどれやら・・・
とりあえずコントローラーのInterLinkはRealFlightG3のUSBプロポでした。

私は「Virtual RC USB」コントローラーを使います。
RCカー用のホイーラー型プロポです。

=================================
ここから「FuelCell」プロジェクトの改造です。

参照設定でSlimDXとSystem.Windows.Formsを追加。
Formsは後でWindowハンドラが必要になるので。

まず、SlimDXのコントローラー用オブジェクトをFuelCellGameクラスに追加。
クラス内先頭のキーボードとかコントローラーとか色んなオブジェクトを定義しているあたり。

SlimDX.DirectInput.Joystick currentJoystick;
SlimDX.DirectInput.JoystickState currentJoystickstate = new SlimDX.DirectInput.JoystickState();

FuelCellGameクラスのコンストラクタ内で目的のコントローラを取得して初期化。
私は「Virtual RC USB」という名前で引きましたが、本来はGUIDとかなんでしょうね・・・

// Joystick
SlimDX.DirectInput.DirectInput dinput
    = new SlimDX.DirectInput.DirectInput();
foreach (SlimDX.DirectInput.DeviceInstance device in
    dinput.GetDevices(SlimDX.DirectInput.DeviceClass.GameController,
    SlimDX.DirectInput.DeviceEnumerationFlags.AttachedOnly))
{
    // create the device
    try
    {
        if (device.ProductName != "Virtual RC USB") continue;
        currentJoystick = new SlimDX.DirectInput.Joystick(dinput,
            device.InstanceGuid);
        currentJoystick.SetCooperativeLevel(this.Window.Handle,
            SlimDX.DirectInput.CooperativeLevel.Exclusive |
            SlimDX.DirectInput.CooperativeLevel.Foreground);
        break;
    }
    catch (SlimDX.DirectInput.DirectInputException)
    {
    }
}
if (currentJoystick == null)
{
    return;
}
foreach (SlimDX.DirectInput.DeviceObjectInstance deviceObject in
    currentJoystick.GetObjects())
{
    if ((deviceObject.ObjectType & SlimDX.DirectInput.ObjectDeviceType.Axis)
        != 0)
        currentJoystick.GetObjectPropertiesById(
            (int)deviceObject.ObjectType).SetRange(-1000, 1000);
}
// acquire the device
currentJoystick.Acquire();

FuelCellGameクラスのUpdateメソッド内でコントローラーのステータスを取得する部分を追加。

if (currentJoystick.Acquire().IsFailure) return;
if (currentJoystick.Poll().IsFailure) return;
currentJoystickstate = currentJoystick.GetCurrentState();
if (SlimDX.Result.Last.IsFailure) return;

ま、何をやってるかはまだよく調べてないんですがね。
returnで逃げちゃってますが、これでは以下のコードが実行されないですね・・・
まだコントローラーのエラーは想定してません。
ドンマイ。

Updateメソッド内でFuelCarrier.Updateメソッドを呼んでますが、ここで渡すオブジェクトをcurrentGamePadState からcurrentJoystickstate に変更します。

当然型が合わなくてエラーが出るので今度はFuelCarrierクラスのUpdateメソッドのコードを修正します。

public void Update(SlimDX.DirectInput.JoystickState gamepadState, ~

最後にコントローラーの操作によりX、Y座標の移動を以下のように変更。
コンパイルエラーが出ているところなので解るかと。

else if (gamepadState.X != 0)
{
    turnAmount = (gamepadState.X/100);
}


else if (gamepadState.Y != 0)
{
    movement.Z = -(gamepadState.Y/100);
}

値は適当に実行してみてから調整しました。

これで完成。
おお、プロポで動く・・・!


しかしRCプロポだと入力がXとYの二つしかありません。
なので他の操作はキーボードです。

おお、これで自前でRCシミュレーターが作れるかも!?

VRCってエンジンカーだからフィーリングが合わなくて・・・
年末くらいにはEPカーにも対応したVRC Proが出るとか出ないとかですが。 

今日はここまで。


nice!(0)  コメント(0) 

XNA:ModToolの人体基本モデルを使ってみる [.net]

XNA Game Studio
Mod Tool

長いことほったらかしにしてましたが、再度Mod Toolに挑戦。
と言ってもマニュアルを見ても全然わからん。
前回、ただのモデルは作ってXNAで表示させるまではやったんですが、アニメーションが何ともかんとも・・
そこでググってみると・・・

ありました。
http://tkina.web.fc2.com/kaihatu/siryou/Softimage-CharacterAnimationForXNA/No01_OriginalModel.htm
ここを参考にしてやってみました。

マウスの中クリックがうまくいかず、悩んだあげくにマウスの設定を見てみたら「中クリック」になってなかったのね・・・
何とかできました。

さて、ModToolには標準で人体のモデルとスケルトンが入ってます。
とりあえず初心者な私はこれを使って練習すればいいんじゃね?
Man.png
というわけでやってみました。

以下メモ書き。
============================

「XNA Game Studio」->「Connect to XNA Project」
 XNAプロジェクトファイルのフォルダを指定(SOFTIMAGE_XNAViewer)
「XNA Game Studio」->「New XNA Scene」
「8」を押してExplorerを出しておく
「XNA Game Studio」->「Create Skinned Model」
Explorerより追加されたModelの下の「SkinnedMesh」を削除
ツールバーは「Animate(アニメート)」にしておく
ここまでは前準備なので「ファイル」->「保存」で一旦保存する

モデルとボーンを作成
「取得」->「プリミティブ」->「モデル」->「ボディ - 男性」
「取得」->「プリミティブ」->「モデル」->「スケルトン - 男性 - 基本」
(完全のスケルトンを選ぶとXNAでエラーになったのです。ボーン数が多すぎるとか?)
Explorerのツリー上でドラッグ&ドロップで以下のオブジェクトの配置を変える。
「ボディ - 男性」で作られた「Man」の下の「Man」を「Create Skinned Model」で作られたモデル(Model)の下に
親だったモデルの「Man」は削除(Man2等の自動番号が振られる場合がある)
「スケルトン - 男性 - 基本」で作られた「ManSkeleton_Complete」を「Create Skinned Model」で作られたモデルの下の「DeformerRoot」の下に
ツリー上で「Man」オブジェクトを選択した状態で、「でフォーム」->「エンベロープ」->「エンベロープの設定」
ダイアログで「はい」を選び、「DeformerRoot」を中クリックしてから右クリックして選択終了する
(中クリックはマウスの設定に注意・・・)

マテリアルの設定(色を付けるだけですが・・・)
「Man」を選択した状態で「7」を押して「RenderTree」を出す
「ノード」->「リアルタイム」->「DirectX」->「DX FX」
(DirectX10を選ぶとこの後の作業でエラーに・・・XNAは9.0Cでしたっけか)
図の「DXFX2」の箱の右上の青い丸をドラッグして「Material6(番号は変わるかも)」へ、「RealTime」を選択して接続
図の「DXFX2」をダブルクリックして、「DirectX FXファイル」に「\SOFTIMAGE_XNAViewer\Content\Effects\Lambert.fx」を指定
(Lambert.fxって何かわからないけどとりあえずサンプル通りに・・・)
色を適当に指定

アニメーションを作成
この辺は実はようわからんです。
「k」キーを押してキーフレームを作るんですが、なかなかうまくいかない・・・
で、何とか動きを付けたのがコレ。



「XNA Game Studio」->「Manage Animation」でアニメーションの追加
でもこれもよくわからんです。
キャラクターキーセットとかアクションの追加や削除がうまくいきません・・・
ModTool側でやった方がいいのかも。


XNAに出力
Explorerで「Model」オブジェクトを選択して、「XNA Game Studio」->「Publish Models」
出力パスは\SOFTIMAGE_XNAViewer\Content\Models\の下に適当なファイル名を(manにしました)

ソースコード上でモデルを追加して実行
 Models.Add(new ModelAsset("Content/Models/man", content));
XBoxコントローラーの十字キーやアナログスティックでモデルの位置を調整して、Startボタンを押すとアニメーションが動きます。

どん。

おやぁ・・・?

何ねコレ?
指先が残ってみょ~~~んと伸びてます・・・

ModTool上のプレビューではちゃんと動いてるんですがね。
.xsiに変換した時の仕様の違いですか?

スケルトンの設定がまずいんですかね?
man1.png
見ると指先まで届いてないのがまずいのか?
man2.png
でもエンベロープで設定されたポイントを見ると手首から先は同じ色分けになってますが・・・

むううう?

調べてみるとこの辺ですかね?
http://tkina.blog60.fc2.com/category8-3.html

しかし対処法がよくわからんです・・・

疲れたので今日はここまで。


nice!(1)  コメント(0) 

VisualStudio2010についてあれやこれや・・・ [.net]

まだあまり使ってないVS2010ですが、とりあえずメモ書き。

<AJAX>
例によってAJAX Extensionsは標準で入ってます。
AJAX Control ToolkitはFramework3.5に対応しているものがそのままFramework4.0でも使えるみたいです。
http://www.asp.net/ajaxlibrary/act.ashx
詳しくはこちら。

<スマートデバイス>
「Visual Studio 2010 は、スマート デバイス開発をサポートしていません。」
http://msdn.microsoft.com/ja-jp/library/sa69he4t.aspx
ありゃりゃ。
.NET Compact Frameworkとか対応してないみたいです。
でも私は仕事でも使ったこと無いですが。

<モバイルWebサイト>
いわゆる携帯サイトとかPDA用サイトの開発です。
以前のVS2008からですが、テンプレート等完全に消えてますね・・・
ライブラリだけ互換の為に残ってるそうです。
テキストエディタでゴリゴリと作れないわけでもないですが・・・
しかし使うと「'System.Web.UI.MobileControls.MobilePage' は古い形式です:」と警告が出ました。
どうやら将来的に無くなる方向なんでしょうか・・・

<UMLリバースエンジニアリング>
クラスをVISIO UMLにリバースエンジニアリングできるようですが、なぜか私のは実行するとエラーでVISIOが落ちます。
ファイルも作られていない?
使ってるのはVISIO 2010なんですが。

<ADO.NET Entity Data Model>
どうやらVS2008SP1から追加された機能らしいですが、私は知りませんでした・・・
エンティティモデル図を作成してクラスが作られるみたいですが、この辺の最近の開発手法はもうよう解らんです、ハイ。
モデル図で右クリックすると「モデルからデータベースを生成」というのが出てきます。
で、DBを生成するためのDDLが作成されます。
おお、フォワードエンジニアリング?
でもマニュアルを見るとエンティティと実DBは1:1である必要はなさそうですが。
むしろ実DBの構成を意識しないためのEntity Data Modelみたいですがね・・・?
もうオジサンには解らないわいな。


まぁ正直VS2005までは何とか使いこなせていたつもりでしたが、VS2008、VS2010と来てもう新機能については何が何やら・・・
LINQも未だに使いこなせていないしな・・・

DataSetやDataSourceだけじゃダメ?

nice!(0)  コメント(0) 

Visual Studio 2010 正式版 キター! [.net]

最近Visual Studio 2010 日本語版が正式にリリースされました。
MSDNサブスクリプションで。

遂に来たか!
早速ダウンロード。

思えばこの10年程MSDNサブスクリプションのライセンスを毎年払ってきたが・・・
無職の身では次の更新は出来ないかもしれない・・・

てかもうコンピュータの仕事に就くことも無いかも・・・

俺にとってはコレが最後のVisual Studioか!?

というわけで早速インストール。

まずはリリースノートを軽く眺め。
ベータ版をアンインストール。

しかし、ベータ版の時点でいろんなものがインストールされて一発で全部はアンインストールされない・・・
名前からVS2010関係っぽいものとベータって書いてるものを片っ端にアンインストール。
私のPCにはVS2005、VS2008と入ってるので余計なものを消したら動かなくなりそうですが、まぁその時は修復するなりなんなりすればよいでしょう・・・
どうせ仕事も無いしな!

BitLockerとウィルス対策ソフトは停止させておくこと。
ふむふむ。

セットアップを実行します。
インストールオプションは全てでもよいですが、カスタムにしてインストールされるコンポーネントを確認。
結局全部インストールするのですが。

途中でFramework4.0を入れた時点で再起動。
そして1時間くらいでセットアップ完了。
ちなみにisoファイルをDaemonToolsでマウントしてセットアップした場合です。

ところでセットアップ完了後にノートPCはまた再起動になりましたが、デスクトップでは再起動メッセージは出てきませんでした。
何か条件があるんですかね?

さらにノートPCは再起動後にネットに繋がらずまた再起動・・・
BitLockerとか使ってるからかな?

セットアップ完了後にBitLockerやアンチウィルスを有効にして完了。

よし、VS2010起動!
vs2010_1.png

とりあえずWebアプリを作成。

むぅ?
なんかDefault.aspxのページに文字が入ってるぞ?
しかもマスターページ使ってる。

なんじゃこりゃ?

最初のページだけサンプルを兼ねてるんでしょうかね?
新規ページを追加すると次からは普通の空白ページでした。

おお、ログインページとかも作られてる。
これは、asp.netのメンバシップ機能を使えってことですかね?

ちょうど先日書いたメンバシップDBの設定をしてみようかね。
と思ったら、VS2010では既にWebConfigにメンバシップの記述があるし・・・!
しまった、ベータ版でも確認すれば見れてたのか?
ちっ、そうとは知らずに一生懸命調べてたわいな・・・

でもこれでメンバシップ用DBの切り替えが楽にできますね。

以前作ったMyAppDBが残ってるのでmembership、roleManager、profileのconnectionStringNameを自分のMyAppDB用ConnectionStringに変更。
(そういえばプロファイル機能は試してなかったな・・・)
実行して以前登録してあるユーザーでログインできることを確認。

問題無く動いてるっぽいな?
(ということはメンバシップDBのテーブル構成は以前と変わってないのか・・・?)

とりあえずVS2010のセットアップは大丈夫っぽい。
さてさて、あとはじっくり新機能でも調べてみるかね。

俺にとって最後のVisual Studioだしな!!!


nice!(0)  コメント(0) 

メンバシップのDB設定 [.net]

VisualStudioにはログイン認証用のメンバシップ機能があります。
デフォルトではSQLEXPRESSになってますが、Windows AsureではSQL Azureを使わないといけないのでしょうか?
しかもSQL AzureはSQL認証ですね。

念のためメンバシップのDBを変更する方法をまとめておきましょ。

VisualStudio2008
SQL Server2008

アプリケーションとDBを用意します。
アプリ:MyApp
DB:MyAppDB ログイン:MyAppLogin

MyAppDBには、業務用のデータも含む前提にします。
まず、MyAppDB内にメンバシップ用のテーブルを作成します。
VSコマンドプロンプトで以下を実行。
aspnet_regsql.exe
regsql1.jpg

アプリ用のDB(MyAppDB)を指定します。
regsql2.jpg
regsql3.jpg

ここでの認証は管理者権限で接続できればOKです。

これでDBの用意ができました。

WebRoleアプリケーション(MyApp)のWeb.configを書き換えます。
ここでMyAppDBは業務用データも入れるので、通常はConnectionStringに定義を入れると思います。

<connectionStrings>
  <add name="MyAppDBConnectionString1" connectionString="Data Source=localhost;InitialCatalog=MyAppDB;Persist Security Info=True;User ID=MyAppLogin;Password=pass" providerName="System.Data.SqlClient" />
</connectionStrings>

メンバシップのDBに、上記のConnectionStringを指定します。
この時、ロールも指定しましょう。

<system.web>

<membership defaultProvider="SqlProvider" userIsOnlineTimeWindow="20">
  <providers>
    <add name="SqlProvider"
    type="System.Web.Security.SqlMembershipProvider"
    connectionStringName="MyAppDBConnectionString1"
    enablePasswordRetrieval="false"
    enablePasswordReset="false"
    requiresQuestionAndAnswer="false"
    requiresUniqueEmail="false"
    passwordFormat="Hashed"
    maxInvalidPasswordAttempts="5"
    minRequiredPasswordLength="4"
    minRequiredNonalphanumericCharacters="0"
    applicationName="/" />
  </providers>
</membership>

<roleManager defaultProvider="SqlRoleProvider"
  enabled="true"
  cacheRolesInCookie="true"
  cookieName=".ASPROLES"
  cookieTimeout="30"
  cookiePath="/"
  cookieRequireSSL="true"
  cookieSlidingExpiration="true"
  cookieProtection="All" >
  <providers>
  <add connectionStringName="MyAppDBConnectionString1"
  applicationName="/"
  name="SqlRoleProvider"
  type="System.Web.Security.SqlRoleProvider" />
  </providers>
</roleManager>


尚、セキュリティーの質問などは不要にしていますが、CreateUserWizardコントロールではEメールアドレスだけはどうしても必須になるようです。
(RequireEmailをFalseにすると消えました・・・)
ちなみにCreateUserWizardには独自の項目を追加できるようですが、まだ試してません。


画面にログイン系のコントロールを適当に並べます。(実行画面参照)
ユーザーを新規作成した時にロールに追加するようにします。

protected void CreateUserWizard1_CreatedUser(object sender, EventArgs e)
{
 if (!Roles.RoleExists("Users"))
 {
  Roles.CreateRole("Users");
 }
 Roles.AddUserToRole(((CreateUserWizard)sender).UserName, "Users");
}


ついでにユーザーのリストを出力します。

SELECT aspnet_Users.UserId, aspnet_Users.UserName, aspnet_Membership.Password,aspnet_Membership.Email
FROM aspnet_Users INNER JOIN aspnet_Membership ON aspnet_Users.UserId = Membership.UserId

実行します。
regsql4.jpg

新規ユーザーを作ってログインします。
regsql6.jpg


終わり。





nice!(0)  コメント(0) 

Windows Azureってどうよ? [.net]

巷ではクラウドクラウドとなんやらようわからん宣伝文句が広がってますが、どこぞのRPGの主人公ではなくクラウドコンピューティングの話。
MSも今年からWindows Azureのサービスを開始したようで。

あいかわらず仕事は無いが、アプリの開発の仕方ぐらいは試してみるか。

Windows Azureは世界のどこかにあるコンピューターを借りて、その上でアプリなど乗せて運用するという感じか。
例えばホスティングなどでは丸ごとWindowsサーバーを借りて、リモート接続でWebアプリを配置したりするのでしょうが、モノがそのままWindows OSなので自分のPCで作ったアプリをそのまま乗せればよい。
しかしWindows Azureはちと違うらしい。

さてどうするんでしょうということで以下を参考にしました。
http://www.atmarkit.co.jp/fdotnet/dnfuture/winazuretry_01/winazuretry_01_01.html
Windows Azure開発入門
http://codezine.jp/article/detail/4558
SQL Azureの概要とSQL Azure Databaseを使ったアプリケーション開発

ふむふむ、WebアプリはWindowsAzureに配置し、DBはSQL Azureに配置するようで。
WebアプリはSDKを使って開発(デバックもできる)し、完成したら実際のWindows Azureに配置して運用する感じですね。
DBは開発では通常のSQL Serverで行い、運用時にSQL Azureに移行して使う感じですかね。
しかしSQL Azureは完全にSQL Serverの機能に対応してるわけではなさそうですが、その辺をチェックする機能は無いのでしょうか?
作っていざSQL Azureに上げてみたらエラーで動かなかったとかありそうな気がするのですが・・・
調べれば何かあるんですかね?
会員になってないので続きが読めなかったわいな。


ざっくりやってみましょ。
OS:Windows7
DB:SQL Server 2008 developer
VisualStudio2008

Windows Azure Software Development Kit (July 2009 CTP)

Windows Azure SDKをインストールしようとするとエラーが出ました。
VS2008にSP1を入れろとのこと。
おや?
バージョン情報を見ると入ってるのだが。

とりあえずVS2008SP1を再度インストールして念のためWinUpdateでVS用の更新を全てインストール。
今度はちゃんとSDKが入りました。

VS2008を起動して新しいプロジェクトで「Windows Azure Cloud Service」を作成。
cloud1.jpg
ダイアログボックスで ソリューションに含めるサービスに「ASP.NET Web Role」(Webアプリ)を追加。
後で追加することもできます。
cloud2.jpg
こんな感じ。
cloud3.jpg
サーバーエクスプローラーより適当なテーブルをドラッグしてGridViewを作成。
で、デバッグ実行。

エラー。
cloud4.jpg

VSを管理者で起動しろとのこと。
そういやVista以降はそんな設定にしないといかんかったか。
以下のファイルのプロパティで管理者で起動に変更。
C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe
C:\Program Files\Common Files\microsoft shared\MSEnv\VSLauncher.exe

で、デバッグ実行。

エラー。
cloud5.jpg

むぅ?

出力を見ると、
Windows Azure Tools: Failed to initialize the Development Storage service.
Unable to start Development Storage.
Failed to start Development Storage: the SQL Server instance ‘localhost\SQLExpress’ could not be found.
Please configure the SQL Server instance for Development Storage using the ‘DSInit’ utility in the Windows Azure SDK.

どうやらSQLExpressが無いのでDSInitで設定しろと言ってるみたい。
そういやExpressは入れてなかったな。

SQLExpressを入れてもいいけど、通常のSQL Serverだけの場合の設定方法も調べてみましょ。
http://thedotnethub.blogspot.com/2009/12/activating-azure-storage-service-for.html

スタートメニューからWindows Azure SDKのコマンドプロンプトを起動します。

以下のコマンドを実行します。
DSInit /sqlInstance:. /forceCreate

sqliInstanceのドット(.)はローカルホストの既定のインスタンスです。
cloud6.jpg

なんか実行結果が出ます。

これでOK。
再度VSでデバック実行します。
無事グリッドにデータが表示されました。
ぱちぱち。


あとはこんな感じでWebアプリを作っていけばいいようですね。
実際の配置にはWindows Azureを料金払って借りないと試せないのでこれにて終了・・・


nice!(0)  コメント(0) 

ファイル監視 [.net]

巷ではHPの改ざんが多数発生しているようですが。

企業サイトであればHPの改ざんやウィルスのチェックをしてくれるサービスが色々あるようなので、それを利用するのもいいかもです。
が、とりあえず簡単にファイルの改ざんをチェックするWindowsサービスを.netで作ってみました。
と言ってもよく見かけるサンプルをそのまま使ってみただけですが。

実はセットアッププロジェクトの作成の仕方をいつも忘れるので、そのための個人的メモ書きだったりします。


言語: C# (VisualStudio2008)
Windowsサービス

プロジェクトの作成でWindowsサービスを作成。
名前はFileWatcherにしました。
FileSystemWatcherを使うだけだし。

ファイルが改ざんされたらメールを送信するようにしたいのですが、今回はイベントログに書くだけにしています。
しかもただアプリケーションのイベントログに書くだけです。

プロジェクトの設定にWatchPathのパラメータを追加。
値はC:\inetppub\wwwroot。

サービスのクラスをFileWatcherに変更。
 public partial class FileWatcher : ServiceBase
 {
  public FileWatcher()
  {
   InitializeComponent();
   base.AutoLog = false;
  }

  protected override void OnStart(string[] args)
  {
   // 監視するフォルダ
   watcher.Path = Properties.Settings.Default["WatchPath"].ToString();
   // 監視する変更の種別
   watcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.Attributes
    | NotifyFilters.LastAccess
    | NotifyFilters.LastWrite | NotifyFilters.Security | NotifyFilters.Size;
   watcher.Filter = "*.*";
   // イベントハンドラ
   watcher.Created += OnChanged;
   watcher.Changed += OnChanged;
   watcher.Deleted += OnChanged;
   watcher.Renamed += OnRenamed;

   // 監視開始
   watcher.EnableRaisingEvents = true;
  }

  protected override void OnStop()
  {
   // 監視停止
   watcher.EnableRaisingEvents = false;
  }

  private FileSystemWatcher watcher = new FileSystemWatcher();

  public void MailSend(string Msg)
  {
   // あとで追加
  }

  public void OnChanged(object source, FileSystemEventArgs e)
  {
   string Result;
   Result = e.ChangeType.ToString("G") + "," + e.FullPath + "\n";
   System.Diagnostics.EventLog.WriteEntry("アプリケーション", Result);
    MailSend(Result);
  }

  public void OnRenamed(object source, RenamedEventArgs e)
  {
   string Result;
   Result = e.ChangeType.ToString("G") + "," + e.OldFullPath + " -> " + e.FullPath + "\n";
   System.Diagnostics.EventLog.WriteEntry("アプリケーション", Result);
   MailSend(Result);
  }
 }

イベントログの書き込みをちゃんとやりたい場合は以下を参照。
http://support.microsoft.com/kb/307024/ja

さて、Windowsサービスはインストールすることを考えなければいけませんね。
コマンドプロンプトで手動で設定してもいいのですが、ちとめんどくさいです。

プロジェクトの先程のサービスをデザイナビューで右クリックすると、「インストーラの追加」があります。
ProjectInstallerクラスが追加され、中にはserviceProcessInstaller1とserviceInstaller1があります。

serviceInstaller1のプロパティでDisplayNameとServiceNameを設定します。
StartTypeをAutomatic(自動)にしてもよいでしょう。
serviceProcessInstaller1のプロパティでAccountにLocalSystemを指定します。
これでこのサービスはSystemアカウントで起動するようになります。
いや、ユーザー指定するのめんどくさいし。

次にソリューションにセットアッププロジェクトを追加します。
セットアッププロジェクトを右クリック -> 追加 -> プロジェクト出力を選び、サービスプロジェクトのプライマリ出力を選びます。
基本的にこの辺はデフォルト値でOKです。

またセットアッププロジェクトを右クリック -> 表示 -> カスタム動作を選びます。
カスタム動作のウィンドウでカスタム動作を右クリック -> カスタム動作の追加を選びます。
アクティブのプライマリ出力を選びます。

あとは好みや事情でインストーラのプロパティを変更します。
セットアッププロジェクトのプロパティで、AuthorとManufacturerにMyCompanyとか適当に入れます。
(インストールフォルダの初期値に使われるのでそれっぽいのを入れます)
InstallAllUsersをtrueにします。
インストール時に全てのユーザーが初期値になります。


ビルドしてインストーラを実行すると、サービスがインストールされます。
セットアッププロジェクトを右クリックすると、インストールとアンインストールの実行ができます。
インストール後は停止しているので管理ツールのサービスもしくはコマンドで起動します。

C:\inetpub\wwwrootにファイルを追加、変更を行うとイベントログに書き込まれます。
やはりメールも送信した方がいいでしょうね。
VisualStudioと同じPC上で実行していると、サービスに例外が発生した時にデバッカが使用できます。


でもこの辺ってチュートリアルにもあったよな・・・?
nice!(0)  コメント(0)