Chương 1

Màu nền
Font chữ
Font size
Chiều cao dòng

Ch°¡ng 1 : Phát triÃn éng dång

1.1 T¡o éng dång Console

1.2 T¡o éng dång dña-trên-Windows

1.3 T¡o và sí dång module

1.4 T¡o và sí dång th° viÇn

1.5 Truy xu¥t các Ñi sÑ dòng lÇnh

1.6 ChÍn biên dËch mÙt khÑi mã vào file thñc thi

1.7 Truy xu¥t mÙt ph§n tí ch°¡ng trình có tên trùng vÛi mÙt të khóa

1.8 T¡o và qu£n lý c·p khóa tên m¡nh

1.9 T¡o tên m¡nh cho assembly

1.10 Xác minh mÙt assembly tên m¡nh không bË sía Õi

1.11 Hoãn viÇc ký assembly

1.12 Ký assembly vÛi chï ký sÑ Authenticode

1.13 T¡o và thi¿t l­p tin t°ßng mÙt SPC thí nghiÇm

1.14 Qu£n lý Global Assembly Cache

HYPERLINK "mk:@MSITStore:C:\\Documents%20and%20Settings\\Tran%20Huy\\Desktop\\Giao%20Trinh%20Lap%20Trinh%20C%20Sharp%202007%202.0.1.chm::/auto_20070804_022116/Cac%20giai%20phap%20lap%20trinh%20C%23.htm" \l "_Toc145927576#_Toc145927576" 1.15 Ngn ng°Ýi khác dËch ng°ãc mã nguÓn cça b¡n

Ch°¡ng này trình bày mÙt sÑ ki¿n théc nÁn t£ng, c§n thi¿t trong quá trình phát triÃn mÙt éng dång C#. Các måc trong ch°¡ng s½ trình bày chi ti¿t các v¥n Á sau ây:

Xây dñng các éng dång Console và Windows Form (måc 1.1 và 1.2).

T¡o và sí dång ¡n thà mã lÇnh và th° viÇn mã lÇnh (måc 1.3 và 1.4).

Truy xu¥t Ñi sÑ dòng lÇnh të bên trong éng dång (måc 1.5).

Sí dång các chÉ thË biên dËch à tùy bi¿n viÇc biên dËch mã nguÓn (måc 1.6).

Truy xu¥t các ph§n tí ch°¡ng trình (°ãc xây dñng trong ngôn ngï khác) có tên xung Ùt vÛi các të khóa C# (måc 1.7).

T¡o và xác minh tên m¡nh cho assembly (måc 1.8, 1.9, 1.10, và 1.11).

Ký mÙt assembly b±ng chï ký sÑ Microsoft Authenticode (måc 1.12 và 1.13).

Qu£n lý nhïng assembly chia s» °ãc l°u trï trong Global Assembly Cache (måc 1.14).

Ngn ng°Ýi dùng dËch ng°ãc assembly cça b¡n (måc 1.15).

T¥t c£ các công cå °ãc th£o lu­n trong ch°¡ng này Áu có trong Microsoft .NET Framework ho·c .NET Framework SDK.

Các công cå thuÙc Framework n±m trong th° måc chính cça phiên b£n Framework mà b¡n ang sí dång (m·c Ënh là \WINDOWS\Microsoft.NET\ Framework\v1.1.4322 n¿u b¡n sí dång .NET Framework version 1.1). Quá trình cài ·t .NET s½ tñ Ùng thêm th° måc này vào °Ýng d«n môi tr°Ýng cça hÇ thÑng.

Các công cå °ãc cung c¥p cùng vÛi SDK n±m trong th° måc Bin cça th° måc cài ·t SDK (m·c Ënh là \Program Files\Microsoft Visual Studio .NET 2003\ SDK\v1.1\Bin). Th° måc này không °ãc thêm vào °Ýng d«n mÙt cách tñ Ùng, vì v­y b¡n ph£i tñ thêm nó vào à dÅ dàng truy xu¥t các công cå này.

H§u h¿t các công cå trên Áu h× trã hai d¡ng Ñi sÑ dòng lÇnh: ng¯n và dài. Ch°¡ng này luôn trình bày d¡ng dài vì dÅ hiÃu h¡n (nh°ng bù l¡i b¡n ph£i gõ nhiÁu h¡n). Ñi vÛi d¡ng ng¯n, b¡n hãy tham kh£o tài liÇu t°¡ng éng trong .NET Framework SDK.

T¡o éng dång Console

B¡n muÑn xây dñng mÙt éng dång không c§n giao diÇn ng°Ýi dùng Ó hÍa (GUI), thay vào ó hiÃn thË k¿t qu£ và Íc dï liÇu nh­p të dòng lÇnh.

HiÇn thñc mÙt ph°¡ng théc t)nh có tên là Main d°Ûi các d¡ng sau trong ít nh¥t mÙt file mã nguÓn:

( public static void Main();

( public static void Main(string[] args);

( public static int Main();

( public static int Main(string[] args);

Sí dång Ñi sÑ /target:exe khi biên dËch assembly cça b¡n b±ng trình biên dËch C# (csc.exe).

M·c Ënh trình biên dËch C# s½ xây dñng mÙt éng dång Console trë khi b¡n chÉ Ënh lo¡i khác. Vì lý do này, không c§n chÉ Ënh /target.exe, nh°ng thêm nó vào s½ rõ ràng h¡n, hïu ích khi t¡o các kËch b£n biên dËch s½ °ãc sí dång bßi các éng dång khác ho·c s½ °ãc sí dång l·p i l·p l¡i trong mÙt thÝi gian. Ví då sau minh hÍa mÙt lÛp có tên là ConsoleUtils (°ãc Ënh ngh)a trong file ConsoleUtils.cs):

using System;

public class ConsoleUtils {

// Ph°¡ng théc hiÃn thË lÝi nh¯c và Íc áp éng të console.

public static string ReadString(string msg) {

Console.Write(msg);

return System.Console.ReadLine();

}

// Ph°¡ng théc hiÃn thË thông iÇp.

public static void WriteString(string msg) {

System.Console.WriteLine(msg);

}

// Ph°¡ng théc Main dùng à thí nghiÇm lÛp ConsoleUtils.

public static void Main() {

// Yêu c§u ng°Ýi dùng nh­p tên.

string name = ReadString("Please enter your name : ");

// HiÃn thË thông iÇp chào mëng.

WriteString("Welcome to Microsoft .NET Framework, " + name);

}

}

à xây dñng lÛp ConsoleUtils thành mÙt éng dång Console có tên là ConsoleUtils.exe, sí dång lÇnh:

csc /target:exe ConsoleUtils.cs

B¡n có thà ch¡y file thñc thi trñc ti¿p të dòng lÇnh. Khi ch¡y, ph°¡ng théc Main cça éng dång ConsoleUtils.exe yêu c§u b¡n nh­p tên và sau ó hiÃn thË thông iÇp chào mëng nh° sau:

Please enter your name : Binh Phuong

Welcome to Microsoft .NET Framework, Binh Phuong

Thñc t¿, éng dång hi¿m khi chÉ gÓm mÙt file mã nguÓn. Ví då, lÛp HelloWorld d°Ûi ây sí dång lÛp ConsoleUtils à hiÃn thË thông iÇp Hello, world lên màn hình (HelloWorld n±m trong file HelloWorld.cs).

public class HelloWorld {

public static void Main() {

ConsoleUtils.WriteString("Hello, world");

}

}

à xây dñng mÙt éng dång Console gÓm nhiÁu file mã nguÓn, b¡n ph£i chÉ Ënh t¥t c£ các file mã nguÓn này trong Ñi sÑ dòng lÇnh. Ví då, lÇnh sau ây xây dñng éng dång MyFirstApp.exe të các file mã nguÓn HelloWorld.cs và ConsoleUtils.cs:

csc /target:exe /main:HelloWorld /out:MyFirstApp.exe

HelloWorld.cs ConsoleUtils.cs

Ñi sÑ /out chÉ Ënh tên cça file thñc thi s½ °ãc t¡o ra. N¿u không °ãc chÉ Ënh, tên cça file thñc thi s½ là tên cça file mã nguÓn §u tiên trong ví då trên là HelloWorld.cs. Vì c£ hai lÛp HelloWorld và ConsoleUtils Áu có ph°¡ng théc Main, trình biên dËch không thà tñ Ùng quy¿t Ënh âu là iÃm nh­p cho file thñc thi. B¡n ph£i sí dång Ñi sÑ /main à chÉ Ënh tên cça lÛp chéa iÃm nh­p cho éng dång cça b¡n.

T¡o éng dång dña-trên-Windows

B¡n c§n xây dñng mÙt éng dång cung c¥p giao diÇn ng°Ýi dùng Ó hÍa (GUI) dña-trên-Windows Form.

HiÇn thñc mÙt ph°¡ng théc t)nh Main trong ít nh¥t mÙt file mã nguÓn. Trong Main, t¡o mÙt thà hiÇn cça mÙt lÛp thëa k¿ të lÛp System.Windows.Forms.Form (ây là form chính cça éng dång). TruyÁn Ñi t°ãng này cho ph°¡ng théc t)nh Run cça lÛp System.Windows.Forms.Application. Sí dång Ñi sÑ /target:winexe khi biên dËch assembly cça b¡n b±ng trình biên dËch C# (csc.exe).

ViÇc xây dñng mÙt éng dång có giao diÇn ng°Ýi dùng Ó hÍa Windows ¡n gi£n hoàn toàn khác xa viÇc phát triÃn mÙt éng dång dña-trên-Windows hoàn chÉnh. Tuy nhiên, b¥t kà vi¿t mÙt éng dång ¡n gi£n nh° Hello World hay vi¿t phiên b£n k¿ ti¿p cho Microsoft Word, b¡n cing ph£i thñc hiÇn nhïng viÇc sau:

T¡o mÙt lÛp thëa k¿ të lÛp System.Windows.Forms.Form cho m×i form c§n cho éng dång.

Trong m×i lÛp form, khai báo các thành viên mô t£ các iÁu kiÃm trên form, ví då Button, Label, ListBox, TextBox. Các thành viên này nên °ãc khai báo là private ho·c ít nh¥t cing là protected à các ph§n tí khác cça ch°¡ng trình không truy xu¥t trñc ti¿p chúng °ãc. N¿u muÑn cho phép truy xu¥t các iÁu kiÃm này, hiÇn thñc các thành viên c§n thi¿t trong lÛp form à cung c¥p viÇc truy xu¥t gián ti¿p (kiÃm soát °ãc) ¿n các iÁu kiÃm n±m trong.

Trong lÛp form, khai báo các ph°¡ng théc thå lý các sñ kiÇn do các iÁu kiÃm trên form sinh ra, ch³ng h¡n viÇc nh¯p vào Button, viÇc nh¥n phím khi mÙt TextBox ang tích cñc. Các ph°¡ng théc này nên °ãc khai báo là private ho·c protected và tuân theo m«u sñ kiÇn .NET chu©n (s½ °ãc mô t£ trong måc 16.10). Trong các ph°¡ng théc này (ho·c trong các ph°¡ng théc °ãc gÍi bßi các các ph°¡ng théc này), b¡n s½ Ënh ngh)a các chéc nng cça éng dång.

Khai báo mÙt ph°¡ng théc khßi dñng cho lÛp form à t¡o các iÁu kiÃm trên form và c¥u hình tr¡ng thái ban §u cça chúng (kích th°Ûc, màu, nÙi dung& ). Ph°¡ng théc khßi dñng này cing nên liên k¿t các ph°¡ng théc thå lý sñ kiÇn cça lÛp vÛi các sñ kiÇn t°¡ng éng cça m×i iÁu kiÃm.

Khai báo ph°¡ng théc t)nh Main th°Ýng là mÙt ph°¡ng théc cça lÛp t°¡ng éng vÛi form chính cça éng dång. Ph°¡ng théc này là iÃm b¯t §u cça éng dång và có các d¡ng nh° ã °ãc Á c­p ß måc 1.1. Trong ph°¡ng théc Main, t¡o mÙt thà hiÇn cça form chính và truyÁn nó cho ph°¡ng théc t)nh Application.Run. Ph°¡ng théc Run hiÃn thË form chính và khßi ch¡y mÙt vòng l·p thông iÇp chu©n trong tiÃu trình hiÇn hành, chuyÃn các tác Ùng të ng°Ýi dùng (nh¥n phím, nh¯p chuÙt& ) thành các sñ kiÇn gíi ¿n éng dång.

LÛp WelcomeForm trong ví då d°Ûi ây minh hÍa các kù thu­t trên. Khi ch¡y, nó yêu c§u ng°Ýi dùng nh­p vào tên rÓi hiÃn thË mÙt MessageBox chào mëng.

using System.Windows.Forms;

public class WelcomeForm : Form {

// Các thành viên private giï tham chi¿u ¿n các iÁu kiÃm.

private Label label1;

private TextBox textBox1;

private Button button1;

// Ph°¡ng théc khßi dñng (t¡o mÙt thà hiÇn form

// và c¥u hình các iÁu kiÃm trên form).

public WelcomeForm() {

// T¡o các iÁu kiÃm trên form.

this.label1 = new Label();

this.textBox1 = new TextBox();

this.button1 = new Button();

// T¡m hoãn layout logic cça form trong khi

// chúng ta c¥u hình và bÑ trí các iÁu kiÃm.

this.SuspendLayout();

// C¥u hình các Label (hiÃn thË yêu c§u).

this.label1.Location = new System.Drawing.Point(16, 36);

this.label1.Name = "label1";

this.label1.Size = new System.Drawing.Size(128, 16);

this.label1.TabIndex = 0;

this.label1.Text = "Please enter your name:";

// C¥u hình TextBox (nh­n thông tin të ng°Ýi dùng).

this.textBox1.Location = new System.Drawing.Point(152, 32);

this.textBox1.Name = "textBox1";

this.textBox1.TabIndex = 1;

this.textBox1.Text = "";

// C¥u hình Buton (ng°Ýi dùng nh¥n vào sau khi nh­p tên).

this.button1.Location = new System.Drawing.Point(109, 80);

this.button1.Name = "button1";

this.button1.TabIndex = 2;

this.button1.Text = "Enter";

this.button1.Click += new System.EventHandler(this.button1_Click);

// C¥u hình WelcomeForm và thêm các iÁu kiÃm.

this.ClientSize = new System.Drawing.Size(292, 126);

this.Controls.Add(this.button1);

this.Controls.Add(this.textBox1);

this.Controls.Add(this.label1);

this.Name = "form1";

this.Text = "Microsoft .NET Framework";

// Phåc hÓi layout logic cça form ngay khi

// t¥t c£ các iÁu kiÃm ã °ãc c¥u hình.

this.ResumeLayout(false);

}

// iÃm nh­p cça éng dång (t¡o mÙt thà hiÇn form, ch¡y vòng l·p

// thông iÇp chu©n trong tiÃu trình hiÇn hành - vòng l·p chuyÃn

// các tác Ùng të ng°Ýi dùng thành các sñ kiÇn ¿n éng dång).

public static void Main() {

Application.Run(new WelcomeForm());

}

// Ph°¡ng théc thå lý sñ kiÇn

// (°ãc gÍi khi ng°Ýi dùng nh¯p vào nút Enter).

private void button1_Click(object sender, System.EventArgs e) {

// Ghi ra Console.

System.Console.WriteLine("User entered: " + textBox1.Text);

// HiÃn thË lÝi chào trong MessageBox.

MessageBox.Show("Welcome to Microsoft .NET Framework, "

+ textBox1.Text, "Microsoft .NET Framework");

}

}

SHAPE \* MERGEFORMAT

Hình 1.1 MÙt éng dång Windows Form ¡n gi£n

à xây dñng lÛp WelcomeForm (trong file WelcomeForm.cs) thành mÙt éng dång, sí dång lÇnh:

csc /target:winexe WelcomeForm.cs

Ñi sÑ /target:winexe báo cho trình biên dËch bi¿t ây là éng dång dña-trên-Windows. Do ó, trình biên dËch s½ xây dñng file thñc thi sao cho không có cía sÕ Console nào °ãc t¡o ra khi b¡n ch¡y éng dång. N¿u b¡n sí dång /target:exe khi xây dñng mÙt éng dång Windows Form thay cho /target:winexe thì éng dång v«n làm viÇc tÑt, nh°ng s½ t¡o ra mÙt cía sÕ Console khi ch¡y. M·c dù iÁu này không °ãc °a chuÙng trong mÙt éng dång hoàn chÉnh, cía sÕ Console v«n hïu ích n¿u b¡n c§n ghi ra các thông tin gá rÑi ho·c ng nh­p khi ang phát triÃn và thí nghiÇm mÙt éng dång Windows Form. B¡n có thà ghi ra Console b±ng ph°¡ng théc Write và WriteLine cça lÛp System.Console.

èng dång WelcomeForm.exe trong hình 1.1 hiÃn thË lÝi chào ng°Ýi dùng có tên là Binh Phuong. Phiên b£n này cça éng dång °ãc xây dñng b±ng Ñi sÑ /target:exe, nên có cía sÕ Console à hiÃn thË k¿t qu£ cça dòng lÇnh Console.WriteLine trong ph°¡ng théc thå lý sñ kiÇn button1_Click .

ViÇc xây dñng mÙt éng dång GUI Ó sÙ th°Ýng tÑn nhiÁu thÝi gian do ph£i t¡o Ñi t°ãng, c¥u hình và liên k¿t nhiÁu form và iÁu kiÃm. Nh°ng may m¯n là Microsoft Visual Studio .NET tñ Ùng hóa h§u h¿t các ho¡t Ùng này. N¿u không có công cå nh° Microsoft Visual Studio .NET thì viÇc xây dñng mÙt éng dång Ó hÍa Ó sÙ s½ r¥t lâu, nhàm chán và dÅ sinh ra l×i.

T¡o và sí dång module

B¡n c§n thñc hiÇn các công viÇc sau:

Tng hiÇu qu£ thñc thi và sí dång bÙ nhÛ cça éng dång b±ng cách b£o £m r±ng bÙ thñc thi n¡p các kiÃu ít °ãc sí dång chÉ khi nào c§n thi¿t.

Biên dËch các kiÃu °ãc vi¿t trong C# thành mÙt d¡ng có thà sí dång l¡i °ãc trong các ngôn ngï .NET khác.

Sí dång các kiÃu °ãc phát triÃn b±ng mÙt ngôn ngï khác bên trong éng dång C# cça b¡n.

Sí dång Ñi sÑ /target:module (cça trình biên dËch C#) à xây dñng mã nguÓn C# cça b¡n thành mÙt module. Sí dång Ñi sÑ /addmodule à k¿t hãp các module hiÇn có vào assembly cça b¡n.

Module là các khÑi c¡ b£n t¡o dñng nên các assembly .NET. Module bao gÓm mÙt file ¡n chéa:

Mã ngôn ngï trung gian (Microsoft Intermediate Language MSIL): °ãc t¡o të mã nguÓn C# trong quá trình biên dËch.

Siêu dï liÇu (metadata): Mô t£ các kiÃu n±m trong module.

Các tài nguyên (resource): Ch³ng h¡n icon và string table, °ãc sí dång bßi các kiÃu trong module.

Assembly gÓm mÙt hay nhiÁu module và mÙt manifest. Khi chÉ có mÙt module, module và manifest th°Ýng °ãc xây dñng thành mÙt file cho thu­n tiÇn. Khi có nhiÁu module, assembly là mÙt nhóm lu­n lý cça nhiÁu file °ãc triÃn khai nh° mÙt thà thÑng nh¥t. Trong tr°Ýng hãp này, manifest có thà n±m trong mÙt file riêng hay chung vÛi mÙt trong các module.

ViÇc xây dñng mÙt assembly të nhiÁu module gây khó khn cho viÇc qu£n lý và triÃn khai assembly; nh°ng trong mÙt sÑ tr°Ýng hãp, cách này có nhiÁu lãi ích, bao gÓm:

BÙ thñc thi s½ chÉ n¡p mÙt module khi các kiÃu Ënh ngh)a trong module này °ãc yêu c§u. Do ó, khi có mÙt t­p các kiÃu mà éng dång ít khi dùng, b¡n có thà ·t chúng trong mÙt module riêng mà bÙ thñc thi chÉ n¡p khi c§n. ViÇc này có các lãi ích sau:

Tng hiÇu qu£ thñc thi, ·c biÇt khi éng dång °ãc n¡p qua m¡ng.

Gi£m thiÃu nhu c§u sí dång bÙ nhÛ.

Kh£ nng sí dång nhiÁu ngôn ngï khác nhau à vi¿t các éng dång ch¡y trên bÙ thñc thi ngôn ngï chung (Common Language Runtime CLR) là mÙt th¿ m¡nh cça .NET Framework. Tuy nhiên, trình biên dËch C# không thà biên dËch mã nguÓn °ãc vi¿t b±ng Microsoft Visual Basic .NET hay COBOL .NET trong assembly cça b¡n. B¡n ph£i sí dång trình biên dËch cça ngôn ngï ó biên dËch mã nguÓn thành MSIL theo mÙt c¥u trúc mà trình biên dËch C# có thà hiÃu °ãc ó là module. T°¡ng tñ, n¿u muÑn l­p trình viên cça các ngôn ngï khác sí dång các kiÃu °ãc phát triÃn b±ng C#, b¡n ph£i xây dñng chúng thành mÙt module.

à biên dËch file nguÓn ConsoleUtils.cs thành mÙt module, sí dång lÇnh:

csc /target:module ConsoleUtils.cs

LÇnh này s½ cho k¿t qu£ là mÙt file có tên là ConsoleUtils.netmodule. Ph§n mß rÙng netmodule là ph§n mß rÙng m·c Ënh cho module, và tên file trùng vÛi tên file nguÓn C#.

B¡n cing có thà xây dñng mÙt module të nhiÁu file nguÓn, cho k¿t qu£ là mÙt file (module) chéa MSIL và siêu dï liÇu cho các kiÃu chéa trong t¥t c£ file nguÓn. Ví då, lÇnh:

csc /target:module ConsoleUtils.cs WindowsUtils.cs

biên dËch hai file nguÓn ConsoleUtils.cs và WindowsUtils.cs thành mÙt module có tên là ConsoleUtils.netmodule.

Tên cça module °ãc ·t theo tên file nguÓn §u tiên trë khi b¡n chÉ Ënh cå thà b±ng Ñi sÑ /out. Ví då, lÇnh:

csc /target:module /out:Utilities.netmodule

ConsoleUtils.cs WindowsUtils.cs

s½ cho k¿t qu£ là file Utilities.netmodule.

à xây dñng mÙt assembly gÓm nhiÁu module, sí dång Ñi sÑ /addmodule. Ví då, à xây dñng file thñc thi MyFirstApp.exe të hai module: WindowsUtils.netmodule và ConsoleUtils.netmodule và hai file nguÓn: SourceOne.cs và SourceTwo.cs, sí dång lÇnh:

csc /out:MyFirstApp.exe /target:exe

/addmodule:WindowsUtils.netmodule,ConsoleUtils.netmodule

SourceOne.cs SourceTwo.cs

LÇnh này s½ cho k¿t qu£ là mÙt assembly gÓm các file sau:

MyFirstApp.exe: Chéa manifest cing nh° MSIL cho các kiÃu °ãc khai báo trong hai file nguÓn SourceOne.cs và SourceTwo.cs.

ConsoleUtils.netmodule và WindowsUtils.netmodule: GiÝ ây là mÙt ph§n cça assembly nh°ng không thay Õi sau khi biên dËch. (N¿u b¡n ch¡y MyFirstApp.exe mà không có các file netmodule, ngo¡i lÇ System.IO.FileNotFoundException s½ bË ném).

T¡o và sí dång th° viÇn

B¡n c§n xây dñng mÙt t­p các chéc nng thành mÙt th° viÇn à nó có thà °ãc tham chi¿u và tái sí dång bßi nhiÁu éng dång.

à t¡o th° viÇn, sí dång Ñi sÑ /target:library khi biên dËch assembly cça b¡n b±ng trình biên dËch C# (csc.exe). à tham chi¿u th° viÇn, sí dång Ñi sÑ /reference và chÉ Ënh tên cça th° viÇn khi biên dËch éng dång.

Måc 1.1 minh hÍa cách xây dñng éng dång MyFirstApp.exe të hai file mã nguÓn ConsoleUtils.cs và HelloWorld.cs. File ConsoleUtils.cs chéa lÛp ConsoleUtils, cung c¥p các ph°¡ng théc ¡n gi£n hóa sñ t°¡ng tác vÛi Console. Các chéc nng này cça lÛp ConsoleUtils cing có thà hïu ích cho các éng dång khác. à sí dång l¡i lÛp này, thay vì gÙp c£ mã nguÓn cça nó vào m×i éng dång, b¡n có thà xây dñng nó thành mÙt th° viÇn, khi¿n các chéc nng này có thà truy xu¥t °ãc bßi nhiÁu éng dång.

à xây dñng file ConsoleUtils.cs thành mÙt th° viÇn, sí dång lÇnh:

csc /target:library ConsoleUtils.cs

LÇnh này sinh ra mÙt file th° viÇn có tên là ConsoleUtils.dll.

à t¡o mÙt th° viÇn të nhiÁu file mã nguÓn, liÇt kê tên các file này ß cuÑi dòng lÇnh. B¡n có thà sí dång Ñi sÑ /out à chÉ Ënh tên th° viÇn, n¿u không, tên th° viÇn °ãc ·t theo tên cça file mã nguÓn §u tiên. Ví då, à t¡o th° viÇn MyFirstLibrary.dll të hai file mã nguÓn ConsoleUtils.cs và WindowsUtils.cs, sí dång lÇnh:

csc /out:MyFirstLibrary.dll /target:library

ConsoleUtils.cs WindowsUtils.cs

Tr°Ûc khi phân phÑi th° viÇn cho ng°Ýi khác sí dång, b¡n nên t¡o tên m¡nh (strong-name) à không ai có thà chÉnh sía assembly cça b¡n. ViÇc ·t tên m¡nh cho th° viÇn còn cho phép ng°Ýi khác cài ·t nó vào Global Assembly Cache, giúp viÇc tái sí dång dÅ dàng h¡n (xem måc 1.9 vÁ cách ·t tên m¡nh cho th° viÇn cça b¡n và måc 1.14 vÁ cách cài ·t mÙt th° viÇn có tên m¡nh vào Global Assembly Cache). Ngoài ra, b¡n có thà ánh d¥u th° viÇn cça b¡n vÛi chï ký Authenticode à ng°Ýi dùng bi¿t b¡n là tác gi£ cça th° viÇn (xem måc 1.12 vÁ cách ánh d¥u th° viÇn vÛi Authenticode).

à biên dËch mÙt assembly có sí dång các kiÃu °ãc khai báo trong các th° viÇn khác, b¡n ph£i báo cho trình biên dËch bi¿t c§n tham chi¿u ¿n th° viÇn nào b±ng Ñi sÑ /reference. Ví då, à biên dËch file HelloWorld.cs (trong måc 1.1) trong tr°Ýng hãp lÛp ConsoleUtils n±m trong th° viÇn ConsoleUtils.dll, sí dång lÇnh:

csc /reference:ConsoleUtils.dll HelloWorld.cs

B¡n c§n chú ý ba iÃm sau:

N¿u tham chi¿u nhiÁu h¡n mÙt th° viÇn, b¡n c§n phân cách tên các th° viÇn b±ng d¥u ph©y ho·c ch¥m ph©y, nh°ng không sí dång kho£ng tr¯ng. Ví då:

/reference:ConsoleUtils.dll,WindowsUtils.dll

N¿u th° viÇn không n±m cùng th° måc vÛi file mã nguÓn, b¡n c§n sí dång Ñi sÑ /lib à chÉ Ënh th° måc chéa th° viÇn. Ví då:

/lib:c:\CommonLibraries,c:\Dev\ThirdPartyLibs

N¿u th° viÇn c§n tham chi¿u là mÙt assembly gÓm nhiÁu file, b¡n c§n tham chi¿u file có chéa manifest (xem thông tin vÁ assembly gÓm nhiÁu file trong måc 1.3).

Truy xu¥t các Ñi sÑ dòng lÇnh

B¡n c§n truy xu¥t các Ñi sÑ °ãc chÉ Ënh trên dòng lÇnh khi thñc thi éng dång.

Sí dång mÙt d¡ng cça ph°¡ng théc Main, trong ó nh­n Ñi sÑ dòng lÇnh d°Ûi d¡ng mÙt m£ng chu×i. Ngoài ra, có thà truy xu¥t Ñi sÑ dòng lÇnh të b¥t cé âu trong mã nguÓn cça b¡n b±ng các thành viên t)nh cça lÛp System.Environment.

Khai báo ph°¡ng théc Main thuÙc mÙt trong các d¡ng sau à truy xu¥t Ñi sÑ dòng lÇnh d°Ûi d¡ng mÙt m£ng chu×i:

public static void Main(string[] args) {}

public static int Main(string[] args) {}

Khi ch¡y, Ñi sÑ args s½ chéa mÙt chu×i cho m×i giá trË °ãc nh­p trên dòng lÇnh và n±m sau tên éng dång. Ph°¡ng théc Main trong ví då d°Ûi ây s½ duyÇt qua m×i Ñi sÑ dòng lÇnh °ãc truyÁn cho nó và hiÃn thË chúng ra cía sÕ Console:

public class CmdLineArgExample {

public static void Main(string[] args) {

// DuyÇt qua các Ñi sÑ dòng lÇnh.

foreach (string s in args) {

System.Console.WriteLine(s);

}

}

}

Khi thñc thi CmdLineArgExample vÛi lÇnh:

CmdLineArgExample "one \"two\" three" four 'five six'

éng dång s½ t¡o ra k¿t xu¥t nh° sau:

one "two" three

four

'five

six'

Chú ý r±ng, khác vÛi C và C++, tên cça éng dång không n±m trong m£ng chéa các Ñi sÑ. T¥t c£ ký tñ n±m trong d¥u nháy kép ( ) °ãc xem nh° mÙt Ñi sÑ, nh°ng d¥u nháy ¡n (') chÉ °ãc xem nh° ký tñ bình th°Ýng. N¿u muÑn sí dång d¥u nháy kép trong Ñi sÑ, ·t ký tñ v¡ch ng°ãc (\) tr°Ûc nó. T¥t c£ các kho£ng tr¯ng Áu bË bÏ qua trë khi chúng n±m trong d¥u nháy kép.

N¿u muÑn truy xu¥t Ñi sÑ dòng lÇnh ß n¡i khác (không ph£i trong ph°¡ng théc Main), b¡n c§n xí lý các Ñi sÑ dòng lÇnh trong ph°¡ng théc Main và l°u trï chúng à sí dång sau này.

Ngoài ra, b¡n có thà sí dång lÛp System.Environment, lÛp này cung c¥p hai thành viên t)nh tr£ vÁ thông tin dòng lÇnh: CommandLine và GetCommandLineArgs.

ThuÙc tính CommandLine tr£ vÁ mÙt chu×i chéa toàn bÙ dòng lÇnh. Tùy thuÙc vào hÇ iÁu hành éng dång ang ch¡y mà thông tin °Ýng d«n có éng tr°Ûc tên éng dång hay không. Các hÇ iÁu hành Windows NT 4.0, Windows 2000, và Windows XP không chéa thông tin °Ýng d«n, trong khi Windows 98 và Windows ME thì l¡i chéa.

Ph°¡ng théc GetCommandLineArgs tr£ vÁ mÙt m£ng chu×i chéa các Ñi sÑ dòng lÇnh. M£ng này có thà °ãc xí lý giÑng nh° m£ng °ãc truyÁn cho ph°¡ng théc Main, tuy nhiên ph§n tí §u tiên cça m£ng này là tên éng dång.

ChÍn biên dËch mÙt khÑi mã vào file thñc thi

B¡n c§n chÍn mÙt sÑ ph§n mã nguÓn s½ °ãc biên dËch trong file thñc thi.

Sí dång các chÉ thË tiÁn xí lý #if, #elif, #else, và #endif à chÉ Ënh khÑi mã nào s½ °ãc biên dËch trong file thñc thi. Sí dång ·c tính System.Diagnostics. ConditionalAttribute à chÉ Ënh các ph°¡ng théc mà s½ chÉ °ãc gÍi tùy theo iÁu kiÇn. iÁu khiÃn viÇc chÍn các khÑi mã b±ng các chÉ thË #define và #undef trong mã nguÓn, ho·c sí dång Ñi sÑ /define khi ch¡y trình biên dËch C#.

N¿u muÑn éng dång cça b¡n ho¡t Ùng khác nhau tùy vào các y¿u tÑ nh° nÁn ho·c môi tr°Ýng mà éng dång ch¡y, b¡n có thà kiÃm tra iÁu kiÇn khi ch¡y bên trong mã nguÓn và kích ho¡t các ho¡t Ùng c§n thi¿t. Tuy nhiên, cách này làm mã nguÓn lÛn lên và £nh h°ßng ¿n hiÇu nng. MÙt cách ti¿p c­n khác là xây dñng nhiÁu phiên b£n cça éng dång à h× trã các nÁn và môi tr°Ýng khác nhau. M·c dù cách này kh¯c phåc °ãc các v¥n Á vÁ Ù lÛn cça mã nguÓn và viÇc gi£m hiÇu nng, nh°ng nó không ph£i là gi£i pháp tÑt khi ph£i giï mã nguÓn khác nhau cho m×i phiên b£n. Vì v­y, C# cung c¥p các tính nng cho phép b¡n xây dñng các phiên b£n tùy bi¿n cça éng dång chÉ të mÙt mã nguÓn.

Các chÉ thË tiÁn xí lý cho phép b¡n chÉ Ënh các khÑi mã s½ °ãc biên dËch vào file thñc thi chÉ n¿u các ký hiÇu cå thà °ãc Ënh ngh)a lúc biên dËch. Các ký hiÇu ho¡t Ùng nh° các công t¯c on/off, chúng không có giá trË mà chÉ là ã °ãc Ënh ngh)a hay ch°a °ãc Ënh ngh)a . à Ënh ngh)a mÙt ký hiÇu, b¡n có thà sí dång chÉ thË #define trong mã nguÓn ho·c sí dång Ñi sÑ trình biên dËch /define. Ký hiÇu °ãc Ënh ngh)a b±ng #define có tác dång ¿n cuÑi file Ënh ngh)a nó. Ký hiÇu °ãc Ënh ngh)a b±ng /define có tác dång trong t¥t c£ các file ang °ãc biên dËch. à bÏ mÙt ký hiÇu ã Ënh ngh)a b±ng /define, C# cung c¥p chÉ thË #undef, hïu ích khi b¡n muÑn b£o £m mÙt ký hiÇu không °ãc Ënh ngh)a trong các file nguÓn cå thÃ. Các chÉ thË #define và #undef ph£i n±m ngay §u file mã nguÓn, trên c£ các chÉ thË using. Các ký hiÇu có phân biÇt chï hoa-th°Ýng.

Trong ví då sau, bi¿n platformName °ãc gán giá trË tùy vào các ký hiÇu winXP, win2000, winNT, ho·c win98 có °ãc Ënh ngh)a hay không. Ph§n §u cça mã nguÓn Ënh ngh)a các ký hiÇu win2000 và released (không °ãc sí dång trong ví då này), và bÏ ký hiÇu win98 trong tr°Ýng hãp nó °ãc Ënh ngh)a trên dòng lÇnh trình biên dËch.

#define win2000

#define release

#undef win98

using System;

public class ConditionalExample {

public static void Main() {

// Khai báo chu×i chéa tên cça nÁn.

string platformName;

#if winXP // Biên dËch cho Windows XP

platformName = "Microsoft Windows XP";

#elif win2000 // Biên dËch cho Windows 2000

platformName = "Microsoft Windows 2000";

#elif winNT // Biên dËch cho Windows NT

platformName = "Microsoft Windows NT";

#elif win98 // Biên dËch cho Windows 98

platformName = "Microsoft Windows 98";

#else // NÁn không °ãc nh­n bi¿t

platformName = "Unknown";

#endif

Console.WriteLine(platformName);

}

}

à xây dñng lÛp ConditionalExample (chéa trong file ConditionalExample.cs) và Ënh ngh)a các ký hiÇu winXP và DEBUG (không °ãc sí dång trong ví då này), sí dång lÇnh:

csc /define:winXP;DEBUG ConditionalExample.cs

C¥u trúc #if .. #endif ánh giá các mÇnh Á #if và #elif chÉ ¿n khi tìm th¥y mÙt mÇnh Á úng, ngh)a là n¿u có nhiÁu ký hiÇu °ãc Ënh ngh)a (ch³ng h¡n, winXP và win2000), thé tñ các mÇnh Á là quan trÍng. Trình biên dËch chÉ biên dËch o¡n mã n±m trong mÇnh Á úng. N¿u không có mÇnh Á nào úng, trình biên dËch s½ biên dËch o¡n mã n±m trong mÇnh Á #else.

B¡n cing có thà sí dång các toán tí lu­n lý à biên dËch có iÁu kiÇn dña trên nhiÁu ký hiÇu. B£ng 1.1 tóm t¯t các toán tí °ãc h× trã.

B£ng 1.1 Các toán tí lu­n lý °ãc h× trã bßi chÉ thË #if .. #endif

Toán tí Ví då Mô t£ == #if winXP == true B±ng. úng n¿u winXP °ãc Ënh ngh)a. T°¡ng °¡ng vÛi #if winXP. != #if winXP != true Không b±ng. úng n¿u winXP không °ãc Ënh ngh)a. T°¡ng °¡ng vÛi #if !winXP. && #if winXP && release Phép AND lu­n lý. úng n¿u winXP và release °ãc Ënh ngh)a. || #if winXP || release Phép OR lu­n lý. úng n¿u winXP ho·c release °ãc Ënh ngh)a. () #if (winXP || win2000) && release D¥u ngo·c ¡n cho phép nhóm các biÃu théc. úng n¿u winXP ho·c win2000 °ãc Ënh ngh)a, Óng thÝi release cing °ãc Ënh ngh)a.

B¡n không nên l¡m dång các chÉ thË biên dËch có iÁu kiÇn và không nên vi¿t các biÃu théc iÁu kiÇn quá phéc t¡p; n¿u không, mã nguÓn cça b¡n s½ trß nên dÅ nh§m l«n và khó qu£n lý ·c biÇt khi dñ án cça b¡n càng lÛn.

MÙt cách khác không linh ho¡t nh°ng hay h¡n chÉ thË tiÁn xí lý #if là sí dång ·c tính System.Diagnostics.ConditionalAttribute. N¿u b¡n áp dång ConditionalAttribute cho mÙt ph°¡ng théc, trình biên dËch s½ bÏ qua mÍi lÝi gÍi ph°¡ng théc ó n¿u ký hiÇu do ConditionalAttribute chÉ Ënh không °ãc Ënh ngh)a t¡i iÃm gÍi. Trong o¡n mã sau, ConditionalAttribute xác Ënh r±ng ph°¡ng théc DumpState chÉ °ãc biên dËch vào file thñc thi n¿u ký hiÇu DEBUG °ãc Ënh ngh)a khi biên dËch.

[System.Diagnostics.Conditional("DEBUG")]

public static void DumpState() {//...}

ViÇc sí dång ConditionalAttribute giúp ·t các iÁu kiÇn gÍi mÙt ph°¡ng théc t¡i n¡i khai báo nó mà không c§n các chÉ thË #if<>Brtv¸º¼îðò( * , p r t Ô Ö Ø ^

'

b

ª

¬

®

è

ê

ì

T

V

X

Œ

Ž

æ

è

ê

N

P

R

-

˜

š

éؼžƒ¼žƒ¼žƒ¼žƒ¼žƒ¼žƒ¼žƒ¼žƒ¼žƒ¼žƒ¼žƒ¼žƒ¼žƒ¼žƒ¼4�h2¡h2¡5�>*CJOJPJQJaJmHnHu:h2¡h2¡5�>*B*CJOJPJQJaJmHnHphÿu7h2¡h2¡5�B*CJOJPJQJaJ mHnHphÿu h2¡h2¡CJOJPJQJaJ,h2¡h2¡5�B*CJ$OJPJQJaJ$phÿ->Bv¼ò, t Ø b

®

ì

X

ê

R

š

Ü Þ à *ðÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕËðð dð ¤gd2¡$

Æð

„v„8dð¤< ¤<]„v^„8a$gd2¡ $d¤< ¤<a$gd2¡ š

œ

v x Ø Ú Ü à ¤¨Vdl„ 'bz|ØÚø& z | ² Þ fæÝ¿Ý¿Ý£Œ{i{i{i{i{i{i{i{i{i{i{U'h2¡h2¡5�CJOJPJQJ^JaJ#h2¡h2¡6�CJOJPJQJaJ h2¡h2¡CJOJPJQJaJ,h2¡h2¡5�B*CJ$OJPJQJaJ$phÿ7h2¡h2¡5�B*CJOJPJQJaJ mHnHphÿu:h2¡h2¡5�>*B*CJOJPJQJaJmHnHphÿuCjh2¡h2¡5�>*B*CJOJPJQJUaJmHnHphÿu*ª4¬F0ºN ö fJŠÒ¾êåååååååååɶ¶¶�($

&

F

Æðd¤ð ¤$d-D@&MÆ

ÿóóóNÆÿa$gd2¡$„d¤< ¤<^„a$gd2¡$

&

F

Æ„#„Ýýd ¤x^„#'„Ýýa$gd2¡$

&

F

Æ„#d¤< ¤<^„#a$gd2¡ æ"FJn€Îà$zœÐüÐÖü,2Nʘº¾ÂÄÈÊÒÔêv|RêÖêÖÄ°Ä°Ä°Ä°Ä°Ä°Ä°Ä°Ä°Ä°Äš„š„š„špZp*h2¡h2¡5�6�CJOJPJQJ^JaJ'h2¡h2¡5�CJOJPJQJ^JaJ*h2¡h2¡5�CJ OJPJQJ\�^JaJ *h2¡h2¡5�CJ OJPJQJ\�^JaJ &h2¡h2¡5�6�CJOJPJQJaJ#h2¡h2¡5�CJOJPJQJaJ'h2¡h2¡5�CJOJPJQJ^JaJ*h2¡h2¡5�6�CJOJPJQJ^JaJ#êÂüP-ˆ-Ú-àÙjj;.$

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9„#d¤x ¤^„#a$gd2¡m$.$

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9„d¤x ¤x^„a$gd2¡m$)

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9„#dð ¤x^„#gd2¡m$$

&

F

Æ „#„Ýýd ¤^„#'„Ýýa$gd2¡-$

&

F

Æ „„äýd¤x ¤^„'„äýa$gd2¡RZÂÄüþP-R-ˆ-Š-Ú-ø- x | € Ž " Æ Ê þ

!�!¦!D#ë×Àë©•©•©•ƒëƒoƒoƒ^L^L^ë^#h2¡h2¡6�CJOJPJQJaJ h2¡h2¡CJOJPJQJaJ&h2¡h2¡5�6�CJOJPJQJaJ#h2¡h2¡5�CJOJPJQJaJ'h2¡h2¡5�CJ OJPJQJRHi^J- j·ðh2¡h2¡5�CJ OJPJQJRHi^J- j·ðh2¡h2¡5�CJOJPJQJ^JaJ'h2¡h2¡5�CJOJPJQJ^JaJ'h2¡h2¡5�CJOJPJQJ^JaJÚ-" º#Ö#Ø#$$š$þ$%H%œ%¨%²%&d&èÕ­‚‚‚‚‚‚‚‚‚‚‚‚*$

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9d¤x ¤xa$gd2¡m$'

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9dð¤x ¤xgd2¡m$$

Æhd¤< ¤<a$gd2¡$

Æh„d¤< ¤<^„a$gd2¡D#\#-#'#º#Ö#T)d)„)œ)Ä)Ò)è)*(*h*++$+D+Ò+,~,- -@-X-Š-¢-Â-Ö-ö-..J./

/</J/X0t0 0º0Â0à0ä0N1íÜÊÜ·¢�ÜíÜÊÜÊÜ·ÜíÜÊÜ·¢ÜíÜíÜÊÜíÜÊÜ·¢�ÜÊÜÊÜÊÜÊÜ{'h2¡h2¡5�CJOJPJQJ^JaJ$h2¡h2¡CJ OJPJQJRHi^J(h2¡h2¡CJOJPJQJRHi^JaJ$h2¡h2¡CJOJPJQJ^JaJ#h2¡h2¡6�CJOJPJQJaJ h2¡h2¡CJOJPJQJaJ$h2¡h2¡CJOJPJQJ^JaJ.d&v&Ä&Ð&Ú&T'"'-'æ'd(v(Ê(T)')d)(*h*Ò+ÔÔÔÔÔÔÔÔÔÔÔÔÔÔÁ™Á'

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9dð¤x ¤xgd2¡m$$

Æhd¤< ¤<a$gd2¡*$

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9d¤x ¤xa$gd2¡m$Ò+,~,.J.L.Œ.-.ú./

/ä0N1Ž1Î4׬™×¬¬¬¬¬¬™×¬™$

Æhd¤< ¤<a$gd2¡*$

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9d¤x ¤xa$gd2¡m$'

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9dð¤x ¤xgd2¡m$ N1Ž1œ1¤1Ô2î2 3"3*3B3j3r3H4R4Î4Ò4Ô4Ø4Ú4â4ä4ì4î4

5"5éØij¡³Ž³Ž³Ž³Ä³xbxbxbxbxN'h2¡h2¡5�CJOJPJQJ^JaJ*h2¡h2¡5�CJOJPJQJ\�^JaJ*h2¡h2¡5�CJOJPJQJ\�^JaJ$h2¡h2¡CJOJPJQJ^JaJ#h2¡h2¡6�CJOJPJQJaJ h2¡h2¡CJOJPJQJaJ'h2¡h2¡5�CJOJPJQJ^JaJ h2¡h2¡CJOJPJQJaJ+h2¡h2¡5�CJOJPJQJRHi^JaJÎ4

5Ì5®8;¬;,?¨BÔDÂHìIÖ·š‡mmmmm‡$

&

F

Æ„d¤< ¤<^„a$gd2¡$

Æhd¤< ¤<a$gd2¡$

&

F

Æ „„äýd ¤x^„'„äýa$gd2¡-$

&

F

Æ „„äýd¤x ¤^„'„äýa$gd2¡($

&

F

Æðd¤ð ¤$d-D@&MÆ

ÿóóóNÆÿa$gd2¡

"5š5°5È5

66b6j6Æ6ø67 7'7˜7ª7ê7

8(8'8-8š8¨8®8"909'9Â9>:V:":°::;l;N<Z<^<h<l<z<~<Œ<à<î<=,=@(@Z@h@Ú@è@ô@A<ABAEêÖêÖÂÖÂÖÂÖêÖÂÖÂÖÂÖêÖêÖ±Ÿ±Ÿ±Ÿ±Ÿ±Œ±Œ±Œ±Œ±Œ±Œ±Œ±Œ±Œ±Œ±Œ±Ÿ±$h2¡h2¡CJOJPJQJ^JaJ#h2¡h2¡6�CJOJPJQJaJ h2¡h2¡CJOJPJQJaJ'h2¡h2¡5�CJOJPJQJ^JaJ'h2¡h2¡5�CJOJPJQJ^JaJ*h2¡h2¡5�6�CJOJPJQJ^JaJ7EE|F„F

G*GFGLGÊHàHÀIÔIìIª^º^¼^¾^ì^î^ð^ô^ö^_N_p_†_ _¼_'H'V'íÜíÜíÜíÜíÜíÜíÉÜÁ½Á¯ÁÜ›ˆÜíÜvÜbQ h2¡h2¡CJOJPJQJaJ'h2¡h2¡5�CJOJPJQJ^JaJ#h2¡h2¡6�CJOJPJQJaJ$h2¡h2¡CJOJPJQJ^JaJ'h2¡h2¡5�CJOJPJQJ^JaJjh2¡UmHnHuh2¡jh2¡U$h2¡h2¡CJ OJPJQJRHi^J h2¡h2¡CJOJPJQJaJ$h2¡h2¡CJOJPJQJ^JaJìI$J&JjJlJìJ K\K"K-KþKXLŽL�LàL&MtM¾MÀM*N-N׬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬*$

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9d¤x ¤xa$gd2¡m$'

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9dð¤x ¤xgd2¡m$ -NÒNÔN8OºOP~PÂP.Q0Q¨Q0R‚RÊR

S S'STfT¬TöTÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔ*$

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9d¤x ¤xa$gd2¡m$ öTŒUŽUüU;VdVŽV¶VÓVWWfXÊX YYY¤Y0Z¶ZÌ¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡*$

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9d¤x ¤xa$gd2¡m$2$

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9„ì„ûd¤x ¤x^„ì'„ûa$gd2¡m$¶ZöZøZP[\[^[¢[

\"\-\Ì\T]V]']6^ª^¶^º^¼^ö^ÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÁ®$

Æhd¤< ¤<a$gd2¡$

Æhd¤< ¤<a$gd2¡*$

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9d¤x ¤xa$gd2¡m$ö^N_P_'H'‚e'g~j¬jìÙÙ±ÙÙ•l($

&

F

Æðd¤ð ¤$d-D@&MÆ

ÿóóóNÆÿa$gd2¡$

&

F

Æ„#„Ýýd ¤x^„#'„Ýýa$gd2¡'

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9dð¤x ¤xgd2¡m$$

Æhd¤< ¤<a$gd2¡$

Æhdð¤< ¤<a$gd2¡V'r'à'î'„a"abbNbhbzb-b

ccÆcÔcºdÒdúd

e,e6e>ePebe~e"e²e f6f¤fºf¼fÚfèf.gPg"g®g'gêgðgàhiiišiÔi~jëÚÈÚÈÚëÚÈÚëÚÈÚÈÚÈÚÈÚµÚµÚµÚÈÚÈÚë¤ÚÈÚµÚµÚ�z�z�z�z�*h2¡h2¡5�6�CJOJPJQJ^JaJ'h2¡h2¡5�CJOJPJQJ^JaJ h2¡h2¡CJOJPJQJaJ$h2¡h2¡CJOJPJQJ^JaJ#h2¡h2¡6�CJOJPJQJaJ h2¡h2¡CJOJPJQJaJ'h2¡h2¡5�CJOJPJQJ^JaJ0~j‚j„j�j'j-j˜j¬jöjVlZlÒlØl|m€m"m²mÎmúmþm,n0n„n˜noloroêo(p*p2pêÔêÔêÔêÀ®š®š®š®À†ÀpÀpÀ†À_M_M_M#h2¡h2¡6�CJOJPJQJaJ h2¡h2¡CJOJPJQJaJ*h2¡h2¡5�6�CJOJPJQJ^JaJ'h2¡h2¡5�CJOJPJQJ^JaJ&h2¡h2¡5�6�CJOJPJQJaJ#h2¡h2¡5�CJOJPJQJaJ'h2¡h2¡5�CJOJPJQJ^JaJ*h2¡h2¡5�CJOJPJQJ\�^JaJ*h2¡h2¡5�CJOJPJQJ\�^JaJ¬jöjlæl"moºožpqÚq"tÜuÐwàÅÅŨ•{{{••{$

&

F

Æ„d¤< ¤<^„a$gd2¡$

Æhd¤< ¤<a$gd2¡$

&

F

Æ „„äýd ¤x^„'„äýa$gd2¡$

&

F

Æ Ð„„„d¤< ¤<^„„a$gd2¡-$

&

F

Æ „„äýd¤x ¤^„'„äýa$gd2¡

2pbpfpºpÊp2qBqÚq'r"r

t

tètêtòuôuv vhvjvHwJwrwtwby�y'y˜yÆyàyzzxz°z¸zÎzêzìz'{š{æ{ê{æ|ê|r}�}Ò}~t~ ~¾~Ð~fj,€4€Æ€.�'�~�†�¤�Ü�ïÝïÝïÝïȲȲȲȲȲȲȲȲȲȲȲȲȲȲȲȲȲȲȲȞȲȲȲȲȞȲȲÈ'h2¡h2¡5�CJOJPJQJ^JaJ+h2¡h2¡6�CJOJPJQJaJmH

sH

(h2¡h2¡CJOJPJQJaJmH

sH

#h2¡h2¡6�CJOJPJQJaJ h2¡h2¡CJOJPJQJaJ>ÐwRx˜xB}Ò}~nÆ€.�

‚ì‚Dƒåå˸�¸¸�¸¸�'

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9dð¤x ¤xgd2¡m$$

Æhd¤< ¤<a$gd2¡$

&

F

Æ„d¤< ¤<^„a$gd2¡$

&

F

Æ„„„d¤< ¤<^„„a$gd2¡

Ü�‚Ƃ΂҂ì‚Dƒˆƒ¶ƒÜƒT„h„®„Ê„ê„......J...r...Š...'...ª...Ê... †Ä†8‡T‡†‡Ž‡ð‡ˆˆ(ˆ,ˆXˆ'ˆŒˆ>‰Z‰†‰˜‰®‰éÔ¼Ô«-�ÔéÔ¼ÔéÔéÔéÔéÔéÔ-�«o«o«o«o«o«o«o«o«#h2¡h2¡6�CJOJPJQJaJ+h2¡h2¡5�CJOJPJQJRHi^JaJ'h2¡h2¡5�CJOJPJQJ^JaJ h2¡h2¡CJOJPJQJaJ/h2¡h2¡5�CJOJPJQJ^JaJmH

sH

(h2¡h2¡CJOJPJQJaJmH

sH

+h2¡h2¡6�CJOJPJQJaJmH

sH

)DƒˆƒàƒÊ... †Œ†Ä†8‡,ˆŠÔÁÁ™ÔÔÁ$

&

F

Æ„d¤< ¤<^„a$gd2¡'

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9dð¤x ¤xgd2¡m$$

Æhd¤< ¤<a$gd2¡*$

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9d¤x ¤xa$gd2¡m$ ®‰ì‰Š

Š

ŠŠŠŠ Š*Š,Š2Š4Š8Šl‹Š‹ô‹ø‹ü‹

Œ^ŒrŒÞŒ.�J�v�"�œ�¶�íÜÆ°Æ°Æ°Æ°™°Æ...q...[...[...q...ÜIÜIÜI#h2¡h2¡6�CJOJPJQJaJ*h2¡h2¡5�6�CJOJPJQJ^JaJ'h2¡h2¡5�CJOJPJQJ^JaJ'h2¡h2¡5�CJOJPJQJ^JaJ-h2¡h2¡5�CJOJPJQJ\�^JaJo(*h2¡h2¡5�CJOJPJQJ\�^JaJ*h2¡h2¡5�CJOJPJQJ\�^JaJ h2¡h2¡CJOJPJQJaJ$h2¡h2¡CJOJPJQJ^JaJŠ8Š,‹ÞŒ¢�('p'î'|"Ô"Ö·š‡‡_‡‡_'

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9dð¤x ¤xgd2¡m$$

Æhd¤< ¤<a$gd2¡$

&

F

Æ „„äýd ¤x^„'„äýa$gd2¡-$

&

F

Æ „„äýd¤x ¤^„'„äýa$gd2¡($

&

F

Æðd¤ð ¤$d-D@&MÆ

ÿóóóNÆÿa$gd2¡ ¶�Ä�â�ö� Ž€ŽŽŽÆŽÞŽÄ�â�('p'Ê'ê'Ð'Ø'È"ì""6">"\"|"Ô"•®•Ä•²-Ü-˜.˜¨˜À˜x™�™äšøš.›H›"›¬›Ô›ô› œpœÈ�Ê� ž"ž¾žÆžŸxŸ@ B ïÝïÊïÝïÊïÝï¶ïÝï¢ïÝïÝïÝﶌïÝïÝïÝïÝïÝï¢ïÝïÊïÝï¶ï¢¶¢ï¢ï¶ïÝ+h2¡h2¡5�CJOJPJQJRHi^JaJ'h2¡h2¡5�CJOJPJQJ^JaJ'h2¡h2¡5�CJOJPJQJ^JaJ$h2¡h2¡CJOJPJQJ^JaJ#h2¡h2¡6�CJOJPJQJaJ h2¡h2¡CJOJPJQJaJ7Ô"•-™ œpœ¦œÈ�"žŸxŸÔÁÁ™ÁSS+

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9„dð¤x ¤x^„gd2¡m$$

&

F

Æ„d¤< ¤<^„a$gd2¡'

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9dð¤x ¤xgd2¡m$$

Æhd¤< ¤<a$gd2¡*$

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9d¤x ¤xa$gd2¡m$ xŸ¶ ö ˜¡d£B¤-¤å¼�€mS$

&

F

Æ„#dð¤< ¤<^„#a$gd2¡$

Æhd¤< ¤<a$gd2¡$

&

F

Æ „„äýd ¤x^„'„äýa$gd2¡-$

&

F

Æ „„äýd¤x ¤^„'„äýa$gd2¡($

&

F

Æðd¤ð ¤$d-D@&MÆ

ÿóóóNÆÿa$gd2¡$

&

F

Æ„d¤< ¤<^„a$gd2¡B ¶ Æ È Ö Ø Þ à î ð ö Ú¡â¡<£'£d£Ž£-£B¤"¤-¤æ¤

¥¥Ô¥Ü¥ª¦¸¦¼¦þ¦Š¨ïÙÃÙÃÙÃÙÃÙ¯›¯›¯ïˆïˆïˆïˆïˆïvïcN(h2¡h2¡CJOJPJQJRHi^JaJ$h2¡h2¡CJOJPJQJ^JaJ#h2¡h2¡6�CJOJPJQJaJ$h2¡h2¡CJOJPJQJ^JaJ'h2¡h2¡5�CJOJPJQJ^JaJ'h2¡h2¡5�CJOJPJQJ^JaJ*h2¡h2¡5�CJOJPJQJ\�^JaJ*h2¡h2¡5�CJOJPJQJ\�^JaJ h2¡h2¡CJOJPJQJaJ-¤è¤¼¦þ¦§Z§d§º§ ¨f¨z¨†¨Š¨Ü¨T©åÒªÒª*$

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9d¤x ¤xa$gd2¡m$'

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9dð¤x ¤xgd2¡m$$

Æhd¤< ¤<a$gd2¡$

&

F

Æ„#dð¤< ¤x^„#a$gd2¡ Š¨¤¨È¨Ü¨T©ž©Ä©ä© ªªªªÚªÜª:«<«

¬ ¬X­'­Ð­Ø­f®Š®¯&¯.¯R¯l¯‚¯Î°ê°î°±±$±z±Ž±-±ª±à±²ô²ü²r³ïÝïÉﶡïÝïÝï�ï�ï�ïzïzïzïzïzïzïÝïÝïÝïÝïÝïzïzï$h2¡h2¡CJOJPJQJ^JaJ'h2¡h2¡5�CJOJPJQJ^JaJ(h2¡h2¡CJOJPJQJRHi^JaJ$h2¡h2¡CJOJPJQJ^JaJ'h2¡h2¡5�CJOJPJQJ^JaJ#h2¡h2¡6�CJOJPJQJaJ h2¡h2¡CJOJPJQJaJ,T©ž©Ä©Î©Ú©ä©¾¬$®V¯È±r³ìÄ™™™ììì$

&

F

Æ„d¤< ¤<^„a$gd2¡*$

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9d¤x ¤xa$gd2¡m$'

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9dð¤x ¤xgd2¡m$$

Æhd¤< ¤<a$gd2¡

r³x³z³Š³Œ³"³-³ž³ ³À³Â³Î³ž'¤'¨'²'¶'À'Ê'Ö'xµÈµ'¶Â¶Ê¶Ö¶ ·.·b·f·j·Ò»Ö»D¿R¿º¿È¿ÀêÔêÔêÔêÔêÔêÀ¬À¬À¬À¬À¬À¬À¬À¬À-À...s...'...¬...$h2¡h2¡CJOJPJQJ^JaJ#h2¡h2¡6�CJOJPJQJaJ h2¡h2¡CJOJPJQJaJ*h2¡h2¡5�6�CJOJPJQJ^JaJ'h2¡h2¡5�CJOJPJQJ^JaJ'h2¡h2¡5�CJOJPJQJ^JaJ*h2¡h2¡5�CJOJPJQJ\�^JaJ*h2¡h2¡5�CJOJPJQJ\�^JaJ%r³Î³''j·¤¼rÃÆ ÆÖ·š‡‡‡_'

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9dð¤x ¤xgd2¡m$$

Æhd¤< ¤<a$gd2¡$

&

F

Æ „„äýd ¤x^„'„äýa$gd2¡-$

&

F

Æ „„äýd¤x ¤^„'„äýa$gd2¡($

&

F

Æðd¤ð ¤$d-D@&MÆ

ÿóóóNÆÿa$gd2¡ À À¢À°ÀjÁxÁ|Á€Á¤Á°Á„Â'š¦ÂÃÞöÃÄ

ÄÄÄ"Ä,Ä:ÄDÄÜÄêÄòÄÅlÅvÅÆÆ Æ6ÌVÌzÌžÌÈÌÍ

ÍÍ͆ÍâÍôÍ Î:Î@ÎHÎRÎÏ Ï(Ï6ϨÐíÜÈÜÈܶÜíÜíÜíÜíÜíÜíÜíÜíÜíÜíÜíÜíÜí£ŽÜíܶÜíÜíÜÈÜíÜíÜíÜíÜíÜ(h2¡h2¡CJOJPJQJRHi^JaJ$h2¡h2¡CJOJPJQJ^JaJ#h2¡h2¡6�CJOJPJQJaJ'h2¡h2¡5�CJOJPJQJ^JaJ h2¡h2¡CJOJPJQJaJ$h2¡h2¡CJOJPJQJ^JaJ8 Æ@Æ\Æ^ÆzÆ|ÆÀÆÂÆÇ

ÇdǞǰÇÈ~ÈêÈTɼÉ"ÊŠÊðÊXˤËÂËÔËÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔ*$

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9d¤x ¤xa$gd2¡m$ÔË&Ì2Ì6̆ÍâͶÐÆÑÈÑPÒ'ÒlÒxÒÔÔÔÁ™ÁÁÁ†sss$dð¤P ¤<$Ifa$gd2¡$

Æhdð¤< ¤<a$gd2¡'

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9dð¤x ¤xgd2¡m$$

Æhd¤< ¤<a$gd2¡*$

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9d¤x ¤xa$gd2¡m$

¨Ð²ÐÈÑØÑPÒxÒzÒ€Ò¢Ò¤ÒÂÒÌÒÓ"Ó&Ó(Ó.ÓPÓRÓ|Ó†ÓÖÓêÓîÓðÓöÓÔ Ô*Ô0ÔVÔ'ÔhÔvԚԜԢÔÊÔÌÔÖÔÚÔÕ

ÕíÜȵȤí'}ÜíÜíܤí'}ÜíÜíܤí'}ÜkÜíÜíܤí'}ÜkÜí#h2¡h2¡6�CJOJPJQJaJ'h2¡h2¡CJ OJPJQJRHi^J†*$h2¡h2¡CJ OJPJQJRHi^J h2¡h2¡CJ OJPJQJaJ $h2¡h2¡CJOJPJQJ^JaJ'h2¡h2¡5�CJOJPJQJ^JaJ h2¡h2¡CJOJPJQJaJ$h2¡h2¡CJOJPJQJ^JaJ*xÒzÒ€ÒD/$

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9dð¤P ¤$Ifa$gd2¡m$»kd�$$IfT-l4ÖÖF8¨

ð€F8ÿÿÿÿÿÿÿÿÿÿÿÿ€Fpÿÿÿÿÿÿÿÿÿÿÿÿ€FHÿÿÿÿÿÿÿÿÿÿÿÿ Ö

tàÖÿÿÿÖ0ÿÿÿÿÿÿ ö6Ö

ÿÿÿÖ

ÿÿÿÿÿÿÿÿÿÿÿÿÖ

ÿÿÿÿÿÿÿÿÿÿÿÿÖ

ÿÿÿÿÿÿÿÿÿÿÿÿ4Ö4Ö

lBÖaölf4pÖÿÿÿyt2¡ŠT€Ò¤Ò&Ó(Óй#•kd¨$$IfT-l4ÖÖF8¨

ð€F8ÿÿÿÿÿÿÿÿ€Fpÿÿÿÿÿÿÿÿ€FHÿÿÿÿÿÿÿÿ

tàÖ0ÿÿÿÿÿÿ ö6Ö

ÿÿÿÖ

ÿÿÿÿÿÿÿÿÿÿÿÿÖ

ÿÿÿÖ

ÿÿÿÿÿÿÿÿÿÿÿÿ4Ö4Ö

lBÖaölf4yt2¡ŠT$

Æhd¤P ¤<$Ifa$gd2¡/$

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9d¤P ¤<$Ifa$gd2¡m$(Ó.ÓRÓîÓСŠ$

Æhd¤P ¤<$Ifa$gd2¡/$

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9d¤P ¤<$Ifa$gd2¡m$/$

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9dð¤P ¤$Ifa$gd2¡m$îÓðÓöÓi:/$

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9dð¤P ¤$Ifa$gd2¡m$•kdu$$IfT-l4ÖÖF8¨

ð€F8ÿÿÿÿÿÿÿÿ€Fpÿÿÿÿÿÿÿÿ€FHÿÿÿÿÿÿÿÿ

tàÖ0ÿÿÿÿÿÿ ö6Ö

ÿÿÿÖ

ÿÿÿÿÿÿÿÿÿÿÿÿÖ

ÿÿÿÖ

ÿÿÿÿÿÿÿÿÿÿÿÿ4Ö4Ö

lBÖaölf4yt2¡ŠTöÓ ÔšÔœÔй#•kdB$$IfT-l4ÖÖF8¨

ð€F8ÿÿÿÿÿÿÿÿ€Fpÿÿÿÿÿÿÿÿ€FHÿÿÿÿÿÿÿÿ

tàÖ0ÿÿÿÿÿÿ ö6Ö

ÿÿÿÖ

ÿÿÿÿÿÿÿÿÿÿÿÿÖ

ÿÿÿÖ

ÿÿÿÿÿÿÿÿÿÿÿÿ4Ö4Ö

lBÖaölf4yt2¡ŠT$

Æhd¤P ¤<$Ifa$gd2¡/$

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9d¤P ¤<$Ifa$gd2¡m$œÔ¢ÔÌÔHÕСŠ$

Æhd¤P ¤<$Ifa$gd2¡/$

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9d¤P ¤<$Ifa$gd2¡m$/$

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9dð¤P ¤$Ifa$gd2¡m$

ÕÕ$ÕHÕJÕPÕ'Õ"ÕüÕÖÖ ÖXÖfÖ"Ö-Ö˜ÖJØÈØÎØøØFÙjÙ'ÙFÚnÚðÚÛNÛ'ÛÄÛÎÛ ÜbÜ°ÜÊÜòܤݪÝF|G¤GäGìG4H\H²H¶HúHïÜïËܸ¤ïÜïÜïÜïËï�ïÜïÜïÜïÜïÜïÜïÜïܸïÜïÜŽïÜïÜïÜï|ï#h2¡h2¡6�CJOJPJQJaJU'h2¡h2¡5�CJOJPJQJ^JaJ'h2¡h2¡CJ OJPJQJRHi^J†*$h2¡h2¡CJ OJPJQJRHi^J h2¡h2¡CJ OJPJQJaJ $h2¡h2¡CJOJPJQJ^JaJ h2¡h2¡CJOJPJQJaJ0HÕJÕPÕi:/$

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9dð¤P ¤$Ifa$gd2¡m$•kd$$IfT-l4ÖÖF8¨

ð€F8ÿÿÿÿÿÿÿÿ€Fpÿÿÿÿÿÿÿÿ€FHÿÿÿÿÿÿÿÿ

tàÖ0ÿÿÿÿÿÿ ö6Ö

ÿÿÿÖ

ÿÿÿÿÿÿÿÿÿÿÿÿÖ

ÿÿÿÖ

ÿÿÿÿÿÿÿÿÿÿÿÿ4Ö4Ö

lBÖaölf4yt2¡ŠTPÕ"Õ"Ö-Öй#•kdÜ$$IfT-l4ÖÖF8¨

ð€F8ÿÿÿÿÿÿÿÿ€Fpÿÿÿÿÿÿÿÿ€FHÿÿÿÿÿÿÿÿ

tàÖ0ÿÿÿÿÿÿ ö6Ö

ÿÿÿÖ

ÿÿÿÿÿÿÿÿÿÿÿÿÖ

ÿÿÿÖ

ÿÿÿÿÿÿÿÿÿÿÿÿ4Ö4Ö

lBÖaölf4yt2¡ŠT$

Æhd¤P ¤<$Ifa$gd2¡/$

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9d¤P ¤<$Ifa$gd2¡m$-Ö˜ÖJØ ÜbÜ°ÜðG�IäI6J„JZL®LðL MìÐì¨}ìì¨}}ì¨}}*$

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9d¤x ¤xa$gd2¡m$'

Æ2"( ¼

P äx

4 È#\'ð*„.2¬5@9dð¤x ¤xgd2¡m$$

&

F

Æ„#„Ýýd ¤x^„#'„Ýýa$gd2¡$

Æhd¤< ¤<a$gd2¡ . Tuy nhiên, bßi vì trình biên dËch th­t sñ bÏ qua các lÝi gÍi ph°¡ng théc, nên mã cça b¡n không thà phå thuÙc vào các giá trË tr£ vÁ të ph°¡ng théc. iÁu này có ngh)a là b¡n có thà áp dång ConditionalAttribute chÉ vÛi các ph°¡ng théc tr£ vÁ void.

B¡n có thà áp dång nhiÁu thà hiÇn ConditionalAttribute cho mÙt ph°¡ng théc, t°¡ng °¡ng vÛi phép OR lu­n lý. Các lÝi gÍi ph°¡ng théc DumpState d°Ûi ây chÉ °ãc biên dËch n¿u DEBUG ho·c TEST °ãc Ënh ngh)a.

[System.Diagnostics.Conditional("DEBUG")]

[System.Diagnostics.Conditional("TEST")]

public static void DumpState() {//...}

ViÇc thñc hiÇn phép AND lu­n lý c§n sí dång ph°¡ng théc iÁu kiÇn trung gian, khi¿n cho mã trß nên quá phéc t¡p, khó hiÃu và khó b£o trì. Ví då d°Ûi ây c§n ph°¡ng théc trung gian DumpState2 Ã Ënh ngh)a c£ hai ký hiÇu DEBUG và TEST.

[System.Diagnostics.Conditional("DEBUG")]

public static void DumpState() {

DumpState2();

}

[System.Diagnostics.Conditional("TEST")]

public static void DumpState2() {//...}

Các lÛp Debug và Trace thuÙc không gian tên System.Diagnostics sí dång ·c tính ConditionalAttribute trong nhiÁu ph°¡ng théc cça chúng. Các ph°¡ng théc cça lÛp Debug tùy thuÙc vào viÇc Ënh ngh)a ký hiÇu DEBUG, còn các ph°¡ng théc cça lÛp Trace tùy thuÙc vào viÇc Ënh ngh)a ký hiÇu TRACE.

Truy xu¥t mÙt ph§n tí ch°¡ng trình

có tên trùng vÛi mÙt të khóa

B¡n c§n truy xu¥t mÙt thành viên cça mÙt kiÃu, nh°ng tên kiÃu ho·c tên thành viên này trùng vÛi mÙt të khóa cça C#.

·t ký hiÇu @ vào tr°Ûc các tên trùng vÛi të khóa.

.NET Framework cho phép b¡n sí dång các thành ph§n ph§n mÁm (software component) °ãc phát triÃn b±ng các ngôn ngï .NET khác bên trong éng dång C# cça b¡n. M×i ngôn ngï Áu có mÙt t­p të khóa (ho·c të dành riêng) cho nó và có các h¡n ch¿ khác nhau Ñi vÛi các tên mà l­p trình viên có thà gán cho các ph§n tí ch°¡ng trình nh° kiÃu, thành viên, và bi¿n. Do ó, có kh£ nng mÙt thành ph§n °ãc phát triÃn trong mÙt ngôn ngï khác tình cÝ sí dång mÙt të khóa cça C# à ·t tên cho mÙt ph§n tí nào ó. Ký hiÇu @ cho phép b¡n sí dång mÙt të khóa cça C# làm Ënh danh và kh¯c phåc viÇc ång Ù tên. o¡n mã sau t¡o mÙt Ñi t°ãng kiÃu operator và thi¿t l­p thuÙc tính volatile cça nó là true (c£ operator và volatile Áu là të khóa cça C#):

// T¡o Ñi t°ãng operator.

@operator Operator1 = new @operator();

// Thi¿t l­p thuÙc tính volatile cça operator.

Operator1.@volatile = true;

T¡o và qu£n lý c·p khóa tên m¡nh

B¡n c§n t¡o mÙt c·p khóa công khai và khóa riêng (public key và private key) Ã gán tên m¡nh cho assembly.

Sí dång công cå Strong Name (sn.exe) Ã t¡o c·p khóa và l°u trï chúng trong mÙt file ho·c trong mÙt kho chéa khóa Cryptographic Service Provider.

Cryptographic Service Provider (CSP) là mÙt ph§n tí cça Win32 CryptoAPI, cung c¥p các dËch vå nh° m­t hóa, gi£i m­t hóa và t¡o chï ký sÑ. CSP còn cung c¥p các tiÇn ích cho kho chéa khóa (key container) nh° sí dång gi£i thu­t m­t hóa m¡nh và các biÇn pháp b£o m­t cça hÇ iÁu hành à b£o vÇ nÙi dung cça kho chéa khóa. CSP và CryptoAPI không °ãc Á c­p §y ç trong quyÃn sách này, b¡n hãy tham kh£o thêm trong tài liÇu SDK.

à t¡o mÙt c·p khóa mÛi và l°u trï chúng trong file có tên là MyKey.snk, thñc thi lÇnh sn k MyKey.snk (ph§n mß rÙng .snk th°Ýng °ãc sí dång cho các file chéa khóa tên m¡nh). File °ãc t¡o ra chéa c£ khóa công khai và khóa riêng. B¡n có thà sí dång lÇnh sn tp MyKey.snk à xem khóa công khai, lÇnh này cho k¿t xu¥t nh° sau:

Microsoft (R) .NET Framework Strong Name Utility Version 1.1.4322.573

Copyright (C) Microsoft Corporation 1998-2002. All rights reserved.

Public key is

07020000002400005253413200040000010001008bb302ef9180bf717ace00d570dd649821f24ed578fdccf1bc4017308659c126570204bc4010fdd1907577df1c2292349d9c2de33e49bd991a0a5bc9b69e5fd95bafad658a57b8236c5bd9a43be022a20a52c2bd8145448332d5f85e9ca641c26a4036165f2f353942b643b10db46c82d6d77bbc210d5a7c5aca84d7acb52cc1654759c62aa34988...

Public key token is f7241505b81b5ddc

Token cça khóa công khai là 8 byte cuÑi cça mã bm °ãc tính ra të khóa công khai. Vì khóa công khai quá dài nên .NET sí dång token cho måc ích hiÃn thË, và là mÙt c¡ ch¿ ng¯n gÍn cho các assembly khác tham chi¿u khóa công khai (ch°¡ng 14 s½ th£o lu­n tÕng quát vÁ mã bm).

Nh° tên gÍi cça nó, khóa công khai (ho·c token cça khóa công khai) không c§n °ãc giï bí m­t. Khi b¡n t¡o tên m¡nh cho assembly (°ãc th£o lu­n trong måc 1.9), trình biên dËch s½ sí dång khóa riêng à t¡o mÙt chï ký sÑ (mÙt mã bm ã-°ãc-m­t-hóa) cça assembly manifest. Trình biên dËch nhúng chï ký sÑ và khóa công khai vào assembly à ng°Ýi dùng có thà kiÃm tra chï ký sÑ.

ViÇc giï bí m­t khóa riêng là c§n thi¿t vì ng°Ýi truy xu¥t vào khóa riêng cça b¡n có thà thay Õi assembly và t¡o mÙt tên m¡nh mÛi khi¿n cho khách hàng cça b¡n không bi¿t mã nguÓn ã bË sía Õi. Không có c¡ ch¿ nào à lo¡i bÏ các khóa tên m¡nh ã bË tÕn h¡i. N¿u khóa riêng bË tÕn h¡i, b¡n ph£i t¡o khóa mÛi và phân phÑi phiên b£n mÛi cça assembly (°ãc ·t tên m¡nh b±ng các khóa mÛi). B¡n cing c§n thông báo cho khách hàng bi¿t là khóa ã bË tÕn h¡i và hÍ nên sí dång phiên b£n nào trong tr°Ýng hãp này, b¡n bË m¥t c£ tiÁn b¡c và uy tín. Có nhiÁu cách à b£o vÇ khóa riêng cça b¡n; sí dång cách nào là tùy vào các y¿u tÑ nh°:

C¥u trúc và t§m cá cça tÕ chéc.

Quá trình phát triÃn và phân phÑi éng dång.

Ph§n mÁm và ph§n céng hiÇn có.

Yêu c§u cça khách hàng.

Thông th°Ýng, mÙt nhóm nhÏ các cá nhân áng tin c­y (°ãc gÍi là signing authority) s½ có trách nhiÇm £m b£o an toàn cho các khóa tên m¡nh cça công ty và ký mÍi assembly tr°Ûc khi chúng °ãc phân phÑi. Kh£ nng trì hoãn ký assembly (s½ °ãc th£o lu­n ß måc 1.11) t¡o iÁu kiÇn thu­n lãi cho viÇc éng dång mô hình này và tránh °ãc viÇc b¡n ph£i phân phÑi khóa riêng cho mÍi thành viên cça nhóm phát triÃn.

Công cå Strong Name còn cung c¥p tính nng sí dång kho chéa khóa CSP à ¡n gi£n hóa viÇc b£o m­t các khóa tên m¡nh. MÙt khi ã t¡o mÙt c·p khóa trong mÙt file, b¡n có thà cài ·t các khóa này vào kho chéa khóa CSP và xóa file i. Ví då, à l°u trï c·p khóa n±m trong file MyKey.snk vào mÙt kho chéa khóa CSP có tên là StrongNameKeys, sí dång lÇnh sn -i MyKeys.snk StrongNameKeys (måc 1.9 s½ gi£i thích cách sí dång các khóa tên m¡nh °ãc l°u trï trong mÙt kho chéa khóa CSP).

MÙt khía c¡nh quan trÍng cça kho chéa khóa CSP là có các kho chéa khóa dña-theo ng°Ýi-dùng và có các kho chéa khóa dña-theo-máy. C¡ ch¿ b£o m­t cça Windows b£o £m ng°Ýi dùng chÉ truy xu¥t °ãc kho chéa khóa dña-theo-ng°Ýi-dùng cça chính hÍ. Tuy nhiên, b¥t kó ng°Ýi dùng nào cça máy Áu có thà truy xu¥t kho chéa khóa dña-theo-máy.

Theo m·c Ënh, công cå Strong Name sí dång kho chéa khóa dña-theo-máy, ngh)a là mÍi ng°Ýi ng nh­p vào máy và bi¿t tên cça kho chéa khóa Áu có thà ký mÙt assembly b±ng các khóa tên m¡nh cça b¡n. à công cå Strong Name sí dång kho chéa khóa dña-theo-ng°Ýi-dùng, sí dång lÇnh sn m n; khi muÑn trß l¡i kho chéa khóa dña-theo-máy, sí dång lÇnh sn m y. LÇnh sn m s½ cho bi¿t công cå Strong Name hiÇn °ãc c¥u hình là sí dång kho chéa khóa dña-theo-ng°Ýi-dùng hay dña-theo-máy.

à xóa các khóa tên m¡nh të kho StrongNameKeys (cing nh° xóa c£ kho này), sí dång lÇnh sn d StrongNameKeys.

T¡o tên m¡nh cho assembly

B¡n c§n t¡o tên m¡nh cho mÙt assembly à nó:

Có mÙt Ënh danh duy nh¥t, cho phép gán các quyÁn cå thà vào assembly khi c¥u hình Code Access Security Policy (chính sách b£o m­t cho viÇc truy xu¥t mã lÇnh).

Không thà bË sía Õi và sau ó m¡o nh­n là nguyên b£n.

H× trã viÇc ánh sÑ phiên b£n và các chính sách vÁ phiên b£n (version policy).

Có thà °ãc chia s» trong nhiÁu éng dång, và °ãc cài ·t trong Global Assembly Cache (GAC).

Sí dång các ·c tính (attribute) méc-assembly à chÉ Ënh n¡i chéa c·p khóa tên m¡nh, và có thà chÉ Ënh thêm sÑ phiên b£n và thông tin b£n Ëa cho assembly. Trình biên dËch s½ t¡o tên m¡nh cho assembly trong quá trình xây dñng.

à t¡o tên m¡nh cho mÙt assembly b±ng trình biên dËch C#, b¡n c§n các y¿u tÑ sau:

MÙt c·p khóa tên m¡nh n±m trong mÙt file ho·c mÙt kho chéa khóa CSP (xem måc 1.8 vÁ cách t¡o c·p khóa tên m¡nh).

Sí dång các ·c tính méc-assembly à chÉ Ënh n¡i trình biên dËch có thà tìm th¥y c·p khóa tên m¡nh ó.

N¿u c·p khóa n±m trong mÙt file, áp dång ·c tính System.Reflection. AssemblyKeyFileAttribute cho assembly và chÉ Ënh tên file chéa các khóa.

N¿u c·p khóa n±m trong mÙt kho chéa khóa CSP, áp dång ·c tính System.Reflection.AssemblyKeyNameAttribute cho assembly và chÉ Ënh tên cça kho chéa khóa.

Ngoài ra, b¡n có thà tùy chÍn:

Áp dång ·c tính System.Reflection.AssemblyCultureAttribute cho assembly à chÉ Ënh thông tin b£n Ëa mà assembly h× trã (B¡n không thà chÉ Ënh b£n Ëa cho các assembly thñc thi vì assembly thñc thi chÉ h× trã b£n Ëa trung l­p).

Áp dång ·c tính System.Reflection.AssemblyVersionAttribute cho assembly à chÉ Ënh phiên b£n cça assembly.

o¡n mã d°Ûi ây (trong file HelloWorld.cs) minh hÍa cách sí dång các ·c tính (ph§n in ­m) Ã chÉ Ënh khóa, b£n Ëa, và phiên b£n cho assembly:

using System;

using System.Reflection;

[assembly:AssemblyKeyName("MyKeys")]

[assembly:AssemblyCulture("")]

[assembly:AssemblyVersion("1.0.0.0")]

public class HelloWorld {

public static void Main() {

Console.WriteLine("Hello, world");

}

}

à t¡o mÙt assembly tên m¡nh të o¡n mã trên, t¡o các khóa tên m¡nh và l°u trï chúng trong file MyKeyFile b±ng lÇnh sn -k MyKeyFile.snk. Sau ó, sí dång lÇnh sn -i MyKeyFile.snk MyKeys à cài ·t các khóa vào mÙt kho chéa khóa CSP có tên là MyKeys. CuÑi cùng, sí dång lÇnh csc HelloWorld.cs à biên dËch file HelloWorld.cs thành mÙt assembly tên m¡nh.

B¡n cing có thà sí dång công cå Assembly Linker (al.exe) à t¡o assembly tên m¡nh, cách này cho phép chÉ Ënh các thông tin tên m¡nh trên dòng lÇnh thay vì sí dång các ·c tính trong mã nguÓn. Cách này hïu ích khi b¡n không muÑn nhúng các ·c tính tên m¡nh vào file nguÓn và khi b¡n sí dång kËch b£n à xây dñng nhïng cây mã nguÓn Ó sÙ. Xem thêm thông tin vÁ Assembly Linker trong tài liÇu .NET Framework SDK.

Xác minh mÙt assembly tên m¡nh không bË sía Õi

B¡n c§n xác minh r±ng mÙt assembly tên m¡nh ch°a hÁ bË sía Õi sau khi nó °ãc biên dËch.

Sí dång công cå Strong Name (sn.exe) Ã xác minh tên m¡nh cça assembly.

M×i khi n¡p mÙt assembly tên m¡nh, bÙ thñc thi .NET l¥y mã bm ã-°ãc-m­t-hóa (°ãc nhúng trong assembly) và gi£i m­t hóa vÛi khóa công khai (cing °ãc nhúng trong assembly). Sau ó, bÙ thñc thi tính mã bm cça assembly manifest và so sánh nó vÛi mã bm vëa-°ãc-gi£i-m­t-hóa. Quá trình xác minh này s½ nh­n bi¿t assembly có bË thay Õi sau khi biên dËch hay không.

N¿u mÙt quá trình xác minh tên m¡nh th¥t b¡i vÛi mÙt assembly thñc thi, bÙ thñc thi s½ hiÃn thË hÙp tho¡i nh° hình 1.2. N¿u cÑ n¡p mÙt assembly ã th¥t b¡i trong quá trình xác minh, bÙ thñc thi s½ ném ngo¡i lÇ System.IO.FileLoadException vÛi thông iÇp Strong name validation failed .

SHAPE \* MERGEFORMAT

Hình 1.2 L×i khi cÑ thñc thi mÙt assembly tên m¡nh ã bË sía Õi

Ngoài viÇc t¡o và qu£n lý các khóa tên m¡nh (ã °ãc th£o lu­n trong måc 1.8), công cå Strong Name còn cho phép xác minh các assembly tên m¡nh. à xác minh assembly tên m¡nh HelloWorld.exe không bË sía Õi, sí dång lÇnh sn -vf HelloWorld.exe. Ñi sÑ -v yêu c§u công cå Strong Name xác minh tên m¡nh cça mÙt assembly xác Ënh, Ñi sÑ -f buÙc thñc hiÇn viÇc xác minh tên m¡nh ngay c£ nó ã bË vô hiÇu tr°Ûc ó cho mÙt assembly nào ó. (B¡n có thà sí dång Ñi sÑ -Vr à vô hiÇu viÇc xác minh tên m¡nh Ñi vÛi mÙt assembly, ví då sn -Vr HelloWorld.exe; måc 1.11 s½ trình bày lý do t¡i sao c§n vô hiÇu viÇc xác minh tên m¡nh).

N¿u assembly này °ãc xác minh là không Õi, b¡n s½ th¥y k¿t xu¥t nh° sau:

Microsoft (R) .NET Framework Strong Name Utility Version 1.1.4322.573

Copyright (C) Microsoft Corporation 1998-2002. All rights reserved.

Assembly 'HelloWorld.exe' is valid

Tuy nhiên, n¿u assembly này ã bË sía Õi, b¡n s½ th¥y k¿t xu¥t nh° sau:

Microsoft (R) .NET Framework Strong Name Utility Version 1.1.4322.573

Copyright (C) Microsoft Corporation 1998-2002. All rights reserved.

Failed to verify assembly -- Unable to format error message 8013141A

Hoãn viÇc ký assembly

B¡n c§n t¡o mÙt assembly tên m¡nh, nh°ng không muÑn mÍi thành viên trong nhóm phát triÃn truy xu¥t khóa riêng cça c·p khóa tên m¡nh.

Trích xu¥t và phân phÑi khóa công khai cça c·p khóa tên m¡nh. Làm theo h°Ûng d«n trong måc 1.9 à t¡o tên m¡nh cho assembly. Áp dång ·c tính System.Reflection.AssemblyDelaySignAttribute cho assembly à chÉ Ënh nó là assembly s½ °ãc ký sau. Sí dång Ñi sÑ -Vr cça công cå Strong Name (sn.exe) à vô hiÇu viÇc xác minh tên m¡nh cho assembly này.

Các assembly tham chi¿u ¿n assembly tên m¡nh s½ chéa token cça assembly °ãc tham chi¿u, ngh)a là assembly °ãc tham chi¿u ph£i °ãc t¡o tên m¡nh tr°Ûc khi °ãc tham chi¿u. Trong mÙt môi tr°Ýng phát triÃn mà assembly th°Ýng xuyên °ãc xây dñng l¡i, m×i ng°Ýi phát triÃn và kiÃm thí Áu c§n có quyÁn truy xu¥t c·p khóa tên m¡nh cça b¡n ây là mÙt nguy c¡ b£o m­t chç y¿u.

Thay vì phân phÑi khóa riêng cho mÍi thành viên cça nhóm phát triÃn, .NET Framework cung c¥p c¡ ch¿ hoãn viÇc ký mÙt assembly (°ãc gÍi là delay signing), theo ó b¡n có thà t¡o tên m¡nh không hoàn chÉnh cho assembly (t¡m gÍi là tên m¡nh bán ph§n). Tên m¡nh bán ph§n này chÉ chéa khóa công khai và token cça khóa công khai (c§n thi¿t à tham chi¿u assembly), nh°ng chëa ch× cho chï ký s½ °ãc t¡o ra të khóa riêng sau này.

Khi quá trình phát triÃn hoàn t¥t, signing authority (ng°Ýi chËu trách nhiÇm vÁ viÇc b£o m­t và viÇc sí dång c·p khóa tên m¡nh) s½ ký l¡i assembly ã bË hoãn tr°Ûc ó à hoàn thành tên m¡nh cho nó. Chï ký °ãc tính toán dña trên khóa riêng và °ãc nhúng vào assembly, và giÝ ây b¡n ã có thà phân phÑi assembly.

Khi hoãn viÇc ký mÙt assembly, b¡n chÉ c§n truy xu¥t khóa công khai cça c·p khóa tên m¡nh. Không có nguy c¡ b£o m­t nào të viÇc phân phÑi khóa công khai, và signing authority ph£i phân phÑi khóa công khai ¿n mÍi thành viên cça nhóm phát triÃn. à trích xu¥t khóa công khai të file MyKeys.snk và ghi nó vào file MyPublicKey.snk, sí dång lÇnh sn -p MyKeys.snk MyPublicKey.snk. N¿u b¡n l°u trï c·p khóa tên m¡nh trong mÙt kho chéa khóa CSP có tên là MyKeys, sí dång lÇnh sn -pc MyKeys MyPublicKey.snk à trích xu¥t khóa công khai ra rÓi l°u trï nó vào file MyPublicKey.snk.

Ví då d°Ûi ây áp dång các ·c tính ã °ãc th£o lu­n trong måc 1.9 à khai báo phiên b£n, b£n Ëa, và n¡i chéa khóa công khai. Óng thÝi áp dång ·c tính AssemblyDelaySign(true) cho assembly à báo cho trình biên dËch bi¿t b¡n muÑn trì hoãn viÇc ký assembly.

using System;

using System.Reflection;

[assembly:AssemblyKeyFile("MyPublicKey.snk")]

[assembly:AssemblyCulture("")]

[assembly:AssemblyVersion("1.0.0.0")]

[assembly:AssemblyDelaySign(true)]

public class HelloWorld {

public static void Main() {

Console.WriteLine("Hello, world");

}

}

Khi cÑ n¡p mÙt assembly bË hoãn ký, bÙ thñc thi s½ nh­n ra assembly này có tên m¡nh và cÑ xác minh assembly (nh° °ãc th£o lu­n trong måc 1.10). Nh°ng vì không có chï ký sÑ nên b¡n ph£i vô hiÇu chéc nng xác minh này b±ng lÇnh sn -Vr HelloWorld.exe.

Khi quá trình phát triÃn hoàn t¥t, b¡n c§n ký l¡i assembly à hoàn thành tên m¡nh cho assembly. Công cå Strong Name cho phép thñc hiÇn iÁu này mà không c§n thay Õi mã nguÓn ho·c biên dËch l¡i assembly, tuy nhiên, b¡n ph£i có quyÁn truy xu¥t khóa riêng cça c·p khóa tên m¡nh. à ký l¡i assembly có tên là HelloWorld.exe vÛi c·p khóa n±m trong file MyKeys.snk, sí dång lÇnh sn -R HelloWorld.exe MyKeys.snk. N¿u c·p khóa °ãc l°u trï trong mÙt kho chéa khóa CSP có tên là MyKeys, sí dång lÇnh sn -Rc HelloWorld.exe MyKeys.

Sau khi ã ký l¡i assembly, b¡n ph£i mß chéc nng xác minh tên m¡nh cho assembly b±ng Ñi sÑ -Vu cça công cå Strong Name, ví då sn -Vu HelloWorld.exe. à kích ho¡t l¡i viÇc xác minh tên m¡nh cho t¥t c£ các assembly ã bË b¡n vô hiÇu tr°Ûc ó, sí dång lÇnh sn Vx. Sí dång lÇnh sn -Vl à xem danh sách các assembly ã bË vô hiÇu chéc nng này.

Khi sí dång assembly ký sau, b¡n nên so sánh các l§n xây dñng khác nhau cça assembly à b£o £m chúng chÉ khác nhau ß chï ký. iÁu này chÉ có thà thñc hiÇn °ãc n¿u assembly ã °ãc ký l¡i b±ng Ñi sÑ -R cça công cå Strong Name. Sí dång lÇnh sn -D assembly1 assembly2 à so sánh hai assembly.

SHAPE \* MERGEFORMAT

Hình 1.3 T¡m hoãn viÇc ký assembly

SHAPE \* MERGEFORMAT

Hình 1.4 Ký l¡i assembly

Ký assembly vÛi chï ký sÑ Authenticode

B¡n c§n ký mÙt assembly b±ng Authenticode à ng°Ýi dùng bi¿t b¡n chính là ng°Ýi phát hành (publisher) và assembly không bË sía Õi sau khi ký.

Sí dång công cå File Signing (signcode.exe) Ã ký assembly vÛi Software Publisher Certificate (SPC) cça b¡n.

Tên m¡nh cung c¥p mÙt Ënh danh duy nh¥t cing nh° chéng minh tính toàn v¹n cça mÙt assembly, nh°ng nó không xác minh ai là ng°Ýi phát hành assembly này. Do ó, .NET Framework cung c¥p kù thu­t Authenticode à ký assembly. iÁu này cho phép ng°Ýi dùng bi¿t b¡n là ng°Ýi phát hành và xác nh­n tính toàn v¹n cça assembly. Chï ký Authenticode còn °ãc sí dång làm chéng cé (evidence) cho assembly khi c¥u hình chính sách b£o m­t truy xu¥t mã lÇnh (Code Access Security Policy xem måc 13.9 và 13.10).

à ký mÙt assembly vÛi chï ký Authenticode, b¡n c§n mÙt SPC do mÙt Certificate Authority (CA) c¥p. CA °ãc trao quyÁn à c¥p SPC (cùng vÛi nhiÁu kiÃu chéng chÉ khác) cho các cá nhân ho·c công ty sí dång. Tr°Ûc khi c¥p mÙt chéng chÉ, CA có trách nhiÇm xác nh­n nhïng ng°Ýi yêu c§u và b£o £m hÍ ký k¿t không sí dång sai các chéng chÉ do CA c¥p.

à có °ãc mÙt SPC, b¡n nên xem Microsoft Root Certificate Program Members t¡i [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsecure/html/rootcertprog.asp]. Þ ây, b¡n có thà tìm th¥y danh sách các CA, nhiÁu CA trong sÑ ó có thà c¥p cho b¡n mÙt SPC. VÛi måc ích thí nghiÇm, b¡n có thà t¡o mÙt SPC thí nghiÇm theo quá trình s½ °ãc mô t£ trong måc 1.13. Tuy nhiên, b¡n không thà phân phÑi ph§n mÁm °ãc ký vÛi chéng chÉ thí nghiÇm này. Vì mÙt SPC thí nghiÇm không do mÙt CA áng tin c­y c¥p, nên h§u h¿t ng°Ýi dùng s½ không tin t°ßng assembly °ãc ký b±ng SPC thí nghiÇm này.

Khi ã có mÙt SPC, sí dång công cå File Signing à ký assembly cça b¡n. Công cå File Signing sí dång khóa riêng cça SPC à t¡o mÙt chï ký sÑ và nhúng chï ký này cùng ph§n công khai cça SPC vào assembly (bao gÓm khóa công khai). Khi xác minh mÙt assembly, ng°Ýi dùng sí dång khóa công khai à gi£i m­t hóa mã bm ã-°ãc-m­t-hóa, tính toán l¡i mã bm cça assembly, và so sánh hai mã bm này à b£o £m chúng là nh° nhau. Khi hai mã bm này trùng nhau, ng°Ýi dùng có thà ch¯c ch¯n r±ng b¡n ã ký assembly, và nó không bË thay Õi të khi b¡n ký.

Ví då, Ã ký mÙt assembly có tên là MyAssembly.exe vÛi mÙt SPC n±m trong file MyCert.spc và khóa riêng n±m trong file MyPrivateKey.pvk, sí dång lÇnh:

signcode -spc MyCert.spc -v MyPrivateKey.pvk MyAssembly.exe

Trong ví då này, công cå File Signing s½ hiÃn thË mÙt hÙp tho¡i nh° hình 1.5, yêu c§u b¡n nh­p m­t kh©u (°ãc sí dång à b£o vÇ khóa riêng trong file MyPrivateKey.pvk).

SHAPE \* MERGEFORMAT

Hình 1.5 Công cå File Signing yêu c§u nh­p m­t kh§u khi truy xu¥t file chéa khóa riêng

B¡n cing có thà truy xu¥t khóa và chéng chÉ trong các kho chéa. B£ng 1.2 liÇt kê các Ñi sÑ th°Ýng dùng nh¥t cça công cå File Signing. B¡n hãy tham kh£o tài liÇu .NET Framework SDK à xem t¥t c£ các Ñi sÑ.

B£ng 1.2 Các Ñi sÑ th°Ýng dùng cça công cå File Signing

Ñi sÑ Mô t£ -k ChÉ Ënh tên cça kho chéa khóa riêng SPC -s ChÉ Ënh tên cça kho chéa SPC -spc ChÉ Ënh tên file chéa SPC -v ChÉ Ënh tên file chéa khóa riêng SPC

à ký mÙt assembly gÓm nhiÁu file, b¡n c§n chÉ Ënh tên file chéa assembly manifest. N¿u muÑn sí dång c£ tên m¡nh và Authenticode cho assembly, b¡n ph£i t¡o tên m¡nh cho assembly tr°Ûc (xem cách t¡o tên m¡nh cho assembly trong måc 1.9).

à kiÃm tra tính hãp lÇ cça mÙt file °ãc ký vÛi chï ký Authenticode, sí dång công cå Certificate Verification (chktrust.exe). Ví då, sí dång lÇnh chktrust MyAssembly.exe à kiÃm tra file MyAssembly.exe. N¿u ch°a c¥u hình cho hÇ thÑng à nó tin t°ßng SPC dùng à ký assembly, b¡n s½ th¥y hÙp tho¡i t°¡ng tñ nh° hình 1.6, hiÃn thË thông tin vÁ ng°Ýi phát hành và cho b¡n chÍn là có tin t°ßng ng°Ýi phát hành ó hay không (chéng chÉ trong hình 1.6 là mÙt chéng chÉ thí nghiÇm °ãc t¡o theo quá trình °ãc mô t£ trong måc 1.13).

N¿u b¡n nh¯p Yes, ho·c tr°Ûc ó ã chÍn là luôn tin t°ßng SPC, công cå Certificate Verification xác nh­n tính hãp lÇ cça chï ký và assembly.

SHAPE \* MERGEFORMAT

Hình 1.6 Công cå Certificate Verification

T¡o và thi¿t l­p tin t°ßng mÙt SPC thí nghiÇm

B¡n c§n t¡o mÙt SPC Ã thí nghiÇm.

Sí dång công cå Certificate Creation (makecert.exe) Ã t¡o mÙt chéng chÉ X.509 và sí dång công cå Software Publisher Certificate (cert2spc.exe) Ã t¡o mÙt SPC të chéng chÉ X.509 này. Thi¿t l­p tin t°ßng chéng chÉ thí nghiÇm b±ng công cå Set Registry (setreg.exe).

à t¡o mÙt SPC thí nghiÇm cho mÙt nhà phát hành ph§n mÁm có tên là Square Nguyen, tr°Ûc h¿t sí dång công cå Certificate Creation à t¡o mÙt chéng chÉ X.509. LÇnh:

makecert -n "CN=Square Nguyen" -sk MyKeys TestCertificate.cer

s½ t¡o mÙt file có tên là TestCertificate.cer chéa mÙt chéng chÉ X.509, và l°u trï khóa riêng t°¡ng éng trong mÙt kho chéa khóa CSP có tên là MyKeys (°ãc t¡o tñ Ùng n¿u ch°a tÓn t¡i). B¡n cing có thà ghi khóa riêng vào file b±ng cách thay -sk b±ng -sv. Ví då, à ghi khóa riêng vào mÙt file có tên là PrivateKeys.pvk, sí dång lÇnh:

makecert -n "CN=Square Nguyen" -sv PrivateKey.pvk TestCertificate.cer

SHAPE \* MERGEFORMAT

Hình 1.7 Công cå Certificate Creation nh¯c nh­p m­t kh©u à b£o vÇ file chéa khóa riêng

N¿u b¡n ghi khóa riêng vào file, công cå Certificate Creation s½ nh¯c b¡n nh­p m­t kh©u à b£o vÇ file này (xem hình 1.7).

Công cå Certificate Creation h× trã nhiÁu Ñi sÑ, b£ng 1.3 liÇt kê mÙt vài Ñi sÑ th°Ýng dùng. Xem thêm tài liÇu .NET Framework SDK vÁ công cå Certificate Creation.

B£ng 1.3 Các Ñi sÑ th°Ýng dùng cça công cå Certificate Creation

Ñi sÑ Mô t£ -e ChÉ Ënh ngày chéng chÉ không còn hiÇu lñc. -m ChÉ Ënh kho£ng thÝi gian (tính b±ng tháng) mà chéng chÉ còn hiÇu lñc. -n ChÉ Ënh mÙt tên X.500 t°¡ng éng vÛi chéng chÉ. ây là tên cça ng°Ýi phát hành ph§n mÁm mà ng°Ýi dùng th¥y khi hÍ xem chi ti¿t cça SPC t¡o ra. -sk ChÉ Ënh tên CSP giï khóa riêng. -ss ChÉ Ënh tên kho chéng chÉ (công cå Certificate Creation s½ l°u chéng chÉ X.509 trong ó). -sv ChÉ Ënh tên file giï khóa riêng.

Khi ã t¡o mÙt chéng chÉ X.509 b±ng công cå Certificate Creation, c§n chuyÃn chéng chÉ này thành mÙt SPC b±ng công cå Software Publisher Certificate Test (cert2spc.exe). Ã chuyÃn TestCertificate.cer thành mÙt SPC, sí dång lÇnh:

cert2spc TestCertificate.cer TestCertificate.spc

Công cå Software Publisher Certificate Test không có Ñi sÑ tùy chÍn nào.

B°Ûc cuÑi cùng à sí dång SPC thí nghiÇm là thi¿t l­p tin t°ßng CA thí nghiÇm gÑc (root test CA); ây là ng°Ýi phát hành m·c Ënh các chéng chÉ thí nghiÇm. B°Ûc này chÉ c§n lÇnh setreg 1 true cça công cå Set Registry (setreg.exe). Khi k¿t thúc thí nghiÇm SPC, bÏ thi¿t l­p tin t°ßng Ñi vÛi CA thí nghiÇm b±ng lÇnh setreg 1 false. Bây giÝ, b¡n có thà sí dång SPC thí nghiÇm à ký assembly vÛi Authenticode nh° quá trình mô t£ ß måc 1.12.

Qu£n lý Global Assembly Cache

B¡n c§n thêm ho·c lo¡i bÏ assembly të Global Assembly Cache (GAC).

Sí dång công cå Global Assembly Cache (gacutil.exe) të dòng lÇnh à xem nÙi dung cça GAC, cing nh° thêm ho·c lo¡i bÏ assembly.

Tr°Ûc khi °ãc cài ·t vào GAC, assembly ph£i có tên m¡nh (xem måc 1.9 vÁ cách t¡o tên m¡nh cho assembly). Ã cài ·t assembly có tên là SomeAssembly.dll vào GAC, sí dång lÇnh gacutil /i SomeAssembly.dll.

à lo¡i bÏ SomeAssembly.dll ra khÏi GAC, sí dång lÇnh gacutil /u SomeAssembly. Chú ý không sí dång ph§n mß rÙng .dll à nói ¿n assembly mÙt khi nó ã °ãc cài ·t vào GAC.

à xem các assembly ã °ãc cài ·t vào GAC, sí dång lÇnh gacutil /l. LÇnh này s½ liÇt kê t¥t c£ các assembly ã °ãc cài ·t trong GAC, cing nh° danh sách các assembly ã °ãc biên dËch tr°Ûc sang d¡ng nhË phân và cài ·t trong NGEN cache. Sí dång lÇnh gacutil /l SomeAssembly à tránh ph£i tìm h¿t danh sách xem mÙt assembly ã °ãc cài ·t ch°a.

.NET Framework sí dång GAC chÉ khi thñc thi, trình biên dËch C# s½ không tìm trong GAC b¥t kó tham chi¿u ngo¡i nào mà assembly cça b¡n tham chi¿u ¿n. Trong quá trình phát triÃn, trình biên dËch C# ph£i truy xu¥t °ãc mÙt b£n sao cåc bÙ cça b¥t kó assembly chia s» nào °ãc tham chi¿u ¿n. B¡n có thà chép assembly chia s» vào th° måc mã nguÓn cça b¡n, ho·c sí dång Ñi sÑ /lib cça trình biên dËch C# à chÉ Ënh th° måc mà trình biên dËch có thà tìm th¥y các assembly c§n thi¿t trong ó.

Ngn ng°Ýi khác dËch ng°ãc mã nguÓn cça b¡n

B¡n muÑn b£o £m assembly .NET cça b¡n không bË dËch ng°ãc.

Xây dñng các gi£i pháp dña-trên-server n¿u có thà à ng°Ýi dùng không truy xu¥t assembly °ãc. N¿u b¡n ph£i phân phÑi assembly thì không có cách nào à ngn ng°Ýi dùng dËch ng°ãc chúng. Cách tÑt nh¥t có thà làm là sí dång kù thu­t obfuscation và các thành ph§n ã °ãc biên dËch thành mã lÇnh nguyên sinh (native code) à assembly khó bË dËch ng°ãc h¡n.

Vì assembly .NET bao gÓm mÙt t­p các mã lÇnh và siêu dï liÇu °ãc chu©n hóa, Ùc l­p nÁn t£ng mô t£ các kiÃu n±m trong assembly, nên chúng t°¡ng Ñi dÅ bË dËch ng°ãc. iÁu này cho phép các trình dËch ng°ãc dÅ dàng t¡o °ãc mã nguÓn r¥t giÑng vÛi mã gÑc, ây s½ là v¥n Á khó gi£i quy¿t n¿u mã cça b¡n có chéa các thông tin ho·c thu­t toán c§n giï bí m­t.

Cách duy nh¥t à £m b£o ng°Ýi dùng không thà dËch ng°ãc assembly là không cho hÍ l¥y °ãc assembly. N¿u có thÃ, hiÇn thñc các gi£i pháp dña-trên-server nh° các éng dång Microsoft ASP.NET và dËch vå Web XML. VÛi mÙt chính sách b£o m­t tÑt ß server, không ai có thà truy xu¥t assembly, do ó không thà dËch ng°ãc chúng.

N¿u viÇc xây dñng các gi£i pháp dña-trên-server là không phù hãp, b¡n có hai tùy chÍn sau ây:

Sí dång mÙt obfuscator à khi¿n cho assembly cça b¡n khó bË dËch ng°ãc (Visual Studio .NET 2003 có chéa phiên b£n Community cça mÙt obfuscator, có tên là Dotfuscator). Obfuscator sí dång nhiÁu kù thu­t khác nhau khi¿n cho assembly khó bË dËch ng°ãc; nguyên lý cça các kù thu­t này là:

Õi tên các tr°Ýng và các ph°¡ng théc private nh±m gây khó khn cho viÇc Íc và hiÃu måc ích cça mã lÇnh.

Chèn các lÇnh dòng iÁu khiÃn khi¿n cho ng°Ýi khác khó có thà l§n theo logic cça éng dång.

ChuyÃn nhïng ph§n cça éng dång mà b¡n muÑn giï bí m­t thành các Ñi t°ãng COM hay các DLL nguyên sinh, sau ó sí dång P/Invoke ho·c COM Interop à gÍi chúng të éng dång °ãc-qu£n-lý cça b¡n (xem ch°¡ng 15 vÁ cách gÍi mã lÇnh không-°ãc-qu£n-lý).

Không có cách ti¿p c­n nào ngn °ãc nhïng ng°Ýi có kù nng và quy¿t tâm dËch ng°ãc mã nguÓn cça b¡n, nh°ng chúng s½ làm cho công viÇc này trß nên khó khn áng kà và ngn °ãc h§u h¿t nh°ng k» tò mò thông th°Ýng.

Nguy c¡ mÙt éng dång bË dËch ng°ãc không chÉ riêng cho C# hay .NET. MÙt ng°Ýi quy¿t tâm có thà dËch ng°ãc b¥t kó ph§n mÁm nào n¿u anh ta có kù nng và thÝi gian.

H¿t ch°¡ng 1 .

Gmail : HYPERLINK "mailto:[email protected]" [email protected]

Yahoo : HYPERLINK "mailto:[email protected]" [email protected]

Bạn đang đọc truyện trên: Truyen2U.Pro