<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      C#綜合揭秘——通過(guò)修改注冊(cè)表建立Windows自定義協(xié)議

      引言

      本文主要介紹注冊(cè)表的概念與其相關(guān)根項(xiàng)的功能,以及瀏覽器如何通過(guò)連接調(diào)用自定義協(xié)議并與客戶(hù)端進(jìn)行數(shù)據(jù)通信。文中講及如何通過(guò)C#程序、手動(dòng)修改、安裝項(xiàng)目等不同方式對(duì)注冊(cè)表進(jìn)行修改。其中通過(guò)安裝項(xiàng)目對(duì)注冊(cè)表進(jìn)行修改的情況最為常見(jiàn),在一般的應(yīng)用程序中都會(huì)涉及。
      當(dāng)中最為實(shí)用的例子將介紹如何通過(guò)"安裝項(xiàng)目"修改注冊(cè)表建立自定義協(xié)議,在頁(yè)面通過(guò)ajax方式發(fā)送路徑請(qǐng)求,并在回調(diào)函數(shù)中調(diào)用自定義協(xié)議。
      最后一節(jié)還將介紹如何調(diào)用自定義協(xié)議去保持?jǐn)?shù)據(jù)的保密性。
      希望本篇文章能對(duì)各位的學(xué)習(xí)研究有所幫助,當(dāng)中有所錯(cuò)漏的地方敬請(qǐng)點(diǎn)評(píng)。

       

      目錄

      一、注冊(cè)表的概念

      二、以C#程序修改注冊(cè)表

      三、在 HKEY_CLASSES_ROOT 中添加自定義協(xié)議

      四、通過(guò)“安裝項(xiàng)目”方式修改注冊(cè)表

      五、自定義協(xié)議的調(diào)用

       

       

       

       

      一、注冊(cè)表的概念

      在談及Windows自定義協(xié)議之前,不得不預(yù)先介紹的是注冊(cè)表這個(gè)概念。注冊(cè)表是windows操作系統(tǒng)的一個(gè)核心數(shù)據(jù)庫(kù),其作用是充當(dāng)計(jì)算機(jī)上操作系統(tǒng)和應(yīng)用程序的中央信息儲(chǔ)存庫(kù),用于存放著各種系統(tǒng)級(jí)參數(shù)。它能直接控制著windows的啟動(dòng)、硬件驅(qū)動(dòng)程序的裝載以及一些windows應(yīng)用程序的運(yùn)行。
      注冊(cè)表中保存有應(yīng)用程序和資源管理器外殼的初始條件、首選項(xiàng)和卸載數(shù)據(jù)等,聯(lián)網(wǎng)計(jì)算機(jī)的整個(gè)系統(tǒng)的設(shè)置和各種許可,文件擴(kuò)展名與應(yīng)用程序的關(guān)聯(lián),硬件部件的描述、狀態(tài)和屬性,性能記錄和其他底層的系統(tǒng)狀態(tài)信息,以及其他數(shù)據(jù)等。

      1.1 打開(kāi)注冊(cè)表

      打開(kāi) "windows運(yùn)行",然后輸入regedit或regedt32即可打開(kāi)注冊(cè)表

       

      1.2 注冊(cè)表結(jié)構(gòu)

      注冊(cè)表由鍵、子鍵和值項(xiàng)構(gòu)成,一個(gè)鍵就是分支中的一個(gè)文件夾,而子鍵就是這個(gè)文件夾中的子文件夾,子鍵同樣是一個(gè)鍵。一個(gè)值項(xiàng)則是一個(gè)鍵的當(dāng)前定義,由名稱(chēng)、數(shù)據(jù)類(lèi)型以及分配的值組成。一個(gè)鍵可以有一個(gè)或多個(gè)值,每個(gè)值的名稱(chēng)各不相同,如果一個(gè)值的名稱(chēng)為空,則該值為該鍵的默認(rèn)值。

      HKEY_CLASSES_ROOT 用于控制所有文件的擴(kuò)展和所有可執(zhí)行文件相關(guān)的信息,本章提到的Windows自定義協(xié)議也是在此項(xiàng)中注冊(cè)產(chǎn)生的(在后面章節(jié)將詳細(xì)講述);

      HEKY_CURRENT_USER  用于管理系統(tǒng)當(dāng)前的用戶(hù)信息,及其應(yīng)用程序的相關(guān)資料,例如:當(dāng)前登錄的用戶(hù)信息,包括用戶(hù)登錄用戶(hù)名和暫存的密碼、當(dāng)前用戶(hù)使用的應(yīng)用軟件信息等。用戶(hù)登錄時(shí),其信息會(huì)在HEKY_USER表中拷貝到此表中,當(dāng)HEKY_USER表中信息發(fā)生改動(dòng)時(shí),HEKY_CURRENT_USER表中的信息也將隨之改動(dòng);

      HKEY_CURRENT_MACHINE  用于存儲(chǔ)控制系統(tǒng)和軟件的信息,當(dāng)中包括網(wǎng)絡(luò)和硬件上所有的軟件設(shè)備信息,比如文件的位置,注冊(cè)和未注冊(cè)的狀態(tài),版本號(hào)等等;比較常用的例如在HKEY_LOCAL_MACHINE\Microsoft\Windows\CurrentVersion\Run下注冊(cè)程序,程序就會(huì)在Windows啟動(dòng)時(shí)自動(dòng)運(yùn)行等等。其實(shí)在HKEY_LOCAL_MACHINE\SOFTWARE\Classes里面就包含了HKEY_CLASSES_ROOT信息,而HKEY_CLASSES_ROOT只是它的一個(gè)鍵值的映射,方便信息管理而已;

      HEKY_USER  作用是把缺省用戶(hù)和目前登陸用戶(hù)的信息輸入到注冊(cè)表編輯器,但它僅被那些配置文件激活的登陸用戶(hù)使用。當(dāng)任何在HKEY_CURRENT_USER里的信息發(fā)生改變,HKEY_USERS里面的信息也會(huì)相應(yīng)改動(dòng)。

      HKEY_CURRENT_CONFIG 用于存儲(chǔ)當(dāng)前系統(tǒng)的配置方式,例如當(dāng)Windows為同一個(gè)硬件安裝有多種驅(qū)動(dòng)程序時(shí),會(huì)在HEKY_CUREENT_MACHINE中記錄多個(gè)程序信息,而在HEKY_CURRENT_CONFIG中只是存儲(chǔ)默認(rèn)使用的驅(qū)動(dòng)信息,Windows 啟動(dòng)時(shí)會(huì)默認(rèn)按照HEKY_CURRENT_CONFIG中的配置調(diào)用相關(guān)的驅(qū)動(dòng)程序;

      回到目錄

       

      二、以C#程序修改注冊(cè)表

      微軟建立了Registry、RegistryKey 常用類(lèi)用于修改Windows 注冊(cè)表中的節(jié)點(diǎn)。

      2.1 Registry 類(lèi)

      Registry 主要用作獲取 Windows 注冊(cè)表中的根項(xiàng)的 RegistryKey 對(duì)象,并提供訪問(wèn)項(xiàng)/值對(duì)的 static 方法。
      它有以下幾個(gè)常用的屬性可直接用于獲取HEKY_CUREENT_MACHINE、HKEY_CLASSES_ROOT等幾個(gè)基礎(chǔ)項(xiàng)

      屬性說(shuō)明
      ClassesRoot 定義文檔的類(lèi)型(或類(lèi))以及與那些類(lèi)型關(guān)聯(lián)的屬性。 該字段讀取 Windows 注冊(cè)表基項(xiàng) HKEY_CLASSES_ROOT。
      CurrentConfig 包含有關(guān)非用戶(hù)特定的硬件的配置信息。 該字段讀取 Windows 注冊(cè)表基項(xiàng) HKEY_CURRENT_CONFIG。
      CurrentUser 包含有關(guān)當(dāng)前用戶(hù)首選項(xiàng)的信息。 該字段讀取 Windows 注冊(cè)表基項(xiàng) HKEY_CURRENT_USER
      DynData 已過(guò)時(shí)包含動(dòng)態(tài)注冊(cè)表數(shù)據(jù)。 該字段讀取 Windows 注冊(cè)表基項(xiàng) HKEY_DYN_DATA。
      LocalMachine 包含本地計(jì)算機(jī)的配置數(shù)據(jù)。 該字段讀取 Windows 注冊(cè)表基項(xiàng) HKEY_LOCAL_MACHINE。
      PerformanceData 包含軟件組件的性能信息。 該字段讀取 Windows 注冊(cè)表基項(xiàng) HKEY_PERFORMANCE_DATA。
      Users 包含有關(guān)默認(rèn)用戶(hù)配置的信息。 該字段讀取 Windows 注冊(cè)表基項(xiàng) HKEY_USERS。

      Registry屬性表2.1.1

       

      Registry 也提供幾個(gè)常用方法用于獲取或設(shè)置注冊(cè)表中指定名稱(chēng)的項(xiàng)值。

      方法說(shuō)明
      GetValue (String, String, Object) 檢索與指定的注冊(cè)表項(xiàng)中的指定名稱(chēng)關(guān)聯(lián)的值。  如果在指定的項(xiàng)中未找到該名稱(chēng),則返回您提供的默認(rèn)值;或者,如果指定的項(xiàng)不存在,則返回 null    
      SetValue(String, String, Object)   設(shè)置指定的注冊(cè)表項(xiàng)的指定名稱(chēng)/值對(duì)。  如果指定的項(xiàng)不存在,則創(chuàng)建該項(xiàng)。    
      SetValue(String, String, Object, RegistryValueKind)   通過(guò)使用指定的注冊(cè)表數(shù)據(jù)類(lèi)型,設(shè)置該指定的注冊(cè)表項(xiàng)的名稱(chēng)/值對(duì)。  如果指定的項(xiàng)不存在,則創(chuàng)建該項(xiàng)。    

      Registry方法表2.1.2

       

      2.2 RegistryKey 類(lèi)

      RegistryKey類(lèi)主要用于管理 Windows 注冊(cè)表中的項(xiàng)級(jí)節(jié)點(diǎn),通過(guò) Registry 類(lèi)的屬性就可以獲取注冊(cè)表中的根節(jié)點(diǎn)。它包含了以下幾個(gè)常用屬性   

      屬性說(shuō)明
      Handle 獲取一個(gè) SafeRegistryHandle 對(duì)象,該對(duì)象表示當(dāng)前 RegistryKey 對(duì)象封裝的注冊(cè)表項(xiàng)。
      Name 檢索項(xiàng)的名稱(chēng)。
      SubKeyCount 檢索當(dāng)前項(xiàng)的子項(xiàng)數(shù)目。
      ValueCount 檢索項(xiàng)中值的計(jì)數(shù)。
      View 獲取用于創(chuàng)建注冊(cè)表項(xiàng)的視圖。

      RegistryKey屬性表2.2.1

       

      RegistryKey類(lèi)的方法比較多,通過(guò)CreateSubKey(String)、GetValue(String)、SetValue(String, Object)、DeleteValue(String)等常用方法,就可以實(shí)現(xiàn)對(duì)注冊(cè)表的查詢(xún)修改。下面簡(jiǎn)單介紹一下RegistryKey的幾個(gè)常用方法   

      方法說(shuō)明
      Close() 關(guān)閉該項(xiàng),如果該項(xiàng)的內(nèi)容已修改,則將該項(xiàng)刷新到磁盤(pán)。
      CreateSubKey(String) 創(chuàng)建一個(gè)新子項(xiàng)或打開(kāi)一個(gè)現(xiàn)有子項(xiàng)以進(jìn)行寫(xiě)訪問(wèn)。
      CreateSubKey(String, RegistryKeyPermissionCheck) 使用指定的權(quán)限檢查選項(xiàng)創(chuàng)建一個(gè)新子項(xiàng)或打開(kāi)一個(gè)現(xiàn)有子項(xiàng)以進(jìn)行寫(xiě)訪問(wèn)。
      CreateSubKey(String, RegistryKeyPermissionCheck, RegistryOptions) 使用指定的權(quán)限檢查和注冊(cè)表選項(xiàng),創(chuàng)建或打開(kāi)一個(gè)用于寫(xiě)訪問(wèn)的子項(xiàng)。
      CreateSubKey(String, RegistryKeyPermissionCheck, RegistrySecurity) 使用指定的權(quán)限檢查選項(xiàng)和注冊(cè)表安全性創(chuàng)建一個(gè)新子項(xiàng)或打開(kāi)一個(gè)現(xiàn)有子項(xiàng)以進(jìn)行寫(xiě)訪問(wèn)。
      CreateSubKey(String, RegistryKeyPermissionCheck, RegistryOptions, RegistrySecurity) 使用指定的權(quán)限檢查選項(xiàng)、注冊(cè)表選項(xiàng)和注冊(cè)表安全性,創(chuàng)建或打開(kāi)一個(gè)用于寫(xiě)訪問(wèn)的子項(xiàng)。
      DeleteSubKey(String) 刪除指定的子項(xiàng)。
      DeleteSubKey(String, Boolean) 刪除指定的子項(xiàng),并指定在找不到該子項(xiàng)時(shí)是否引發(fā)異常。
      DeleteSubKeyTree(String) 遞歸刪除子項(xiàng)和任何子級(jí)子項(xiàng)。
      DeleteSubKeyTree(String, Boolean) 以遞歸方式刪除指定的子項(xiàng)和任何子級(jí)子項(xiàng),并指定在找不到子項(xiàng)時(shí)是否引發(fā)異常。
      DeleteValue(String) 從此項(xiàng)中刪除指定值。
      DeleteValue(String, Boolean) 從此項(xiàng)中刪除指定的值,并指定在找不到該值時(shí)是否引發(fā)異常。
      Flush() 將指定的打開(kāi)注冊(cè)表項(xiàng)的全部特性寫(xiě)到注冊(cè)表中。
      GetSubKeyNames() 檢索包含所有子項(xiàng)名稱(chēng)的字符串?dāng)?shù)組。
      GetValue(String) 檢索與指定名稱(chēng)關(guān)聯(lián)的值。  如果注冊(cè)表中不存在名稱(chēng)/值對(duì),則返回 null 
      GetValue(String, Object) 檢索與指定名稱(chēng)關(guān)聯(lián)的值。  如果未找到名稱(chēng),則返回您提供的默認(rèn)值。 
      GetValue(String, Object, RegistryValueOptions) 檢索與指定的名稱(chēng)和檢索選項(xiàng)關(guān)聯(lián)的值。  如果未找到名稱(chēng),則返回您提供的默認(rèn)值。 
      SetValue(String, Object) 設(shè)置指定的名稱(chēng)/值對(duì)。

      RegistryKey方法表2.2.2

       

      2.3 應(yīng)用實(shí)例

      下面先通過(guò)幾個(gè)例子,簡(jiǎn)單介紹一下如何通過(guò) Registry、RegistryKey 類(lèi)修改系統(tǒng)注冊(cè)表。

      2.3.1 新建自定義的項(xiàng)

      下面應(yīng)用程序?qū)?huì)在注冊(cè)表中新建 MyApplication項(xiàng),并在其子項(xiàng)Path的默認(rèn)值中保存應(yīng)用程序的StartupPath、在AppPath值中保存應(yīng)用程序的UserAppDataPath

              static void Main(string[] args)
              {
                  //獲取Machine根項(xiàng)
                  RegistryKey machine = Registry.LocalMachine;
                  //打開(kāi)SOFTWARE項(xiàng)
                  RegistryKey software = machine.OpenSubKey("SOFTWARE", true);
                  //新項(xiàng)MyApplication項(xiàng)
                  RegistryKey myApplication = software.CreateSubKey("MyApplication");
                  RegistryKey subkey = myApplication.CreateSubKey("Path");
                  //新建鍵值,當(dāng)鍵值名稱(chēng)為空時(shí),將被設(shè)置為默認(rèn)值
                  subkey.SetValue(null, Application.StartupPath);
                  subkey.SetValue("AppPath", Application.UserAppDataPath);
              }

      運(yùn)行應(yīng)用程序后,打開(kāi)"windows運(yùn)行",然后輸入regedit,在注冊(cè)表LocalMachine項(xiàng)中可以查找到新建的MyApplication項(xiàng)

       

      2.3.2 開(kāi)機(jī)啟動(dòng) “命令提示符”

      注冊(cè)表所包含的信息很多,其中在“HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run”處正是用于Windows開(kāi)機(jī)啟動(dòng)的程序信息。下面以Windows自帶的“命令提示符”工具為例子,通過(guò)修改注冊(cè)表實(shí)現(xiàn)開(kāi)機(jī)啟動(dòng)。(說(shuō)明:"命令提示符"的路徑是在“C:\Windows\System32\cmd.exe”)

            static void Main(string[] args)
              {
                  //打開(kāi)注冊(cè)表子項(xiàng)
                  RegistryKey key = Registry.LocalMachine
                      .OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
                  //增加開(kāi)機(jī)啟動(dòng)項(xiàng)
                  key.SetValue("Cmd", "C:\\Windows\\System32\\cmd.exe");
              }

      修改后可以看到注冊(cè)表中在“HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run”中會(huì)增加了一個(gè)名為Cmd的鍵

      當(dāng)重啟計(jì)算機(jī)時(shí)就會(huì)看到“命令提示符”將自動(dòng)啟動(dòng)

       

      回到目錄

       

      三、在 HKEY_CLASSES_ROOT 中添加自定義協(xié)議

      上面的章節(jié)已經(jīng)簡(jiǎn)單介紹如何通過(guò)程序操作注冊(cè)表,下面將介紹一下如果通過(guò)修改HKEY_CLASSES_ROOT中的項(xiàng),建立自定義協(xié)議。
      首先建立一個(gè)應(yīng)用程序MyApplication,寫(xiě)入簡(jiǎn)單的Hello World測(cè)試代碼

         static void Main(string[] args)
              {
                  Console.WriteLine("Hello World");
                  Console.ReadKey();
              }

      手動(dòng)在注冊(cè)表中建立下面的項(xiàng)和鍵:

      • 1、在HKEY_CLASSES_ROOT下添加項(xiàng)MyApplication.
      • 2、修改MyApplication項(xiàng)下的默認(rèn)值輸入"URL:(可為空)"。
      • 3、在MyApplication項(xiàng)下再添加一個(gè)鍵值"URL Protocol"。(必要健,否則在IE瀏覽器中可能無(wú)法運(yùn)行)
      • 4、在MyApplication項(xiàng)下新建項(xiàng)"shell"
      • 5、在shell項(xiàng)下新建項(xiàng)"open"
      • 6、在open項(xiàng)下新建項(xiàng)"command"
      • 7、修改command項(xiàng)的默認(rèn)鍵值為MyApplication應(yīng)用程序的路徑 "D:\C# Projects\MyApplication.exe" "%1"

      注意:把 command 鍵值設(shè)置為 "D:\C# Projects\MyApplication.exe" "%1",只要當(dāng)中包含標(biāo)示符“%1”,應(yīng)用程序可以根據(jù)自定義協(xié)議的路徑獲取對(duì)應(yīng)的參數(shù),其使用方式將在下面的章節(jié)再詳細(xì)說(shuō)明。

      簡(jiǎn)單測(cè)試:建立一個(gè)HTML頁(yè)面,如入以下代碼。
      注意:此連接路徑正是以注冊(cè)表產(chǎn)首項(xiàng)的MyApplication名稱(chēng)相同。

      <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
        ......
      </head>
       <body>
           <a href="MyApplication://command">Hello World</a>
         </body>
      </html>

      當(dāng)按下Hello World連接符時(shí),系統(tǒng)就會(huì)調(diào)用自定義協(xié)議MyApplication,啟動(dòng)“D:\C# Projects\MyApplication.exe”

       

      回到目錄

      四、通過(guò)“安裝項(xiàng)目”方式修改注冊(cè)表

      4.1 建立應(yīng)用程序

      上面章節(jié)所介紹的只是自定義協(xié)議的簡(jiǎn)單使用方式,然而在做軟件項(xiàng)目的時(shí)候,無(wú)論是使用C/S或者B/S方式,自定義協(xié)議都必須實(shí)現(xiàn)在客戶(hù)端的自動(dòng)安裝才能使用,因此客戶(hù)端的注冊(cè)表設(shè)置只能通過(guò)程序進(jìn)行修改。有見(jiàn)及此,微軟早在“安裝項(xiàng)目”中設(shè)置了注冊(cè)表修改功能。下面的章節(jié)將為大家介紹如何通過(guò) Visual Studio 2010 的“安裝項(xiàng)目”,實(shí)現(xiàn)注冊(cè)表的修改。
      建立一個(gè)新的MyApplication應(yīng)用程序,輸入以下代碼。

          [DataContract]
          public class Person
          {
              [DataMember]
              public int ID;
              [DataMember]
              public string Name;
              [DataMember]
              public int Age;
          }
      
          class Program
          {
              static void Main(string[] args)
              {
                  if (args != null)
                  {
                      //獲取輸入?yún)?shù)
                      string data = args[0].Split('&')[1];
                      //把JSON轉(zhuǎn)換成Person對(duì)象
                      Person person = GetPerson(data);
                      //數(shù)據(jù)顯示
                      Console.WriteLine(person.Name + "'s age is:" + person.Age);
                      Console.ReadKey();
                  }
              }
      
              //數(shù)據(jù)轉(zhuǎn)換
              static Person GetPerson(string data)
              {
                  DataContractJsonSerializer serializer = new 
                      DataContractJsonSerializer(typeof(Person));
                  MemoryStream stream = new MemoryStream(Encoding.Unicode.GetBytes(data));
                  Person person = (Person)serializer.ReadObject(stream);
                  stream.Close();
                  return person;
              }
          }

       

      4.2 添加安裝項(xiàng)目

      然后在解決方案里面添加一個(gè)“安裝項(xiàng)目”

      右鍵點(diǎn)擊"安裝項(xiàng)目",選擇“視圖-文件系統(tǒng)”后,在應(yīng)用程序文件夾中添加當(dāng)前的“MyApplication”項(xiàng)目。

       

      4.3 修改注冊(cè)表

      右鍵點(diǎn)擊"安裝項(xiàng)目",選擇“視圖-注冊(cè)表”后,按照第三節(jié)的例子在HKEY_CLASSES_ROOT上建立多個(gè)必要項(xiàng)。為方法獲取此應(yīng)用程序的安裝路徑,可以在MyApplication項(xiàng)中加入一個(gè)鍵值Path,綁定"[TARGETDIR]",便于系統(tǒng)隨時(shí)能通過(guò)此鍵值獲取應(yīng)用程序的安裝路徑。

      在“安裝項(xiàng)目”中有多個(gè)可用的綁定值,例如:“[TARGETDIR]”用于綁定應(yīng)用程序的安裝路徑,“[Manufacturer]”用于綁定應(yīng)用程序制造商名稱(chēng)等等。在command的值中輸入"[TARGETDIR]MyApplication.exe""%1",系統(tǒng)成功安裝后,此值就會(huì)轉(zhuǎn)換成應(yīng)用程序的安裝路徑。例如:MyApplication應(yīng)用程序安裝在"D:\C# Projects"安件夾中,那么注冊(cè)表的command默認(rèn)值就會(huì)變成“D:\C# Projects\MyApplication.exe” “%1”。

       

      4.4 添加安裝自定義操作

      在安裝應(yīng)用程序的前后,很多時(shí)候需要做一些必要的操作,例如存儲(chǔ)程序的Path值,為應(yīng)用程序生成一個(gè)sn文件作為標(biāo)識(shí)等等。這時(shí)候就可以通過(guò)建立Installer的子類(lèi),在安裝的前后的事件進(jìn)行操作。
      首先建立新項(xiàng)目InstallComponent,在項(xiàng)目中加入一個(gè)具備RunInstaller特性的類(lèi)繼承Installer類(lèi),RunInstaller特性是作用是用于指示在程序集安裝期間是否調(diào)用該安裝程序。而Installer類(lèi)是Framework 中所有自定義安裝程序的基類(lèi),它具備了以下多個(gè)方法。    

      方法說(shuō)明
      Commit 在派生類(lèi)中重寫(xiě)時(shí),完成安裝事務(wù)。
      Install 在派生類(lèi)中被重寫(xiě)時(shí),執(zhí)行安裝。
      OnAfterInstall 引發(fā) AfterInstall 事件。
      OnAfterRollback 引發(fā) AfterRollback 事件。
      OnAfterUninstall 引發(fā) AfterUninstall 事件。
      OnBeforeInstall 引發(fā) BeforeInstall 事件。
      OnBeforeRollback 引發(fā) BeforeRollback 事件。
      OnBeforeUninstall 引發(fā) BeforeUninstall 事件。
      OnCommitted 引發(fā) Committed 事件。
      OnCommitting 引發(fā) Committing 事件。
      Rollback 在派生類(lèi)中重寫(xiě)時(shí),還原計(jì)算機(jī)的安裝前狀態(tài)。
      Uninstall 在派生類(lèi)中重寫(xiě)時(shí),移除安裝。

      Installer方法表4.4.1

      只要自定義的類(lèi)型繼承了Installer類(lèi)并重寫(xiě) InstallCommitRollbackUninstall 等方法,系統(tǒng)就可以在應(yīng)用程序安裝的多個(gè)不同狀態(tài)下進(jìn)行操作。下面這個(gè)常用例子當(dāng)中,MyInstaller加入了AfterInstall事件的處理方法,在MyApplication應(yīng)用程序安裝完成后,會(huì)根據(jù)注冊(cè)表的Path鍵值獲取應(yīng)用程序的安裝路徑,并在該文件夾內(nèi)加入sn文件。sn文件內(nèi)存儲(chǔ)著一個(gè)GUID,作為該應(yīng)用程序的一個(gè)標(biāo)識(shí)。

         [RunInstaller(true)]
          public partial class MyInstaller : Installer
          {
              public MyInstaller()
                  : base()
              {
              //綁定完成安裝事件的處理方法
                  this.AfterInstall += new InstallEventHandler(OnAfterInstall);
              }
      
              /// 加入安裝完成后的處理方法
              protected override void OnAfterInstall(object sender, InstallEventArgs e)
              {
                  CreateSn();
              }
      
            //在完成安裝后建立一個(gè)sn文件,對(duì)該應(yīng)用程序進(jìn)行標(biāo)識(shí)
              private void CreateSn()
              {
                  var regKey = Registry.ClassesRoot.OpenSubKey("MyApplication", true);
                  if (regKey != null)
                  {
                      //根據(jù)注冊(cè)表中的Path鍵值,獲取系統(tǒng)在客戶(hù)端的安裝路徑
                      string path = regKey.GetValue("Path").ToString();
                  //建立sn文件
                      string snPath = path + "sn";
                      StreamWriter writer = new StreamWriter(snPath, true, Encoding.Unicode);
                      writer.Write(Guid.NewGuid().ToString());
                      writer.Close();
                  }
              }
      
              /// 重寫(xiě)安裝過(guò)程方法
              public override void Install(IDictionary stateSaver)
              {
                  base.Install(stateSaver);
              }
      
              /// 重寫(xiě)卸載方法
              public override void Uninstall(IDictionary savedState)
              {
                  base.Uninstall(savedState);
              }
      
              /// 重寫(xiě)回滾方法
              public override void Rollback(IDictionary savedState)
              {
                  base.Rollback(savedState);
              }
      
              //重寫(xiě)提交方法
              public override void Commit(IDictionary savedState)
              {
                  base.Commit(savedState);
              }
          }

       

      4.5 在安裝項(xiàng)目中綁定自定義操作

      當(dāng)完成自定義操作的設(shè)定后,回到安裝項(xiàng)目,右鍵點(diǎn)擊"安裝項(xiàng)目",選擇“視圖-文件系統(tǒng)”后,在應(yīng)用程序文件夾中添加自定義操作的“InstallComponent”項(xiàng)目。

      然后右鍵點(diǎn)擊"安裝項(xiàng)目",選擇“視圖-自定義操作-添加自定義操作-應(yīng)用程序文件夾”,選擇剛才導(dǎo)入的 “InstallComponent”項(xiàng)目。

      把安裝、提交、回滾、卸載等操作都與InstallComponent的MyInstaller類(lèi)進(jìn)行綁定。

       

      生成安裝項(xiàng)目后,點(diǎn)擊setup應(yīng)用程序進(jìn)行系統(tǒng)安裝,完成安裝后你就會(huì)發(fā)現(xiàn)在注冊(cè)表的HKEY_CLASSES_ROOT下將添加了MyApplication項(xiàng)。而且在該應(yīng)用程序文件夾中會(huì)自動(dòng)增加一個(gè)sn文件,里面將保存著一個(gè)CUID碼。

      回到目錄

       

      五、自定義協(xié)議的調(diào)用

      5.1 以連接方式調(diào)用

      調(diào)用自定義協(xié)議的方式很多,其中最簡(jiǎn)單的就是以連接方式來(lái)調(diào)用,好像下面的例子,當(dāng)頁(yè)面連接地址為MyApplication://自定義協(xié)議時(shí),系統(tǒng)就會(huì)自動(dòng)到注冊(cè)表查找該協(xié)議,根據(jù)command默認(rèn)項(xiàng)的綁定路徑對(duì)該程序進(jìn)行調(diào)用。并把“MyApplication://command&{'ID':'1','Name':'Rose','Age':'26'}" 路徑名作為static void main(string[] args) 方法中的其中一個(gè)參數(shù)輸入。

      <body>
         <script  type="text/javascript">
          window.onload = function () {
              var link = "MyApplication://command&{'ID':'1','Name':'Rose','Age':'26'}";
              location.href = link;
          }
         </script>
      </body>

      觀察第4節(jié)的內(nèi)容,自定義協(xié)議的main方法會(huì)把a(bǔ)rgs[0]參數(shù)按照字符'&'進(jìn)行分組,然后把后面的"{'ID':'1','Name':'Rose','Age':'26'}"JSON字符串轉(zhuǎn)換成Person對(duì)象進(jìn)行顯示。

       

      5.2 動(dòng)態(tài)調(diào)用

      回顧前面例子,一直都是運(yùn)用最簡(jiǎn)單的連接方式對(duì)自定義協(xié)議進(jìn)行調(diào)用。然而在現(xiàn)實(shí)的開(kāi)展過(guò)程中,這種方法并不可行,因?yàn)槊看握{(diào)用客戶(hù)端的自定義協(xié)議可能需要不同的參數(shù),把參數(shù)直接通過(guò)連接路徑來(lái)傳輸具有安全性問(wèn)題。
      最簡(jiǎn)單的解決方案是把自定義協(xié)議的路徑在IHttpHandler里面生成,再通過(guò)ajax來(lái)獲取,在回調(diào)函數(shù)中再調(diào)用此協(xié)議。通過(guò)此方法,協(xié)議的路徑不會(huì)以文本的方式存在于客戶(hù)端。除非是熟悉開(kāi)發(fā)人員通過(guò)測(cè)試工具進(jìn)行逐步檢索,否則一般人不能通過(guò)頁(yè)面找到自定義協(xié)議信息。
      下面就是一個(gè)以IHttpHandler生成自定義協(xié)議的一個(gè)例子,MyHandler會(huì)根據(jù)url路徑獲取請(qǐng)求對(duì)象的id值,然后進(jìn)行數(shù)據(jù)查詢(xún),并把查詢(xún)到的對(duì)象轉(zhuǎn)化為JSON格式。最后把自定義協(xié)議的路徑返回到客戶(hù)端。

          [DataContract]
          public class Person
          {
              public Person(int id, string name, int age)
              {
                  ID = id;
                  Name = name;
                  Age = age;
              }
      
              [DataMember]
              public int ID;
              [DataMember]
              public string Name;
              [DataMember]
              public int Age;
          }
      
         public class MyHandler : IHttpHandler
          {
              public bool IsReusable
              {
                  get { return true; }
              }
      
              public void ProcessRequest(HttpContext context)
              {
                  //通過(guò)QueryString獲取id
                  string data = context.Request.QueryString["id"];
                  if (data != null)
                  {
                      int id = int.Parse(data);
                      //根據(jù)id進(jìn)行數(shù)據(jù)查找
                      foreach (var person in DataSource())
                      {
                          if (person.ID == id)
                          {
                              //把Person對(duì)象轉(zhuǎn)化為JSON數(shù)據(jù)
                              string json = ConvertToJson(person);
                              //輸出自定義協(xié)議路徑
                              context.Response.Write(GetUrl(json));
                          }
                      }
                  }
              }
      
              //獲取自定義協(xié)議路徑
              private string GetUrl(string json)
              {
                  return "MyApplication://command&" + json;
              }
      
              //把Person對(duì)象轉(zhuǎn)化為JSON
              private string ConvertToJson(Person person)
              {
                  DataContractJsonSerializer serializer = new
                      DataContractJsonSerializer(typeof(Person));
                  MemoryStream stream = new MemoryStream();
                  serializer.WriteObject(stream, person);
                  byte[] bytes = stream.ToArray();
                  stream.Close();
                  return Encoding.ASCII.GetString(bytes);
              }
      
              //模擬數(shù)據(jù)源
              private IList<Person> DataSource()
              {
                  IList<Person> list = new List<Person>();
                  Person person1 = new Person(1, "Rose", 34);
                  list.Add(person1);
                  ......
                  return list;
              }
          }

      客戶(hù)端通過(guò)ajax把id發(fā)送到MyHandler.ashx進(jìn)行查詢(xún),在回調(diào)函數(shù)中調(diào)用所獲取到的自定義協(xié)議。
      如果自定義協(xié)議參數(shù)中具有保密資料的信息還可以通過(guò)加密方式進(jìn)行傳遞,好像上面的一個(gè)例子,客戶(hù)端可以先把自動(dòng)生成的sn發(fā)送到服務(wù)器進(jìn)行記錄,并與客戶(hù)ID進(jìn)行綁定。在請(qǐng)求自定義協(xié)議的路徑時(shí)通過(guò)IHttpHandler把相關(guān)的信息通過(guò)sn進(jìn)行加密,等到數(shù)據(jù)發(fā)送到客戶(hù)端后再進(jìn)行解密。

      <head>
          <title></title>
          <script src="Scripts/jquery-1.8.2.min.js" type="text/javascript"></script>
      </head>
      <body>
         <a name="send" id="send" href="#">GetPerson</a>
         <script type="text/javascript">
             $(function () {
                 $('#send').click(function () {
                     $.ajax({
                         type: "GET",
                         url: "MyHandler.ashx?id=1",
                         data: null,
                         dataType: null,
                         success: function (data) {
                             location.href = data;
                         }
                     });
                 });
             });
         </script>
      </body>
      </html>

      回到目錄 

       

      本章小結(jié)

      自定義協(xié)議有著廣泛的應(yīng)用,像QQ、迅雷、淘寶等等這些的常見(jiàn)的應(yīng)用程序都會(huì)使用自定義協(xié)議。特別在大型的企業(yè)系統(tǒng)開(kāi)發(fā)過(guò)程中,C/S、B/S融合開(kāi)發(fā)的情況很常見(jiàn),這時(shí)候自定義協(xié)議更發(fā)揮其獨(dú)特的作用。一般在系統(tǒng)自動(dòng)更新,客戶(hù)端信息獲取等這些功能上都會(huì)使用自定義協(xié)議進(jìn)行開(kāi)發(fā)。相對(duì)于ActiveX控件,自定義協(xié)議不會(huì)受到瀏覽器的約束,更能簡(jiǎn)化客戶(hù)端與瀏覽器之間的信息傳信。

      對(duì) .NET 開(kāi)發(fā)有興趣的朋友歡迎加入QQ群:162338858 同探討 !

       

      C#綜合揭秘

      通過(guò)修改注冊(cè)表建立Windows自定義協(xié)議
      Entity Framework 并發(fā)處理詳解
      細(xì)說(shuō)進(jìn)程、應(yīng)用程序域與上下文
      細(xì)說(shuō)多線程(上)
      細(xì)說(shuō)多線程(下)
      細(xì)說(shuō)事務(wù)

      深入分析委托與事件

       

      作者:風(fēng)塵浪子

      http://www.rzrgm.cn/leslies2/p/3727762.html

      原創(chuàng)作品,轉(zhuǎn)載時(shí)請(qǐng)注明作者及出處

       

      posted on 2014-05-16 15:46  風(fēng)塵浪子  閱讀(19185)  評(píng)論(15)    收藏  舉報(bào)

      導(dǎo)航

      主站蜘蛛池模板: 18禁成人免费无码网站| 精品在免费线中文字幕久久| 亚洲熟妇一区二区三个区| 国产精品久久久久久无毒不卡| 免费观看国产女人高潮视频| 性欧美vr高清极品| 北岛玲中文字幕人妻系列| 精品欧洲av无码一区二区| 国产无遮挡免费视频免费| 富阳市| 男人扒女人添高潮视频| 国产一区二区四区不卡| 日本熟妇XXXX潮喷视频| 亚洲精品国偷自产在线| 免费av网站| 亚洲午夜伦费影视在线观看| 午夜福利国产精品小视频| 免费的很黄很污的视频| 久久精品视频一二三四区| 中文字幕日韩精品有码| 国产亚洲AV电影院之毛片| 少妇被粗大的猛烈进出动视频| 亚洲中文字幕无码中字| 久久久久久久久18禁秘| 国产av午夜精品福利| 国产一区二区视频在线看| 国产三级精品三级在线专区1| 在线天堂中文新版www| 蜜桃视频网站| 自拍偷拍第一区二区三区| 国产一区二区午夜福利久久| 成人看的污污超级黄网站免费| 资源县| 亚洲综合伊人久久大杳蕉| AV喷水高潮喷水在线观看COM| 黄色网站免费在线观看| 国产成人高清精品免费软件| 久久精品国产亚洲av成人| 亚洲国产成人久久一区久久| 一区二区三区精品视频免费播放 | 人妻少妇88久久中文字幕|