2010年11月17日星期三

Windows Work Flow Foundation 勉強の1概要紹介

図一枚は文字千字より説明並びに理解し易いと感じられるでしょう。

「Windows Workflow Foundation」(以下、WF)*1は、2005年9月に開催されたPDC(Professional Developers Conference)で発表されたマイクロソフトの次世代ワークフロー基盤のことである。
業務や処理の流れを図示・ルール化したものです。

容易な開発と実行をサポートするWFが、Windows Communication Foundation(以下、WCF)やWindows Presentation Foundation(以下、WPF)と一緒に、Windows Vistaに搭載されるWinFX*2の一部として提供されることである。

 ※WinFXは次期WindowsクライアントOSのWindows Vistaに搭載される新APIセットで、次世代アプリケーションの開発・実行基盤である


マイクロソフトが公開しているWFの資料の中では、
WFは一連処理と人間参与処理を分けて定義すると、
・システム・ワークフロー(System Flow)
・ヒューマン・ワークフロー(Human Flow)
に分けています。普段のネットショッピングなどの流れはシステムワークフローであって、
人の承認などはヒューマン・ワークフローである。


システムワークフローはまた二つに分けれます。
・シーケンシャル・ワークフロー(Sequential Workflow)
・ ステートマシン・ワークフロー(State Machine Workflow

シーケンシャル・ワークフローは、UMLのアクティビティ図と同じような感じでワークフローを記述できる。アクティビティは行為と考えられ、何かをやるやらせることです。
シーケンシャルは行為に関するから、どの条件でなにをやるのかは基本です。

ステートマシン・ワークフローは、UMLの状態遷移図のイメージでワークフローを記述できる。
状態はやる前に、やった後、待ち合わせ等と考えられます。

BPEL (Business Process Execution Language)は何?

BPELは、WSDLで記述されたWebサービス・インターフェイスをベースとして、Webサービスの呼び出し、データの操作、障害通知、例外処理、プロセスの終了などのアクティビティを結び合わせて、複雑なプロセスを定義する。また、処理フロー記述のほかに、B2B(企業間の取引)フローのように、異なる企業間でのWebサービス連携の記述にも適用可能となっている。

BPELは、それまであったWSFL(IBM)とXLANG(マイクロソフト)というベンダ仕様を融合し、2002年8月にIBM、マイクロソフト、BEAシステムズによって発表され、その後2003年5月にIBM、マイクロソフト、BEA、SAP、シーベルによってBPEL 1.1が公開された。これを叩き台に標準化団体のOASISで標準化の作業が進められている。現状でも、BPEL仕様に準拠していれば、どのベンダ製品でも実行可能な形になっている。

ビジネスプロセスを記述・設計するための言語としての側面と、ビジネスプロセス・エンジン(オーケストレーション・エンジン)などと呼ばれる実行環境で、Webサービスによるプロセスを実行するスクリプト言語としての側面がある。

Windows Script勉強の1 補足パラメータを渡す

一件補足します。
WSにパラメータを渡すときに、渡されたパラメータがどう取得して使うのか、例を挙げます。

Set objArgs = WScript.Arguments
For I = 0 to objArgs.Count - 1
WScript.Echo objArgs(I)
Next

この例で、渡されたパラメータをメッセージとして表示する。
簡単ですが、test.vbsに保存して、ファイル(c:\log.txt)をtest.vbs上にドラッグしてドロップしていたら、メッセージ「c:\log.txt」を表示される。

2010年11月16日星期二

Create Windows Service by C#

.Net 下创建Windows Service 非常简单。

1 继承ServiceBase,根据需要Override OnStart, OnStop, OnPauce, OnContinue,OnShutDown等方法。
所以并不是所有的基类虚方法都要重写的,一般来说写一个OnStart就够了。
例如
public partial class HellowordService : ServiceBase
    {
        public HellowordService()
        {
            // ServiceBase继承自Component,所以也是个组件,可以直接将想要的服务
            // 分线程Component直接托近来使用,比如将FileSystemWatcher拖进来监视系统文件状况
            // 还可以拖个Backgroudworker近来,将具体的逻辑委托出去。
            InitializeComponent();
        }
        protected override void OnStart(string[] args)
        {
            // TODO: Add code here to start your service.
            Console.WriteLine("Hello word!");
        }
    }
再来一个HelloWxgService
public partial class HelloWxgService: ServiceBase
    {
        public HelloWxgService()
        {
              InitializeComponent();
        }
        protected override void OnStart(string[] args)
        {
            // TODO: Add code here to start your service.
            Console.WriteLine("Hello wxg!");
        }
    }

2 具体的Service类做好后,要做个Service安装类。
安装类要继承Installer基类,也是个组件,而且还要对这个继承类声明成执行安装属性
[RunInstaller(true)],是为了通过.net的安装工具installUtil安装时,告诉installUtil,安装入口是谁。
例:
    [RunInstaller(true)]
    public partial class WSManagerInstaller : Installer
    {
        public WSManagerInstaller ()
        {
            InitializeComponent();
        }
    }

3 Installer的子类HellowordServiceInstaller 中要添加ServiceInstaller和ServiceProcessInstaller。
一个Service,对应一个ServiceInstaller, 而ServiceProcessInstaller 就一个就够了。
ServiceProcessInstaller 是在InstallUtil安装服务时,写注册表用的安装类。
ServiceInstaller.ServiceName 设定值将在控制面板-管理工具-Service的列表中显示。
例:
   private ServiceInstaller serviceInstaller1;
   private ServiceInstaller serviceInstaller2;
   private ServiceProcessInstaller processInstaller;

   private InitializeComponent(){

      // Instantiate installers for process and services.
      processInstaller = new ServiceProcessInstaller();
      serviceInstaller1 = new ServiceInstaller();
      serviceInstaller2 = new ServiceInstaller();

      // The services run under the system account.
      processInstaller.Account = ServiceAccount.LocalSystem;
      processInstaller.User=null;
      processInstaller.Password=null;

      // The services are started manually.
      serviceInstaller1.StartType = ServiceStartMode.Manual;
      serviceInstaller2.StartType = ServiceStartMode.Manual;

      // ServiceName must equal those on ServiceBase derived classes.           
      serviceInstaller1.ServiceName = "TestFileWatherService";
      serviceInstaller2.ServiceName = "HelloewordService";

      // Add installers to collection. Order is not important.
      this.Installers.Add(serviceInstaller1);
      this.Installers.Add(serviceInstaller2);
      this.Installers.Add(processInstaller);
   }
4 Installer类做成后,通过InstallUtil.exe执行安装/卸载
InstallUtil.exe的路径是
%WINDOWS%\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe
安装命令:
%WINDOWS%\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe  TestServices.exe
卸载命令(增加 -u ):
%WINDOWS%\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe  -u TestServices.exe

以上,安装完之后,就可以通过windows的Service管理工具查看,并启动或停止。
注意:以上的例子中将服务设定成手动启动,
安装完后,可能要重起PC才有效,不然总是会出1083的服务不能启动错误。

2010年11月12日星期五

共通キーで暗号化複合化(対称アルゴリズム)

キーの作成と管理は、暗号プロセスの重要な部分です。
対称アルゴリズムでは、キーと初期化ベクター (IV) を作成する必要があります。
共通キーは暗号化複合化同一ということですので、
誰でも手に入れたら、復号できるのです。
したがって、作成したキーと IV は、情報共有者内部のみで公開します。

一般に、キーと IV はセッションごとに新しく作成する必要があり、
キーも IV も格納して、後のセッションで使用することは望ましくありません。

通常、共通キーと IV を離れた場所にいる人へ送信するためには、
非対称暗号化方式を使用して共通キーと IV を暗号化します。
これらの値を暗号化せずに安全でないネットワークをとおして送信することは、
値を傍受した人ならだれでもデータを復号化できるようになるため、非常に危険です。

つまり共通キーを使うのは
①セッション単位で共通キー(KEYとIV)を作成する。
②非対称キー(元私、先公)で共通キーを暗号化する。
③送信相手に暗号化された共通キーを送信する。
④送信相手は自分のに対する非対称キー(元私、先公)で復号化して、共通キーを取得する。
⑤お互いに共通キーで送受信する。
代表的な例はSSLです。
.Netで共通キーの生成例:
// インスタンス化された時点で、KEY、IVが生成されます。
TripleDESCryptoServiceProvider TDES = new TripleDESCryptoServiceProvider();
//明示的に生成KEY,IVで、新たな別のKEY、IVを生成します。
//毎回生成されたKEY、IVは固定ではないです。
TDES.GenerateIV();
TDES.GenerateKey();

2010年11月11日星期四

.Net2.0明确手动管理Transaction简介

.Net2.0对业务Transaction的管理,有两种方式,
一种是TransactionScope的自动管理,所有逻辑只要包含在TransactionScope范围内,会被自动注册到一个Transaction,最终一次提交或回滚。

第二种就是用户自己创建ICommittableTransaction, 自己规定什么时候调用Commit或者Rollback。

第一种TransactionScope方式,已经在TransactionScope简介中介绍了。
说说第二种,手动明确管理Transaction.
代码例:

// Create the Transaction
ICommittableTransaction oTran = Transaction.Create();

// Open a connection to SQL Server 2005
using (SqlConnection oCn1 = new SqlConnection(this.sCn1))
{
    SqlCommand oCmd1 = new SqlCommand(this.sSQL, oCn1);
    oCn1.Open();

    // The connection is not yet enlisted in the transaction scope 
    oCn1.EnlistTransaction();

    // Now the connection is enlisted in the transaction scope 
    oCmd1.ExecuteNonQuery((ITransaction)oTran);
    oCn1.Close();
}

// Tell the transaction to commit 
oTran.Commit();

ICommittableTransaction,TransactionScope都在在.Net2.0的System.Transactions命名空间下。
注意ICommittableTransaction是管理业务Transaction用的,
有别于具体的某个DBConnection.BeginTransaction得到的DBTransaction.

TransactionScope简介

TransactionScope是.net2.0开始提供的事务处理机制中的关键。
Java2EE中有分散业务的Transaction管理,所以.net中也应该有。

TransactionScope能够实现的功能,简单的说其实就是分散业务的统合管理,
不再仅仅是一个DBConnection中的一连处理,可以像Java2EE一样管理所有的业务,
比如对多个数据库的操作,只要在TransactionScope内,就全受其所管。
而且,TransactionScope还可以嵌套,设定范围。

对于涉及Transaction的Aplication, MS推荐使用黯然型的TransactionScope,
即,具体的业务逻辑不需要关注什么时候BeginTransaction,什么时候Commit,或者Rollback,
只要将一堆事情,当成一件事做完就可以了。

具体例:
void btnImplicitDistributed_Click(object sender, EventArgs e)
{
    // Create the TransactionScope
    using (TransactionScope oTranScope = new TransactionScope(TransactionScopeOptions.Required))
    {
        // first job
        using (IConnection oCn1 = new SqlConnection(this.constr1))
        {
            ICommand oCmd1 = new SqlCommand(this.sSQL, oCn1);
            oCn1.Open();
            // At this point, the connection is in the transaction scope,
            // which is a lightweight transaction.
            oCmd1.ExecuteNonQuery();
            oCn1.Close();
        }
        // second job
        using (IConnection oCn2 = new OracleConnection(this.constr2))
        {
            ICommand oCmd2 = new OracleCommand(this.sSQL, oCn2);
            oCn2.Open();
            // The connection is enlisted in the transaction scope,
            // which is now promoted to a distributed transaction
            // controlled by MSDTC
            oCmd2.ExecuteNonQuery();
            oCn2.Close();
        }
        // Tell the transaction scope to commit when ready
        oTranScope.Consistent = true;
        // The following bracket completes and disposes the transaction
        // or do this.
        // oTranScope.Complete();
    }
}

上例中,各自DBTransaction会隐式的加入到TransactionScope中,正常处理结束后,在跳出using之后,就会判断TransactionScope的Commitable属性,决定是否执行Commit;中途出现Exception的话,自动调用Scope中保存的各个Tranasction的Rollback.

上例的两个DB操作,通常会放到两个Method中调用,或反射调用,甚至在一个LIST中遍历调用。只要是在这个Scope内,就算是一个大的Transaction。

TransactionScopeOptions范围限定简介:
TransactionScopeOptionsDescription
Required(default)If within a currently active transaction scope, this transaction scope will join it. Otherwise it will create its own transaction scope.
RequiresNewThis transaction will create its own transaction scope.
SuppressNo transaction.


嵌套
using(TransactionScope scope1 = new TransactionScope())
{
     try
     {
          //Start of non-transactional section 
          using(TransactionScope scope2 = new
             TransactionScope(TransactionScopeOption.Suppress))
          {
               //Do non-transactional work here
          }
          //Restores ambient transaction here
   }
     catch
     {}
   //Rest of scope1
}