2010年12月29日星期三

AJax UpdatePanel Execute Javascript function After PostBack

I want to execute a javascript function on response postback.
I know window.onload=function(){...}, it's init the page,
but I want to reset the page control properties by javascript after the postback, not directly from server.

I  have a btnOK, I add  the following snippet  under btnOK_Click(sender, e);

ScriptManager.RegisterStartupScript(updPanel, GetType(string), "funName", "Alert('hello word!');", True)

It will create a javascript snippet in html on response back. and execute it. on page refresh, it will alert hello word.

2010年12月14日星期二

Extension Methods (C# Programming Guide)

Extension Methods (C# Programming Guide)
The following example shows how to call the standard query operator OrderBy method on an array of integers. The expression in parentheses is a lambda expression. Many standard query operators take lambda expressions as parameters, but this is not a requirement for extension methods.
=============================================================
class ExtensionMethods2   
{
    static void Main()
    {           
        int[] ints = { 10, 45, 15, 39, 21, 26 };
        var result = ints.OrderBy(g => g);
        foreach (var i in result)
        {
            System.Console.Write(i + " ");
        }          
    }       
}
//Output: 10 15 21 26 39 45
=============================================================
Extension methods are defined as static methods but are called by using instance method syntax.
Their first parameter specifies which type the method operates on, and the parameter is preceded by the this modifier.
Extension methods are only in scope when you explicitly import the namespace into your source code with a using directive.

The following example shows an extension method defined for the System.String class. Note that it is defined inside a non-nested, non-generic static class:
=============================================================
namespace ExtensionMethods
{
    public static class MyExtensions
    {
        public static int WordCount(this String str)
        {
            return str.Split(new char[] { ' ', '.', '?' },
                             StringSplitOptions.RemoveEmptyEntries).Length;
        }
    }  
}

The WordCount extension method can be brought into scope with this using directive:
And it can be called from an application by using this syntax:
=============================================================
string s = "Hello Extension Methods";
int i = s.WordCount();

The following example implements an extension method named WordCount in the MyExtensions.StringExtension class
=============================================================
using System.Linq;
using System.Text;
using System;
namespace CustomExtensions
{
    //Extension methods must be defined in a static class
    public static class StringExtension
    {
        // This is the extension method.
        // The first parameter takes the "this" modifier
        // and specifies the type for which the method is defined.
        public static int WordCount(this String str)
        {
            return str.Split(new char[] {' ', '.','?'}, StringSplitOptions.RemoveEmptyEntries).Length;
        }
    }
}
namespace Extension_Methods_Simple
{
    //Import the extension method namespace.
    using CustomExtensions;
    class Program
    {
        static void Main(string[] args)
        {
            string s = "The quick brown fox jumped over the lazy dog.";
            //  Call the method as if it were an
            //  instance method on the type. Note that the first
            //  parameter is not specified by the calling code.
            int i = s.WordCount();
            System.Console.WriteLine("Word count of s is {0}", i);
        }
    }
}


ref: http://msdn.microsoft.com/en-us/library/bb311042.aspx

Filtering with DataView (LINQ to DataSet)

Creating DataView from a Query with Filtering Information
=====================================================
Dim orders As DataTable = dataSet.Tables("SalesOrderDetail")
Dim query = _
    From order In orders.AsEnumerable() _
    Where order.Field(Of Int16)("OrderQty") > 2 And _
          order.Field(Of Int16)("OrderQty") < 6 _
    Select order
Dim view As DataView = query.AsDataView()
bindingSource1.DataSource = view

The following example creates a DataView from a query for orders placed after June 6, 2001:
=====================================================
Dim orders As DataTable = dataSet.Tables("SalesOrderHeader")
Dim query = _
    From order In orders.AsEnumerable() _
    Where order.Field(Of DateTime)("OrderDate") > New DateTime(2002, 6, 1) _
    Select order
Dim view As DataView = query.AsDataView()
bindingSource1.DataSource = view

The following example uses the SoundEx algorithm to find contacts whose last name is similar to "Zhu". The SoundEx algorithm is implemented in the SoundEx method.
=====================================================
Dim contacts As DataTable = dataSet.Tables("Contact")
Dim soundExCode As String = SoundEx("Zhu")
Dim query = _
    From contact In contacts.AsEnumerable() _
    Where SoundEx(contact.Field(Of String)("LastName")) = soundExCode _
    Select contact
=====================================================
Dim view As DataView = query.AsDataView()
bindingSource1.DataSource = view
dataGridView1.AutoResizeColumns()

Using the RowFilter Property
=====================================================
Dim contacts As DataTable = dataSet.Tables("Contact")
Dim view As DataView = contacts.AsDataView()
view.RowFilter = "LastName='Zhu'"
bindingSource1.DataSource = view
dataGridView1.AutoResizeColumns()

Dim contacts As DataTable = dataSet.Tables("Contact")
Dim query = _
    From contact In contacts.AsEnumerable() _
    Where contact.Field(Of String)("LastName") = "Hernandez" _
    Select contact

Dim view As DataView = query.AsDataView()
bindingSource1.DataSource = view
dataGridView1.AutoResizeColumns()
view.RowFilter = "LastName='Zhu'"
After a DataView has been created from a DataTable or LINQ to DataSet query, you can use the RowFilter property to specify subsets of rows based on their column values. The string-based and expression-based filters are mutually exclusive. Setting the RowFilter property will clear the filter expression inferred from the LINQ to DataSet query, and the filter expression cannot be reset.
The filter on a DataView can be cleared after filtering has been set using the RowFilter property. The filter on a DataView can be cleared in two different ways:
■Set the RowFilter property to null.
■Set the RowFilter property to an empty string.
=====================================================
Dim orders As DataTable = dataSet.Tables("SalesOrderHeader")
Dim query = _
    From order In orders.AsEnumerable() _
    Where order.Field(Of DateTime)("OrderDate") > New DateTime(2002, 11, 20) _
        And order.Field(Of Decimal)("TotalDue") < New Decimal(60.0) _
    Select order
Dim view As DataView = query.AsDataView()
bindingSource1.DataSource = view
view.RowFilter = Nothing
=====================================================
Dim contacts As DataTable = dataSet.Tables("Contact")
Dim view As DataView = contacts.AsDataView()
view.RowFilter = "LastName='Zhu'"
bindingSource1.DataSource = view
dataGridView1.AutoResizeColumns()
' Clear the row filter.
view.RowFilter = ""

LINQ Query Syntax versus Method Syntax (C#)

At compile time, query expressions are translated to something that the CLR does understand: method calls.
These methods are called the standard query operators, and they have names such as Where, Select, GroupBy, Join, Max, Average, and so on. You can call them directly by using method syntax instead of query syntax.

The following example shows a simple query expression and the semantically equivalent query written as a method-based query.

class QueryVMethodSyntax
{
    static void Main()
    {
        int[] numbers = { 5, 10, 8, 3, 6, 12};
        //Query syntax:
        IEnumerable<int> numQuery1 =
            from num in numbers
            where num % 2 == 0
            orderby num
            select num;
        //Method syntax:
        IEnumerable<int> numQuery2 = numbers.Where(num => num % 2 == 0).OrderBy(n => n);
        foreach (int i in numQuery1)
        {
            Console.Write(i + " ");
        }
        Console.WriteLine(System.Environment.NewLine);
        foreach (int i in numQuery2)
        {
            Console.Write(i + " ");
        }
        // Keep the console open in debug mode.
        Console.WriteLine(System.Environment.NewLine);
        Console.WriteLine("Press any key to exit");
        Console.ReadKey();
    }
}
/*
    Output:
    6 8 10 12
    6 8 10 12
 */

The output from the two examples is identical. You can see that the type of the query variable is the same in both forms: IEnumerable<T>.
If you are familiar with the generic IEnumerable<T> interface, you know that it does not have a Where method. However, if you invoke the IntelliSense completion list in the Visual Studio IDE, you will see not only a Where method, but many other methods such as Select, SelectMany, Join, and Orderby. These are all the standard query operators.

Although it looks as if IEnumerable<T> has been redefined to include these additional methods, in fact this is not the case. The standard query operators are implemented as a new kind of method called extension methods. Extensions methods "extend" an existing type; they can be called as if they were instance methods on the type. The standard query operators extend IEnumerable<T> and that is why you can write numbers.Where(...).

Queries in LINQ to DataSet

A query is an expression that retrieves data from a data source. Queries are usually expressed in a specialized query language, such as SQL for relational databases and XQuery for XML. Therefore, developers have had to learn a new query language for each type of data source or data format that they query. Language-Integrated Query (LINQ) offers a simpler, consistent model for working with data across various kinds of data sources and formats. In a LINQ query, you always work with programming objects.
A LINQ query operation consists of three actions: obtain the data source or sources, create the query, and execute the query.

In LINQ, a query is stored in a variable. If the query is designed to return a sequence of values, the query variable itself must be a enumerable type. This query variable takes no action and returns no data; it only stores the query information. After you create a query you must execute that query to retrieve any data.
In contrast to deferred queries, which return a sequence of values, queries that return a singleton value are executed immediately. Some examples of singleton queries are Count, Max, Average, and First. These execute immediately because the query results are required to calculate the singleton result. For example, in order to find the average of the query results the query must be executed so that the averaging function has input data to work with. You can also use the ToList(Of TSource) or ToArray(Of TSource) methods on a query to force immediate execution of a query that does not produce a singleton value. These techniques to force immediate execution can be useful when you want to cache the results of a query. For more information about deferred and immediate query execution, see Getting Started with LINQ.

LINQ to DataSet queries can be formulated in two different syntaxes: query expression syntax and method-based query syntax.

==========================================================
Query Expression Syntax

By using query expression syntax, you can perform even complex filtering, ordering, and grouping operations on data sources with minimal code.
Query expression syntax is new in C# 3.0 and Visual Basic 2008.

// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
DataTable products = ds.Tables["Product"];

IEnumerable<DataRow> query =
    from product in products.AsEnumerable()
    select product;
Console.WriteLine("Product Names:");
foreach (DataRow p in query)
{
    Console.WriteLine(p.Field<string>("Name"));
}


==========================================================
Method-Based Query Syntax

The method-based query syntax is a sequence of direct method calls to LINQ operator methods,
passing lambda expressions as the parameters

// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
DataTable products = ds.Tables["Product"];

var query = products.AsEnumerable().
    Select(product => new
    {
        ProductName = product.Field<string>("Name"),
        ProductNumber = product.Field<string>("ProductNumber"),
        Price = product.Field<decimal>("ListPrice")
    });

Console.WriteLine("Product Info:");

foreach (var productInfo in query)
{
    Console.WriteLine("Product name: {0} Product number: {1} List price: ${2} ",
        productInfo.ProductName, productInfo.ProductNumber, productInfo.Price);
}

==========================================================
Composing Queries

As mentioned earlier in this topic, the query variable itself only stores the query commands when the query is designed to return a sequence of values. If the query does not contain a method that will cause immediate execution, the actual execution of the query is deferred until you iterate over the query variable in a foreach or For Each loop. Deferred execution enables multiple queries to be combined or a query to be extended. When a query is extended, it is modified to include the new operations, and the eventual execution will reflect the changes. In the following example, the first query returns all the products. The second query extends the first by using Where to return all the products of size "L":


// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
DataTable products = ds.Tables["Product"];

IEnumerable<DataRow> productsQuery =
    from product in products.AsEnumerable()
    select product;

IEnumerable<DataRow> largeProducts =
    productsQuery.Where(p => p.Field<string>("Size") == "L");

Console.WriteLine("Products of size 'L':");

foreach (DataRow product in largeProducts)
{
    Console.WriteLine(product.Field<string>("Name"));
}



After a query has been executed, no additional queries can be composed, and all subsequent queries will use the in-memory LINQ operators. Query execution will occur when you iterate over the query variable in a foreach or For Each statement, or by a call to one of the LINQ conversion operators that cause immediate execution.
These operators include the following: ToList<TSource>, ToArray<TSource>, ToLookup, and ToDictionary.

In the following example, the first query returns all the products ordered by list price. The ToArray<TSource> method is used to force immediate query execution:

// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
DataTable products = ds.Tables["Product"];

IEnumerable<DataRow> query =
    from product in products.AsEnumerable()
    orderby product.Field<Decimal>("ListPrice") descending
    select product;

// Force immediate execution of the query.
IEnumerable<DataRow> productsArray = query.ToArray();

Console.WriteLine("Every price from highest to lowest:");

foreach (DataRow prod in productsArray)
{
    Console.WriteLine(prod.Field<Decimal>("ListPrice"));
}

ref: http://msdn.microsoft.com/en-us/library/bb397947.aspx

Lambda Expressions(operator of " => ") (C# Programming Guide)

A lambda expression is an anonymous function that can contain expressions and statements,
and can be used to create delegates or expression tree types.
All lambda expressions use the lambda operator =>, which is read as "goes to". The left side of the lambda operator specifies the input parameters (if any) and the right side holds the expression or statement block. The lambda expression x => x * x is read "x goes to x times x." This expression can be assigned to a delegate type as follows:

delegate int del(int i);
static void Main(string[] args)
{
    del myDelegate = x => x * x;
    int j = myDelegate(5); //j = 25
}

==========================================================
Expression Lambdas
A lambda expression with an expression on the right side is called an expression lambda.
Expression lambdas are used extensively in the construction of Expression Trees (C# and Visual Basic).
An expression lambda returns the result of the expression and takes the following basic form:
 (input parameters) => expression
The parentheses are optional only if the lambda has one input parameter;
otherwise they are required. Two or more input parameters are separated by commas enclosed in parentheses:

 (x, y) => x == y

Sometimes it is difficult or impossible for the compiler to infer the input types. When this occurs,
you can specify the types explicitly as shown in the following example:

 (int x, string s) => s.Length > x

Specify zero input parameters with empty parentheses:

 () => SomeMethod()

==========================================================
Statement Lambdas
A statement lambda resembles an expression lambda except that the statement(s) is enclosed in braces:

(input parameters) => {statement;}

The body of a statement lambda can consist of any number of statements; however, in practice there are typically no more than two or three.

delegate void TestDelegate(string s);

TestDelegate myDel = n => { string s = n + " " + "World"; Console.WriteLine(s); };
myDel("Hello");

==========================================================
Lambdas with the Standard Query Operators
Many Standard query operators have an input parameter whose type is one of the Func<T, TResult> family of generic delegates. The Func<T, TResult> delegates use type parameters to define the number and type of input parameters, and the return type of the delegate. Func delegates are very useful for encapsulating user-defined expressions that are applied to each element in a set of source data. For example, consider the following delegate type:

public delegate TResult Func<TArg0, TResult>(TArg0 arg0)

The delegate can be instantiated as Func<int,bool> myFunc where int is an input parameter and bool is the return value. The return value is always specified in the last type parameter. Func<int, string, bool> defines a delegate with two input parameters, int and string, and a return type of bool. The following Func delegate, when it is invoked, will return true or false to indicate whether the input parameter is equal to 5:

Func<int, bool> myFunc = (x => x == 5);
bool result = myFunc(4); // returns false of course

You can also supply a lambda expression when the argument type is an Expression<Func>, for example in the standard query operators that are defined in System.Linq.Queryable. When you specify an Expression<Func> argument, the lambda will be compiled to an expression tree.
A standard query operator, the Count method, is shown here:

int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
int oddNumbers = numbers.Count(n => n % 2 == 1);

This example shows how to specify multiple input parameters by enclosing them in parentheses.
The method returns all the elements in the numbers array until a number is encountered
whose value is less than its position. Do not confuse the lambda operator (=>) with the greater than
or equal operator (>=).

var firstSmallNumbers = numbers.TakeWhile((n, index) => n >= index);

==========================================================
Type Inference in Lambdas
When writing lambdas, you often do not have to specify a type for the input parameters because the compiler can infer the type based on the lambda body, the underlying delegate type, and other factors as described in the C# Language Specification. For most of the standard query operators, the first input is the type of the elements in the source sequence. So if you are querying an IEnumerable<Customer>, then the input variable is inferred to be a Customer object, which means you have access to its methods and properties:

customers.Where(c => c.City == "London");


The general rules for lambdas are as follows:
■The lambda must contain the same number of parameters as the delegate type.
■Each input parameter in the lambda must be implicitly convertible to its corresponding delegate parameter.
■The return value of the lambda (if any) must be implicitly convertible to the delegate's return type.

==========================================================
Variable Scope in Lambda Expressions
Lambdas can refer to outer variables that are in scope in the enclosing method or type in which the lambda is defined. Variables that are captured in this manner are stored for use in the lambda expression even if variables would otherwise go out of scope and be garbage collected. An outer variable must be definitely assigned before it can be consumed in a lambda expression. The following example demonstrates these rules:

delegate bool D();
delegate bool D2(int i);

class Test
{
    D del;
    D2 del2;
    public void TestMethod(int input)
    {
        int j = 0;
        // Initialize the delegates with lambda expressions.
        // Note access to 2 outer variables.
        // del will be invoked within this method.
        del = () => { j = 10;  return j > input; };
        // del2 will be invoked after TestMethod goes out of scope.
        del2 = (x) => {return x == j; };
     
        // Demonstrate value of j:
        // Output: j = 0
        // The delegate has not been invoked yet.
        Console.WriteLine("j = {0}", j);        // Invoke the delegate.
        bool boolResult = del();
        // Output: j = 10 b = True
        Console.WriteLine("j = {0}. b = {1}", j, boolResult);
    }
    static void Main()
    {
        Test test = new Test();
        test.TestMethod(5);
        // Prove that del2 still has a copy of
        // local variable j from TestMethod.
        bool result = test.del2(10);
        // Output: True
        Console.WriteLine(result);
          
        Console.ReadKey();
    }
}




The following rules apply to variable scope in lambda expressions:
■A variable that is captured will not be garbage-collected until the delegate that references it goes out of scope.
■Variables introduced within a lambda expression are not visible in the outer method.
■A lambda expression cannot directly capture a ref or out parameter from an enclosing method.
■A return statement in a lambda expression does not cause the enclosing method to return.
■A lambda expression cannot contain a goto statement, break statement, or continue statement
 whose target is outside the body or in the body of a contained anonymous function.

ref: http://msdn.microsoft.com/en-us/library/bb397687.aspx

2010年12月9日星期四

GridView Databinding注意事項

GridViewのデータバインディングについて、MSDNにはいろいろな例がありますが、
EIDTモード場合のバインディングは足りないと思います。
GridViewはDatatableにバインディングした後、Editモードにするのはどうすればいいか、
はっきりしていないです。

実際にはGridViewのEditIndexを設定すればOKです。
即ち、以下のソースで説明します。
Protected Sub Grid_RowEditing(ByVal sender As Object, ByVal e As GridViewEditEventArgs) _
    Handles grd.RowEditing 
   ’編集開始イベントの中で、新たな編集先行番を設定する必要です。
        grd.EditIndex= e.NewEditIndex
   '設定完了後、再びGridにDataSourceのバインディングが必要です。
        grd.DataBind()
End Sub

なお、編集キャンセルしたい場合、GridView.EditIndex=-1にリセットが必要です。
キャンセルボタンに関連することも可能です。
Protected Sub Grid_RowCancelingEdit(ByVal sender As Object, ByVal e As GridViewCancelEditEventArgs) _
    Handles grd.RowCancelingEdit
        grd.EditIndex= -1
        grd.DataBind()
    End Sub

===============
同じく、GridViewの行選択が変わりたい場合、GridView.SelectedIndexの指定が必要です。
以下例:
Protected Sub Grid_SelectedIndexChanging(ByVal sender As Object, ByVal e As GridViewSelectEventArgs)  Handles grd.SelectedIndexChanging
        grd.SelectedIndex = e.NewSelectedIndex
        grd.DataBind()
End Sub

===============

同じくGridViewの頁が変わりたい場合、GridView.PageIndexの指定が必要です。
以下例:
Protected Sub Grid_PageIndexChanging(ByVal sender As Object, ByVal e As GridViewPageEventArgs) _
    Handles grd.PageIndexChanging
        if grd.PageIndex <> e.NewPageIndex then
            grd.PageIndex = e.NewPageIndex
        End If
       grd.DataBind()
    End Sub

以上の例は皆変更しようとすると、対応Indexの設定が必要で、その後またDataBind()の再バインディングが必要です。しないと、データが表示しないです。
grdのDataSourceはGridViewのEnableViewState=trueの場合(ディフォルトはtrue)、ViewStateの保存されます、再DataSourceの指定は不要です、逆に指定したら、新たなDataSourceとして扱うことになります。

データ バインディング構文

データ バインディング式は <%# デリミタと %> デリミタの間に記述され、Eval 関数と Bind 関数を使用します。Eval 関数は、一方向 (読み取り専用) バインディングを定義するために使用します。Bind 関数は、双方向 (更新可能) バインディングに使用します。Eval メソッドと Bind メソッドを呼び出してデータ バインディング式でデータ バインディングを実行することに加えて、<%# デリミタと %> デリミタの間でパブリックにスコープされた任意のコードを呼び出して実行し、ページの処理中に値を返すことができます。
データ バインディング式は、コントロールの DataBind メソッドまたは Page クラスが呼び出されたときに解決されます。GridView、DetailsView、FormView などのコントロールでは、データ バインディング式はコントロールの PreRender イベントの中で自動的に解決されるので、DataBind メソッドを明示的に呼び出す必要はありません。
ItemTemplate の FormView コントロールと共にデータ バインディング式を使用するコード例を次に示します。

Eval メソッドの使用
Eval メソッドは、GridView、DetailsView、FormView などのデータ バインド コントロールのテンプレートの遅延バインディング データ式を評価します。Eval メソッドは、名前付けコンテナの現在のデータ項目を参照する DataBinder オブジェクトの Eval メソッドを実行時に呼び出します。名前付けコンテナは、GridView コントロールの行などのように、一般にレコード全体を含むデータ バインド コントロールの最小単位です。したがって、Eval メソッドは、データ バインド コントロールのテンプレート内のバインディングにのみ使用できます。
Eval メソッドはデータ フィールドの名前を受け取り、データ ソースの現在のレコードからそのフィールドの値を含む文字列を返します。2 番目のパラメータを指定して、返される文字列の形式を指定することもできます (省略可能)。文字列の書式指定パラメータは、String クラスの Format メソッドに対して定義された構文を使用します。
<asp:FormView ID="FormView1"
  DataSourceID="SqlDataSource1"
  DataKeyNames="ProductID"    
  RunAt="server">
                                   
  <ItemTemplate>
    <table>
      <tr><td align="right"><b>Product ID:</b></td>       <td><%# Eval("ProductID") %></td></tr>
      <tr><td align="right"><b>Product Name:</b></td>     <td><%# Eval("ProductName") %></td></tr>
      <tr><td align="right"><b>Category ID:</b></td>      <td><%# Eval("CategoryID") %></td></tr>
      <tr><td align="right"><b>Quantity Per Unit:</b></td><td><%# Eval("QuantityPerUnit") %></td></tr>
      <tr><td align="right"><b>Unit Price:</b></td>       <td><%# Eval("UnitPrice") %></td></tr>
    </table>                
  </ItemTemplate>                  
</asp:FormView>

Bind メソッドの使用
Bind メソッドは、Eval メソッドに部分的に似ていますが、重要な違いがあります。Eval メソッドと同様に、Bind メソッドを使用してもデータ バインド フィールドの値を取得できますが、Bind メソッドはデータを変更できる場合にも使用します。
ASP.NET では、GridView、DetailsView、FormView などのデータ バインド コントロールは、データ ソース コントロールの更新、削除、および挿入操作を自動的に使用します。たとえば、データ ソース コントロールに対して SQL の Select、Insert、Delete、および Update ステートメントを定義している場合、GridView、DetailsView、または FormView コントロールのテンプレートで Bind を使用すると、そのコントロールで、テンプレートの子コントロールから値を抽出してデータ ソース コントロールに渡すことができます。次に、データ ソース コントロールは、データベースに対して適切なコマンドを実行します。そのために、データ バインド コントロールの EditItemTemplate または InsertItemTemplate の内部では Bind 関数が使用されます。
Bind メソッドは、編集モードの GridView 行によってレンダリングされた TextBox コントロールなどの入力コントロールで一般的に使用されます。データ バインド コントロールは、自身のレンダリング処理の一部としてこのような入力コントロールを作成する場合、入力値を抽出できます。
Bind メソッドは、次の例に示すように、データ フィールドの名前を受け取ってバインド プロパティに関連付けます。
セキュリティに関するメモ : 
この例には、ユーザー入力を受け付けるテキスト ボックスがあるため、セキュリティ上の脅威になる可能性があります。既定では、ASP.NET Web ページは、ユーザー入力にスクリプトまたは HTML 要素が含まれていないことを検証します。詳細については、「スクリプトによる攻略の概要」を参照してください。

コピー<EditItemTemplate>
  <table>
    <tr>
      <td align=right>
        <b>Employee ID:</b>
      </td>
      <td>
        <%# Eval("EmployeeID") %>
      </td>
    </tr>
    <tr>
      <td align=right>
        <b>First Name:</b>
      </td>
      <td>
        <asp:TextBox ID="EditFirstNameTextBox" RunAt="Server"
          Text='<%# Bind("FirstName") %>' />
      </td>
    </tr>
    <tr>
      <td align=right>
        <b>Last Name:</b>
      </td>
      <td>
        <asp:TextBox ID="EditLastNameTextBox" RunAt="Server"
            Text='<%# Bind("LastName") %>'  />
      </td>
    </tr>
    <tr>
      <td colspan="2">
        <asp:LinkButton ID="UpdateButton" RunAt="server"
          Text="Update" CommandName="Update" />
        &nbsp;
        <asp:LinkButton ID="CancelUpdateButton" RunAt="server"
          Text="Cancel" CommandName="Cancel" />
      </td>
    </tr>
  </table>
</EditItemTemplate>
行の Update ボタンがクリックされると、Bind 構文を使用してバインドされた各コントロール プロパティの値が抽出され、更新操作のためにデータ ソース コントロールに渡されます。
DataBind メソッドの明示的な呼び出し
GridView、FormView、DetailsView などのコントロールは、DataSourceID プロパティを使用してデータ ソース コントロールにバインドされるときに DataBind メソッドを暗黙的に呼び出してバインディングを実行します。ただし、明示的に DataBind メソッドを呼び出す必要がある場合もあります。
そのような状況の 1 つは、DataSourceID プロパティの代わりに DataSource プロパティを使用してコントロールをデータ ソース コントロールにバインドした場合です。その場合は、明示的に DataBind メソッドを呼び出してデータ バインディングを実行し、データ バインディング式を解決する必要があります。
もう 1 つの状況は、データ バインド コントロールのデータを手動で更新する必要がある場合です。同じデータベースから情報を表示する 2 つのコントロールを含むページがあるとします。おそらく個別のビューを使用しています。この場合、データ表示の同期を維持するために明示的にデータにコントロールを再バインドする必要があります。たとえば、製品の一覧を表示する GridView コントロールおよびユーザーが製品を個々に編集するための DetailsView コントロールがあるとします。GridView コントロールと DetailsView コントロールは同じソースからデータを表示しますが、異なるクエリを使用してデータを取得しているので、別のデータ ソース コントロールにバインドされています。ユーザーが DetailsView コントロールを使用してレコードを更新すると、関連付けられているデータ ソース コントロールによって更新処理が実行されます。ただし、GridView コントロールは、別のデータ ソース コントロールにバインドされているので、ページが更新されるまで古いレコードの値が表示されます。そこで、DetailsView コントロールがデータを更新した後に、DataBind メソッドを呼び出します。これによって、<%# デリミタと %> デリミタの間のすべてのデータ バインディング式およびパブリックにスコープされたコードが再実行され、GridView コントロールのビューが更新されます。その結果、GridView コントロールに DetailsView コントロールによる更新内容が反映されます。
ルックアップ テーブルへのバインディングの使用
データ バインド コントロールは、ユーザーが DropDownList コントロールまたは他のリスト コントロールを使用し、ルックアップ テーブルから選択して値を更新または挿入できるようにする場合によく使用されます。この場合、ルックアップ コントロールは、可能な値の一覧を返す個別のデータ ソースにバインドされます。またルックアップ コントロールの選択した値は、親データ バインドの行のフィールドにバインドされます。
この機能は次の手順で追加できます。まず、ルックアップ コントロールについて、リスト コントロール (DropDownList コントロールまたは ListBox コントロール) をデータ バインド コントロール (GridView、DetailsView、FormView などの各コントロール) のテンプレートに追加します。ルックアップ コントロールの SelectedValue プロパティは、コンテナ コントロールのデータ ソースにある関連フィールドにバインドします。次に、ルックアップ コントロールの DataSourceID プロパティを、ルックアップ値を取得するデータ ソース コントロールに設定します。ルックアップ コントロールの DataTextField プロパティは、表示する値を含むルックアップ テーブルのフィールドに設定します。また、適用できる場合、DataValueField プロパティは、ルックアップ値の固有な識別子を含むルックアップ テーブルのフィールドに設定します。
次のコード例は、FormView コントロールの InsertItemTemplate テンプレートに含まれる DropDownList コントロールです (これは、DetailsView コントロールの Fields プロパティまたは GridView コントロールの Columns プロパティに含まれる、TemplateField の InsertItemTemplate テンプレートの可能性もあります)。DropDownList コントロールの SelectedValue プロパティは、Bind メソッドを使用して、FormView コントロールの現在の行の CategoryID フィールドに双方向にバインディングします。DataSourceID コントロールの DropDownList プロパティは、可能なカテゴリ名と ID の一覧を取得する個別のデータ ソース コントロールに設定されます。DropDownList コントロールの DataTextField プロパティは、可能なカテゴリ名が表示されるように、ルックアップ データ ソースの CategoryName フィールドに設定されます。DropDownList コントロールの DataValueField プロパティは、関連するカテゴリ名のルックアップ データ ソースの CategoryID フィールドに設定されます。ユーザーがリストからカテゴリ名を選択すると、DropDownList コントロールの SelectedValue プロパティは、選択したカテゴリ名のカテゴリ ID に設定されます。
VBC#C++F#JScript
コピー<tr>
  <td align="right"><b>Category:</b></td>
  <td><asp:DropDownList ID="InsertCategoryDropDownList"
                        SelectedValue='<%# Bind("CategoryID") %>'
                        DataSourceID="CategoriesDataSource"
                        DataTextField="CategoryName"
                        DataValueField="CategoryID"
                        RunAt="Server" />
  </td>
</tr>

同じリスト コントロールを編集項目のテンプレートにも使用できます。

DataSource紹介 ー概略

データ ソース コントロール  説明 
ObjectDataSource
 ビジネス オブジェクトまたはその他のクラスと共に使用し、中間層オブジェクトに依存する Web アプリケーションを作成してデータを管理します。
詳細については、「ObjectDataSource Web サーバー コントロール」を参照してください。

SqlDataSource
 Microsoft SQL Server、OLE DB、ODBC、または Oracle データベースへのアクセスを提供する ADO.NET マネージ データ プロバイダを使用できます。
詳細については、「SqlDataSource Web サーバー コントロール」を参照してください。

AccessDataSource
 Microsoft Access データベースで使用できます。
詳細については、「AccessDataSource Web サーバー コントロール」を参照してください。

XmlDataSource
 TreeView コントロール、Menu コントロールなどの階層的な ASP.NET サーバー コントロールで特に有効な XML ファイルを使用できます。
詳細については、「XmlDataSource Web サーバー コントロール」を参照してください。

SiteMapDataSource
 ASP.NET サイト ナビゲーションで使用します。詳細については、「ASP.NET サイト ナビゲーションの概要」を参照してください。

DataSource紹介 - ObjectDataSource

ObjectDataSourceは中間層ビジネス オブジェクトとして扱うのは普通です。
使う前に、対応ビジネスオブジェクトが必要です。
例:
===============
 Namespace Samples.DataSources
  Public Class TestObjectDataSource
    ' Select all employees.
    Public Function GetTestData(key as string) As DataTable
     return new DataTable
    End Function
   
    public Function Update(dt as DataTable) as Integer
     '更新
     return 0
    End Function
   
    public Function Delete(dt as DataTable) as Integer
     '削除
     return 0
    End Function
 End Class
End Namespace
===============

<html>
 <asp:ObjectDataSource
        ID="TestObjectDataSource1"
        runat="server"
        TypeName="Samples.DataSources.TestObjectDataSource"
        EnablePaging="true"
        SelectCountMethod="SelectCount"
        StartRowIndexParameterName="StartRecord"
        MaximumRowsParameterName="MaxRecords"
        SelectMethod="GetTestData" >
      </asp:ObjectDataSource>
 <asp:GridView ID="EmployeesGridView"
              DataSourceID="TestObjectDataSource1" >
 </asp:GridView>
</html>

2010年12月8日星期三

组织的力量

成大事者必然存在于某个组织,脱离了组织,个人什么都不是。
个人在组织中的位置越高,影响力就越强,个人可以发挥能力就越强。

组织的力量,取决于领导的能力。
领导代表权利,更代表义务。

如何成为领导,首先考虑成为组织的一员,成为组织成员的目的是什么。
健康的组织,像阳光普照每一个角落。
作为一名新人,如何最快速的成为组织中的领头羊,是学习的意识和能力。

新闻-中国民间发明家发明致穷-读后感

从网上看到的[民间发明家发明致穷]这篇报道, 让我突发奇想,从这篇报道里,
我看到了一个项目。

1 是否能够将专利统一管理,建立市场,公开销售/竞售。
2 如何收集专利,与发明人取得联系并长期合作。
3 如何鉴别专利的真假。
4 如何评价专利的市场价值。
5 如何调节专利提供者与需求者之间的关系。
6 是否能够提供一种先有需求后搞发明的服务模式。
7 是否有启动资金,启动平台,是否有时间。
8 是否能够找到总负责本项目的合适人选,及其他相关角色的人选。
9 如何能让思想不半途而废。


新闻提到了美国日本的发明专利转化率高达80%,中国的不到5%.
说明一个严重的问题是国家的发明专利机构不作为,只负责登记,其他一概不问。
我们是否能够模拟专利组织,处理所有专利组织不作为的部分,
就是评估专利,专利推广等上面提到的问题。

题外话:
金融业: 支付宝虽然不是银行,却做到了银行的本质。
物流业: 已经不再是邮局的天下。
那么还有哪些衙门还有哪些地方不作为,可以为我们小老百姓创造就业机会的呢。
本人联系方式lqwangxg@gmail.com. 对讨论创业感兴趣的,可以做个朋友。
———————————————————————————————————
机会就在每一天。

2010年12月1日星期三

.net Control継承にToolboxBitmap利用

VS IDE(VS2008等)の Toolboxに既存しているControlを継承して、新たなControlを作る時に、
継承ControlのBitmapはディフォルトの◎で表示されています。
親のBitmapを表示させる方法があります。
以下例のようにToolboxBitmapの属性を使えば簡単にできる:
C#
[ToolboxBitmap(typeof(TextBox))]
public class CurrencyTextBox : TextBox, IScriptControl, IValidator, IIsRequired
{
...
}

=============================================
VB.net
<ToolboxBitmap(GetType(TextBox))> _
Public Class CurrencyTextBox
    Inherits TextBox
    Implements IScriptControl, IValidator, IIsRequired
 ...
End Class

2010年11月30日星期二

VB.Net UserControlにEventを追加する。

UserControlは複数の子Controlを組み込んで新たなUserControlを作ることです。
例えば、Label,TextBoxとButtonの三つControlを組み込んで、InputPanelを作ります。
TextBoxに入力する内容をButtonクリックよりMessgeBoxで表示する。
この場合、
① UserControlを新規作ります。
② Label,TextBoxとButtonの三つControlを追加します。
③ UserControlはControlから継承なので、ButtonのようなClickイベントがありませんが、
  Clickイベントを発生させるため、追加します。
  追加内容は
  1、Event Clickを宣言します。
  2、該当UserControl所属するButtonがクリックされる時点で、UserControlのClickとして、処理を走ります。
  
  追加ソース例:
  Public Event Click As EventHandler
    Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
        RaiseEvent Click(sender, e)
    End Sub
    注意点:UserControの使い画面にはUserControl.Clickイベントに対する処理Subが存在しなくても、RaiseEventで問題ありません。

2010年11月29日星期一

净化思想的两幅对联

————————————————
花繁柳密处拨得开,方见手段
风狂雨骤时立得定,才是脚跟
————————————————

每当遇到困惑时,可以想想自己的手段是否够严密老辣。

每当遇到抉择时,可以想想自己的脚跟是否够稳固持久。

————————————————
做好人,自当有正大光明之气象
成大事,不可无勤勉谨慎之功夫
————————————————

不可因小恶而为之,不可因小善而不为。
不为恶是义务,不为善是权利。
义务要遵守,同时善举也要做。

成事在天谋事在人,所以一定要勤勉谨慎。

2010年11月26日星期五

自定义HttpModule遇到的问题 解答Shadow和OverLoads及Overrides的区别

自定义的IHttpModule孙子CustomModule没有被Load的问题,搞清楚了。
其实并不是没有被Load,而是没有VB.net的语法问题,导致的执行BaseHttpModule的方法,而不是孙子CustomModule的方法。
具体情况是:
————————————————
类层次:
BaseHttpModule
   Implements IHttpModule
  ————————————————
CustomModule
   Inherits BaseHttpModule
————————————————
BaseHttpModule中的Init(context As HttpApplication)是Overridable的,
在子类CustomModule中可以被Overrides的。
刚开始没有注意到这个Overridable,简单写成了OverLoads才出的问题。
还改成了Shadow,结果也不行,最后才注意到这个Overridable。

顺便说一下,Shadow和OverLoads及Overrides的区别。
Overrides :通过Interface和具体类型名生成实体后,调用其方法的时候,实际调用的是最底层的实现逻辑。有时候在方法的开头会加上
例如MyBase.Init(context)
这样一句,目的是基类逻辑执行完之后,在执行自己的具体逻辑。

Shadow    通过Interface和具体类型名生成实体后,调用其方法的时候,实际调用的是最上层类的实现逻辑。底层的都被隐藏掉了。所以一般少用。

OverLoads    原意是重载。同一类中方法重载可以省略OverLoads,但是父子类中方法的重载,必须加上OverLoads。同参数的重载也是可以的,但是通过Inteface来调用的时候,只会调用上层的方法,类似于Shadow,底层的被隐藏了。想不被隐藏,还是得用Overrides明确。

自定义HttpModule遇到的问题

自定义HttpModule 继承自IHttpModule,
基本条件,实现其中的Init(HttpApplication app), Dispose()就可以了。
如果需要抓错,可以重写OnError。

由于HttpModule拦截处理的是Application级别的内容,
所以,Application范围内的任何内容都可以被过滤处理一遍。
比如想将所有的Request.Form中的内容都打出来,
就可以在Init方法中通过遍历app.Request.Form实现。
实现好的CustomModule需要加到Web.Config中的HttpModule段中,
这样下一次Application启动的时候,才会被调用的。
要注意的是,IIS7之后,单独在Web.Config中写也不会被Load,还要在IIS7中的Module管理中
追加这个自定义的Module。
<add name="ConstomModule"  type="Wxg.Web.ConstomModule, Wxg.Web"/>
type的值是[类型名称 + ,+ Assembly名称], Assembly名称就是*.dll或*.exe的*名称。


今天遇到了一个想不通的问题,我想在CustomModule和IHttpModule中间加一层BaseHttpModule,
目的是为了出一些Module级别的共通性Log。 CustomModule 从IHttpModule的儿子,降级成孙子之后,在Web.Config中将孙子配好了,却不被Load。
等调查清楚了再追加说明吧。

浏览器地址栏显示自定义图标

以为很难的问题,明白了,才知道就一句话的事。
IE7开始支持自定义图标,其他的主流浏览器也基本都支持。

方法是,在html头部加上一个
<link rel=”shortcut icon” href="sample.ico" />
おしまい。

2010年11月24日星期三

ReplaceHelper and FileReplacer's ReadMe.

ReplaceHelper and FileReplacer's ReadMe.
ReplaceHelper and FileReplacer is Written by WANGXG on 2010.
They are Regex Replace tool, and the main functions is below.
Functions
① Regex's Matches, Show the MatchCollection Results in a tree.
   tree structure:
   +Match
   |    |--Group
   |            |--Capture[index, length]1
   |            |--Capture[index, length]1
   |-----
   |    |--Group
   |            |--Capture[index, length]1
   +Match
   |    |--Group
   |            |--Capture[index, length]1
  
② Replace By Group Index under conditions.
   e.g.
   input:[ ZIP:001002, TEL:009-0032-3232 ] AND [ ZIP:001002, TEL:009-0022-3232 ]
   replace[ZIP:XXXXXX] to ZIP:002XXX, and replace[TEL:XX9-XXXX-XXXX] to [PHONE:XX3-XXXX-XXXX],
   conditions: Only ZIP:XXX0XX AND NOT TEL:009-003X-XXXX will be replaced.
   the replace systex is :
    <item>
     <pattern>
      <![CDATA[
   ZIP:([\d]{3})[\d]+,\s*(TEL):\d\d(\d)-[\d-]+
  ]]></pattern>
  <replace group="1"><![CDATA[
          002
  ]]></replace>
  <replace group="2"><![CDATA[
          PHONE
  ]]></replace>
  <replace group="3"><![CDATA[
          8
  ]]></replace>
  <do><![CDATA[
   ZIP:([\d]{3})0[\d]{2},\s*(TEL):\d\d(\d)-[\d-]+
  ]]></do>
  <undo><![CDATA[
   ZIP:[\d]+,\s*(TEL):009-002[\d-]+
  ]]></undo>
    </item>
③ For Replace a text file and replace patterns by name, with the next XML format:
 <?xml version="1.0" encoding="utf-8" ?>
 <replaces>
     <replace name="DeleteRemarksComment">
         <item>
             <pattern>
                 <![CDATA[\s*'''\s*\<remarks\>\s*\<\/remarks\>]]>
             </pattern>
             <replace group="0"><![CDATA[]]></replace>
         </item>
     </replace>
     <replace name="AspControl2CustomControl">
         <item>
             <pattern>
                 (asp:)\w+
             </pattern>
             <replace group="1"> sct:Custom </replace>
         </item>
     </replace>
 </replaces>

④ For different xmls:
 <?xml version="1.0" encoding="utf-8" ?>
 <replaces>
   <replace file="SubReplace2.xml"/>
     <replace file="SimplifyTextBox.xml"/>
     <replace file="InsertResource.xml"/>
    </replaces>
  
⑤ Add Systex with:
 [$WORDS$]: use WORDS to replace
 <$KEY$>  : use dictionary[KEY] to replace.
 {GROUPINDEX}: use Match.Group[GROUPINDEX]  to replace.

WINDOWS2008R2(64bit) + IIS7.5 +VB.Net3.5 + Oracle11g64bit WebApp発行問題解決策

誤解しないように:
①WINDOWS2008R2は64bitだけ提供していますが、64bitを明確に記述します。
②IIS7.5には.NetFrameworkの選択は.net2.0だけですが(.net3.5や.net4.0が選択できません)、
 正しいです。.net3.5/4.0は.net2.0をベースとして追加したライブですので、
 .net3.5をインストールしたら、.netFramework2.0のもとで動けます。
IIS7.5で発行時の「問題・原因・解決策」
①問題:Web.Configに <authentication mode="Windows"/>の記述で、Machine.configに上書きできません。
 原因:該当WebAppはIISManager中でApplicationに変換していませんでした。
 解決方法:IISManagerで仮ディレクトリに設定し、DefaultWebSiteではなく、独立のWebAppにする。
②問題:IISのLog確認より、HTTP302エラーが発生、アクセス権限が不足。
 原因:IIS_USERSからWebApp所在Directoryにアクセス権限なし。
 解決方法:WebApp所在Directoryの属性よりIIS_USERSのアクセス権限を追加する。
③問題:Application Start途中でエラーが発生、http500エラー。
 原因:Web.ConfigのHttpModuleにカスタマイズモジュールをAddしましたが、IIS7.5の「モジュール」管理には追加しません。
    IIS7.5のモジュール管理にはディフォルトはScriptModuleだけがLocalとして追加されています。
 解決方法:Web.configのHttpModuleに記述されたModuleを全部IIS7.5の「モジュール」管理に追加する。
④問題:発行環境と開発環境のODPバージョンが不一致、DBProvider見つかりません、または読み込めません。
    DBFactorys.GetFactory(providername)の行からエラーがthrowされました。
    発行環境IIS7.5で、ORACLEサーバは11g(64.bit), ODPは2.112.2.0
    開発環境ORACLE11gClient(32bit) ODPは2.112.2.2
 原因:IIS7.5の使っている.netFrameworkの環境はC:\windows\Microsoft.net\Framework64\Config\machine.config
    Not:                                   C:\windows\Microsoft.net\Framework\Config\machine.config
    IIS7.5 は64bitのODP2.112.2.2を読込もうとしてますが、見つからないため、エラーが出る。
 解決方法:32bitのODPVer2.112.2.2をサーバにインストールして、
    IISのApplicationPoolsの属性「enable 32 bit applications]をtrueに設定する。32bitのAPPをWOW64として実行する。
    ちなみにOTNに探したが、Ver2.112.2.2(64bit)のODPがありません。
以上で、環境がやっとできました。他のPCで発行のURLでアクセスしてみた結果OKでした。

2010年11月19日星期五

Log4net.config

the steps to let Log4Net run in ASP.Net 1.1 are:
  1. writing config section for Log4Net in web.config file
  2. insert logging code in conponents and web page code-behind
  3. At website's AssemblyInfo.cs or .vb file, add "<Assembly: log4net.Config.DOMConfigurator(Watch:=True)>" for VB.net or "[assembly: log4net.Config.XmlConfigurator(Watch=true)]" for C# to enable Log4Net to Log stuffs.
  4. compile the web application and run.
By searching and refering the posts here and here and here, comes out that the configuration way in ASP.NET 2.0 is little bit different, as follows:
  1. writing config section for Log4Net in web.config file
  2. insert logging code in conponents and web page code-behind
  3. At Global.asax file, under Application_Start event, add "log4net.Config.XmlConfigurator.Configure()" to trigger Log4Net to log stuffs.
  4. compile the web application and run.
By doing the settings above, Log4Net started to output logs in my ASP.Net 2.0 application.

2010年11月18日星期四

PowerShell概要

PowerShellはWSHの替わりものであります。
WSHの利用できる言語はVBScript,Javascriptですが、もうすでに.net時代なので、この二つのScriptはなかなか古い感じられ、さっさとOS管理用のScriptも昇級しよう。

PowerShellの特徴:
  • 豊富に用意された高機能なコマンド(「コマンドレット」
  • 「.NET Frameworkクラス・ライブラリ」との連携(.net Framework2.0必須)
  • 「ドライバ」経由でさまざまなデータストアへのアクセスが可能
これで、.netに上手な管理者たちは楽になるでしょう。

PowerShell2.0はWINDOW2008R2とWINDOWS7からOSに含まれています。
この前のバージョンのOS(WINXPまで)には使いたければ、先に.netframework2.0のインストールが必要です。それから、PowerShellをOSに対応するバージョンをインストールする。

PowerShellを利用するに当たって、何はおいても、まず「コマンドレット(Cmdlet)」の理解は欠かせない。コマンドレットとは、要は、PowerShellで利用可能なコマンドのことである。
標準で129種類にも及ぶコマンドレットが提供されており、これらコマンドレットを組み合わせることで、従来、コマンド・プロンプトやWSHでは実現できなかった(もしくは困難であった)処理を限りなく短いコードで実現することができる。

まずPowerShellで利用可能なコマンドレットをざっと確認してみることにしよう。利用可能なコマンドレットの一覧を取得するのはGet-Commandコマンドレットの役割だ。Get-Commandコマンドレットを利用することで、名前(Name)、構文(Definition)などを確認することができる。

詳細情報の確認にはGet-Helpコマンドレットを使う。
コマンドレットの末尾に「-?」オプションを付けてもよい
PowerShellでは、主要なコマンドレットに対してエイリアス(別名)を提供します。
例えば、カレント・フォルダ配下の情報を取得するためのGet-ChildItemコマンドレット――これはエイリアスを利用することで、以下のように書き換えることも可能だ。
例:
Set-Alias remove Remove-Item
意味はPowerShell中のファイル削除命令の Remove-Item をremoveに別名つけて、
PowerShell中でCMD中のようにファイル削除命令removeが使えることにした。

Get-Aliasにより現在の別名リスをを表示できます。

基本は命令キーワードにより実行するものですが、一行不足の場合、改行継続は”|”で使う。
例:
PS > Get-ChildItem |
>> Where-Object {$_.LastWriteTime -lt (Get-Date).AddMonths(-6)} |
>> ForEach-Object {$_.Delete()}

Get-ChildItemはCurrentDirectory下のファイルをリストする。|で改行
Where-Objectで最新書き込み時間は6ヶ月以内の条件をつける。
For-Each-ObjectでLOOPして結果を$_.Delete()で削除する。

PowerShellは変数のタイプがあります。


エイリアス .NET Frameworkの型名
byteSystem.Byte
intSystem.Int32
longSystem.Int64
single、floatSystem.Single
doubleSystem.Double
decimalSystem.Decimal
charSystem.Char
boolSystem.Boolean
stringSystem.String
array/td> System.Array
xmlSystem.Xml.XmlDocument
typeSystem.Type

特別なCHARもあります。

エスケープ・シーケンス概要
`bバックスペース
`n改行
`rキャリッジ・リターン
`tタブ

つまり、PowerShellは前と違って、.netFramework baseの高級Scriptである。

==========================================================
WINDOWS2008R2のServerCoreを最小インストールする場合は、
PowerShellと.NetFramework2.0が使えないですが。以下のコマンドで起動できます。
start /w ocsetup NetFx2-ServerCore
start /w ocsetup MicrosoftWindowsPowerShell

PowerShellを起動するには
start C:\Windows\System32\WindowsPowerShell\v1.0\PowerShell.exe
とします。

netコマンドの使い方

netコマンドは、Microsoft Windowsネットワークにおいて、ネットワーク関係の設定を行ったり、現在の状態を表示させたりするために使われるコマンドである。

クライアントOSの主流がMS-DOSからWindows環境に移るにつれ、ほとんどのネットワーク機能はWindows上からGUIベースで管理できるようになったが、同時にコマンド版の管理ツールであるnetコマンドの強化も継続して行われているので、必要に応じて使い分けるとよいだろう。特に、リモートからTelnetなどでログオンしてネットワークのトラブルシューティングを行うためには、このようなコマンドラインのツールはぜひとも使いこなせるようになっておきたい。

netコマンドには数多くのサブコマンドがあり、実際に利用する場合は、いずれかのサブコマンド名とそれに対するパラメータ類を続けて指定する必要がある。netコマンドだけを単独で起動すると(このコマンドの実体は%windir%\system32\net.exe。Windows 9x/Meの場合は%windir%\net.exe)、サブコマンドの一覧が表示される。

2010年11月17日星期三

IIS での HTTP 401 エラーのトラブルシューティング

トラブルシューティングの手順
HTTP 401 エラーのサブステータス コードを識別します。
サブ状態コードを識別する一般的な 2 つの方法があります。
サブステータス コードから IIS 6. 0 では、Web ログに記録です。 Web ログは、次の場所にあります。
%SYSTEMROOT%\System32\LogFiles\W3SVC###\
HTTP 401. 1: が無効なユーザーの資格情報によって拒否されました。
説明

IIS はユーザーの要求を実行するログオンできませんでした。 すべての要求は、要求が匿名場合でも、ユーザーに関連付けられたでなければなりません。

一般的な理由
  • 間違ったユーザー名またはパスワードが提供されます。 ログオンに失敗しましたしたユーザーを特定し、ユーザー名またはパスワードの修正します。
  • Kerberos 認証は失敗します。 関連情報を参照するには、以下の「サポート技術情報」 (Microsoft Knowledge Base) をクリックしてください:
    326985  (http://support.microsoft.com/kb/326985/ ) IIS での問題の Kerberos 関連のトラブルシューティング方法
    ほかにも便利な Kerberos 記事次のとおりです。
    871179  (http://support.microsoft.com/kb/871179/ ) 受信した、"HTTP エラー 401. 1 - 権限: 無効な資格情報によりアクセスが拒否されました"エラー メッセージ IIS 6.0 アプリケーション プールの一部である Web site をアクセスするとき
    IIS 6. 0 (IIS 6. 0) を持つアプリケーション プール ID を構成します。
    http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/f05a7c2b-36b0-4b6e-ac7c-662700081f25.mspx (http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/f05a7c2b-36b0-4b6e-ac7c-662700081f25.mspx)

    統合 Windows 認証 (IIS 6. 0)
    http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/523ae943-5e6a-4200-9103-9808baa00157.mspx (http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/523ae943-5e6a-4200-9103-9808baa00157.mspx)

    (IIS 6. 0) の Kerberos の制約付き委任を構成します。
    http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/df979570-81f6-4586-83c6-676bb005b13e.mspx (http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/df979570-81f6-4586-83c6-676bb005b13e.mspx)
  • ローカルまたはドメイン ポリシーまたはユーザー権利の割り当て、ユーザーを防ぎますサーバーへのアクセスします。 サーバーはログオンの失敗を監査するには構成されている場合、セキュリティ ログに詳細可能性があります。 必要なユーザー権利は、次の資料を参照します。
    812614  (http://support.microsoft.com/kb/812614/ ) IIS 6.0 でのデフォルトのアクセス許可とユーザー権利
    271071  (http://support.microsoft.com/kb/271071/ ) IIS 5.0 Web サーバーに必要な NTFS アクセス許可とユーザー権利の設定方法
    832981  (http://support.microsoft.com/kb/832981/ ) ユーザーのセキュリティ イベント ログがいっぱいになったら Web サイトにアクセスできません。
    300549  (http://support.microsoft.com/kb/300549/ ) 有効にし、Windows 2000 のセキュリティ監査を適用する方法
  • このエラーは匿名アクセスが構成されている場合にも発生する可能性があります。 これは、ユーザー名または IIS メタベースに格納されている匿名アカウントに対してパスワード、ドメイン アカウントを使用する場合、ローカル ユーザー データベース (または、Active Directory ディレクトリ サービス) に格納された実績情報と異なる場合に発生します。 この問題を解決して IIS アカウントのパスワードをリセットします。
  • IIS 5. 0 を IIS 6. 0 を実行するサーバーをアップグレードした後は IIS は IIS 5. 0 互換モードで実行してください。 サーバーが IIS に切り替えられると 6. 0 分離モード、匿名の要求に対して HTTP 401. 1 エラーが表示されます。 これは IIS 5. 0 匿名パスワード同期の原因発生します。 この問題を解決をするには AnonymousPasswordSync メタベース キーを false に設定して、アカウントを IIS の匿名ユーザーのパスワードをリセットします。
  • このエラーに関するについては、記事の「サポート技術情報」(Microsoft Knowledge Base) を表示する次の資料番号をクリックしてします。
    896861  (http://support.microsoft.com/kb/896861/ ) 統合認証を使用して、IIS 5. 1 または IIS 6 でホストされている Web サイトを参照するとエラー 401. 1 を受信します。
    304201  (http://support.microsoft.com/kb/304201/ ) できないアクセス Web サイトまたは IIS を起動できないサービスを非ローカル システム アカウントと IIS と Windows 認証を使用して実行
    263140  (http://support.microsoft.com/kb/263140/ ) 匿名および基本認証ドメイン コントローラー上で IIS 5. 0 に接続するときの失敗します。
HTTP 401. 2: サーバーの構成によっては拒否されました
説明

クライアントのブラウザーと IIS でした認証プロトコルに一致しません。

一般的な理由
  • IIS での認証プロトコルの (匿名を含む) が選択されていません。 少なくとも 1 つの認証の種類選択してください。 関連情報を参照するには、以下の「サポート技術情報」 (Microsoft Knowledge Base) をクリックしてください:
    253667  (http://support.microsoft.com/kb/253667/ ) エラー メッセージ: HTTP 401. 2 - 権限: 認証なしのサーバーの構成のため、ログオンに失敗しました
  • 統合認証のみを有効にし、それ以前]、非 - クライアント ブラウザーが、サイトにアクセスします。 これはクライアントのブラウザーに統合認証を実行できないためです。 この問題を解決をするには、次の方法のいずれかを使用します。
    • 基本認証を受け入れる IIS を構成します。 これはだけ発生 SSL 経由でセキュリティを確保するため。
    • 統合認証を実行できるクライアント ブラウザーを使用します。 Internet Explorer および Netscape ナビゲーターと Mozilla Firefox の新しいバージョンには、統合認証を実行できます。
  • 統合認証は、プロキシを経由します。 これは、プロキシ、NTLM 認証された接続を維持しないし、したがって、クライアントからサーバーに匿名の要求を送信するためです。 この問題を解決するオプションは次のとおりです。
    • 基本認証を受け入れる IIS を構成します。 これはだけ発生 SSL 経由でセキュリティを確保するため。
    • プロキシを使用しないでください。
リソースの ACL によって HTTP 401.3: が拒否されました
説明

このエラーは、ユーザーは、サーバーに正常に認証が、ユーザーが要求されたコンテンツに NTFS アクセス許可を持たない場合に返されます。

一般的なソリューション
  • コンテンツに NTFS アクセス許可を正しく設定します。 以下の資料の「NTFS のアクセス許可] を確認します。
    812614  (http://support.microsoft.com/kb/812614/ ) IIS 6.0 でのデフォルトのアクセス許可とユーザー権利
    271071  (http://support.microsoft.com/kb/271071/ ) IIS 5.0 Web サーバーに必要な NTFS アクセス許可とユーザー権利の設定方法
  • 適切な認証方法が設定されるされている確認します。 たとえば、統合認証を使用してユーザーが認証の資格情報のように求めされません。 この場合は、明確でないか、要求が認証する場合があります。
  • コンテンツがリモート共有上にある場合、は、ユーザーが十分な NTFS および共有のアクセス許可でことを確認します。 関連情報を参照するには、以下の「サポート技術情報」 (Microsoft Knowledge Base) をクリックしてください:
    332142  (http://support.microsoft.com/kb/332142/ ) UNC 共有のコンテンツに対して NTLM 要求を行うと 401 エラー メッセージが表示される
HTTP 401.4: がカスタムの ISAPI フィルターによって拒否されました
説明

読み込まれた ISAPI フィルターには、要求拒否しました。

ソリューション

ISAPI フィルターは、要求を拒否を識別し、ソリューションを決定する開発者またはベンダーに連絡します。
カスタムの ISAPI または CGI Web アプリケーションで HTTP 401.5: が拒否されました
説明

ISAPI 拡張機能または CGI アプリケーション要求を拒否しました。

ソリューション

どの ISAPI 拡張機能または CGI アプリケーションは、要求を拒否を識別し、ソリューションを決定する開発者またはベンダーに連絡します。

結果

要約すると、HTTP 401 エラーをトラブルシューティングするときは、まずは常になりますサブステータス コードを確認します。
  • 401. 1: 認証が、試行しますが、失敗しました。
  • 401. 2: サーバーとクライアントでした認証プロトコルに同意できないため、認証が行われません。
  • 401.3: 認証が成功したがアカウントを認証には、要求されたリソースまたはコンテンツにアクセスする権限がありません。
  • 401.4: ISAPI フィルターは、要求を拒否します。
  • 401.5: ISAPI 拡張機能または CGI アプリケーションは、要求を拒否します。

IIS6.0 WebApplication Publish

開発環境: VS2008, Ajax3.5
発行環境:Windows XP IIS6.0

発行手順:
① VS2008でサンプルのWebApplication2を作成して、コンパイルする。

② VS2008でWebApplication2のプロジェクトを選択して、右クリック→発行→

 ③発行画面で発行パスを設定する。
注意:コピー内容について、基本は実行に必要なファイルのみですが、場合により変わります。

④ 発行先のフォルダにNETWORK SERVICEのアクセス権限を渡す。
これがアクセスできるの第一歩です。

⑤IISの配置、仮想ディレクトリを作成する。途中は全部ディフォルトでOKです。



⑥下図はディフォルト設定です。ディレクトリの参照を選択しない場合、アクセスフォルダ下に
default頁が見つからない場合、FileListしません、アクセスエラーの画面を表示する。

以上は簡単なIIS6.0の設定手順で。
上図のASP.NET Tabには.netframeworkのバージョン設定があります。
バージョン不一致のエラーが発生する場合、そこで調整ができます。

IIS7 Web.Config Security Filter Set

1 Filter Based on URL Sequences禁止输入URL直接访问WEB画面

<configuration>
<system.webServer>
<security>
<requestfiltering>
<denyurlsequences>
<add sequence=".."/>
</denyUrlSequences>
</requestFiltering>
</security>
</system.webServer>
</configuration>

2 Filter by Verbs 过滤访问动词,例如只允许Get方法的访问。

<configuration>
<system.webServer>
<security>
<requestfiltering>
<verbs allowUnlisted="false">
<add verb="GET" allowed="true" />
</verbs>
</requestFiltering>
</security>
</system.webServer>
</configuration>

3 Filter Based on Request Limits.对Request的过滤。
包括Request总长度,URL长度,查询字符串的长度。

<configuration>
<system.webServer>
<security>
<requestfiltering>
<requestLimits
       maxAllowedContentLength="30000000"
       maxUrl="260"
       maxQueryString="25" />
</requestFiltering>
</security>
</system.webServer>
</configuration>

4 Filter Based on File Extensions 过滤访问文件的后缀名。
例如禁止.asp,.xml的访问.

<configuration>
<system.webServer>
<security>
<requestfiltering>
<fileextensions allowUnlisted="true" >
<add fileExtension=".asp" allowed="false"/>
<add fileExtension=".xml" allowed="false"/>
</fileExtensions>
</requestFiltering>
</security>
</system.webServer>
</configuration>

5 Filter High Bit Characters 禁止包含非ASCII码的Request访问。

<configuration>
<system.webServer>
<security>
<requestFiltering allowHighBitCharacters="true" />
</security>
</system.webServer>
</configuration> 

6 Filter Out Hidden Segments禁止访问子目录下的部分目录
例 有http://test.com/A, http://test.com/B两个目录,只想A被访问。

<configuration>
<system.webServer>
<security>
<requestfiltering>
<hiddensegments>
<add segment="A"/>
</hiddenSegments>
</requestFiltering>
</security>
</system.webServer>
</configuration>

7 Filter Double-Encoded Requests 过滤二次编码的请求,回避二次编码攻击。

<configuration>
<system.webServer>
<security>
<requestFiltering
                  allowDoubleEscaping="false">
</requestFiltering>
</security>
</system.webServer>
</configuration>

什么是二次编码请求攻击, 将在下一篇详细说明。

cacls简介:ACL(Access Control Entry即[文件/目录]访问控制入口)的CUI工具

cacls是NTFS文件系统的命令行访问控制工具。
具体的使用方法可以在CMD下通过cacls查看帮助。
常用的有:
1 授予[用户/组],[文件/目录]权限

'授予users组 系统目录system32下所有dll r读权限
cacls "%SystemRoot%/system32/*.dll" /g users:r /e
'授予users组 系统目录/临时文件夹 c变更权限
cacls "%SystemRoot%/Temp" /g users:c /e

2 删除[用户/组],[文件/目录]权限
'删除users组 系统目录/system 访问权限
cacls "%SystemRoot%/system" /r "users" /e
'删除everyone组 系统目录/驱动文件夹 访问权限
cacls "%SystemDrive%" /r "everyone" /e

アクセス権: N なし
W 書き込み
R 読み取り
C 変更 (書き込み)
F フル コントロール

IIS 6.0 的默认权限和用户权限[FROM MSDN]

下表记录了 NTFS 文件系统权限、注册表权限和 Microsoft Windows 用户权限。此信息在安装套件中包含 Microsoft ASP.NET 时适用。本文重点关注 World Wide Web 发布服务,并不考虑文件传输协议 (FTP) 服务、简单邮件传输协议 (SMTP) 服务和 Microsoft FrontPage Server Extensions (FPSE) 等其他组件。

注意:为便于说明,本文档中的 IUSR_MachineName 帐户和配置的匿名帐户在使用时可以互换。



NTFS 权限


目录用户\组权限
%windir%\help\iishelp\commonAdministrators完全控制
%windir%\help\iishelp\commonSystem完全控制
%windir%\help\iishelp\commonIIS_WPG读取、执行
%windir%\help\iishelp\commonUsers(请参见“注意 1”。)读取、执行
%windir%\IIS Temporary Compressed FilesAdministrators完全控制
%windir%\IIS Temporary Compressed FilesSystem完全控制
%windir%\IIS Temporary Compressed FilesIIS_WPG完全控制
%windir%\IIS Temporary Compressed FilesCreator owner完全控制
%windir%\system32\inetsrvAdministrators完全控制
%windir%\system32\inetsrvSystem完全控制
%windir%\system32\inetsrvUsers读取、执行
%windir%\system32\inetsrv\*.vbsAdministrators完全控制
%windir%\system32\inetsrv\ASP compiled templatesAdministrators完全控制
%windir%\system32\inetsrv\ASP compiled templatesIIS_WPG完全控制
%windir%\system32\inetsrv\HistoryAdministrators完全控制
%windir%\system32\inetsrv\HistorySystem完全控制
%windir%\system32\LogfilesAdministrators完全控制
%windir%\system32\inetsrv\metabackAdministrators完全控制
%windir%\system32\inetsrv\metabackSystem完全控制
Inetpub\AdminscriptsAdministrators完全控制
Inetpub\wwwroot(或内容目录)Administrators完全控制
Inetpub\wwwroot(或内容目录)System完全控制
Inetpub\wwwroot(或内容目录)IIS_WPG读取、执行
Inetpub\wwwroot(或内容目录)IUSR_MachineName读取、执行
Inetpub\wwwroot(或内容目录)ASPNET(请参见“注意 2”。)读取、执行
注意 1:在使用基本身份验证或集成身份验证时以及在配置自定义错误时,都必须对此目录拥有相应的权限。例如,在出现错误 401.1 时,只有向已登录用户授予了读取 4011.htm 文件的权限,该用户才会看到预期的自定义错误详细信息。

注意 2:默认情况下,IIS 5.0 隔离模式中使用 ASP.NET 作为 ASP.NET 进程标识。如果将 ASP.NET 切换到 IIS 5.0 隔离模式,则 ASP.NET 必须对内容区域具有访问权限。IIS 帮助中对 ASP.NET 进程隔离进行了详细说明。有关其他信息,请访问下面的 Microsoft 网站:

ASP.NET 进程隔离
http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/e409289d-2786-4a34-bb7e-9c546602c2c8.mspx (http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/e409289d-2786-4a34-bb7e-9c546602c2c8.mspx)
(可能为英文网页)


注册表权限


收起该表格展开该表格
位置用户\组权限
HKLM\System\CurrentControlSet\Services\ASPAdministrators完全控制
HKLM\System\CurrentControlSet\Services\ASPSystem完全控制
HKLM\System\CurrentControlSet\Services\ASPIIS_WPG读取
HKLM\System\CurrentControlSet\Services\HTTPAdministrators完全控制
HKLM\System\CurrentControlSet\Services\HTTPSystem完全控制
HKLM\System\CurrentControlSet\Services\HTTPIIS_WPG读取
HKLM\System\CurrentControlSet\Services\IISAdminAdministrators完全控制
HKLM\System\CurrentControlSet\Services\IISAdminSystem完全控制
HKLM\System\CurrentControlSet\Services\IISAdminIIS_WPG读取
HKLM\System\CurrentControlSet\Services\w3svcAdministrators完全控制
HKLM\System\CurrentControlSet\Services\w3svcSystem完全控制
HKLM\System\CurrentControlSet\Services\w3svcIIS_WPG读取


Windows 用户权限


收起该表格展开该表格
策略Users
从网络访问此计算机Administrators
从网络访问此计算机ASPNET
从网络访问此计算机IUSR_MachineName
从网络访问此计算机IWAM_MachineName
从网络访问此计算机Users
调整进程内存配额Administrators
调整进程内存配额IWAM_MachineName
调整进程内存配额Local service
调整进程内存配额Network service
跳过遍历检查IIS_WPG
允许本地登录(请参见“注意”)Administrators
允许本地登录(请参见“注意”)IUSR_MachineName
拒绝本地登录ASPNET
在身份验证之后模拟客户端Administrators
在身份验证之后模拟客户端ASPNET
在身份验证之后模拟客户端IIS_WPG
在身份验证之后模拟客户端Service
作为批处理作业登录ASPNET
作为批处理作业登录IIS_WPG
作为批处理作业登录IUSR_MachineName
作为批处理作业登录IWAM_MachineName
作为批处理作业登录Local service
作为服务登录ASPNET
作为服务登录Network service
替换进程级别令牌IWAM_MachineName
替换进程级别令牌Local service
替换进程级别令牌Network service

注意:在以默认设置全新安装的带有 IIS 6.0 的 Microsoft Windows Server 2003 中,Users 组和 Everyone 组都拥有“跳过遍历检查”权限。工作进程标识通过这两个组当中的一个继承“跳过遍历检查”权限。如果从“跳过遍历检查”权限中删除这两个组,工作进程标识将不会通过任何其他分配继承“跳过遍历检查”权限,因此工作进程将无法启动。如果必须从“跳过遍历检查”权限中删除 Users 组和 Everyone 组,请添加 IIS_WPG 组以允许 IIS 按预期方式运行。

注意:在 IIS 6.0 中,如果将基本身份验证配置为身份验证选项之一,则基本身份验证的 LogonMethod 元数据库属性将为 NETWORK_CLEARTEXT。NETWORK_CLEARTEXT 登录类型不需要“允许本地登录”用户权限。这同样适用于匿名身份验证。有关其他信息,请参见 IIS 帮助中的“基本身份验证默认登录类型”主题。您也可以访问下面的 Microsoft 网站:

基本身份验证
http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/cf438d2c-f9c7-4351-bf56-d2ab950d7d6e.mspx (http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/cf438d2c-f9c7-4351-bf56-d2ab950d7d6e.mspx)

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
}