NET Framework 用C#建立SHELL擴充

來源:互聯網
上載者:User
建立

一、前言

.NET平台是微軟公司推出的作為未來軟體運行和開發的環境,C#是微軟力薦的在.NET平台下開發應用軟體的慣用語言。本文將討論在.NET環境下如何使用C#語言開發Windows Shell擴充問題。如今Windows家族已發展到XP世代了,想必每個程式員都對Shell Extension不會感到陌生吧,在這裡我不想花太多的時間介紹Shell Extension的原理知識,本文中將通過一個執行個體介紹用C#建立一個Shell Extension,在此過程中也會簡單介紹一些Shell Extension的原理知識(如果想詳細瞭解Shell擴充原理知識,請參閱MSDN)。

二、開發環境

(1)、Windows2000 專業版。
(2)、Visual Studio.NET Beta 2.0或正式版1.0。

三、原理介紹

本執行個體實現一個ShellExecuteEx Win32調用的鉤子操作,Windows Explorer常常會用到這個調用,如開啟、編輯、列印等等Shell操作都要用到這個調用。在Windows註冊表HKLM\Software\Microsoft\Windows\CurrentVersion\Explorer\ShellExecuteHooks項下安裝了所有實現Shell擴充的組件資訊。當Windows Explorer執行Shell操作前,先在註冊中尋找到登入的Shell向外延展群組件,並將其執行個體化,每個Shell向外延展群組件必須至少實現了IShellExecuteHook介面,此介面提供了一個Execute()函數,Explorer將通過組件執行個體對象調用Execute()函數,如此函數返回為S_FALSE繼續後面的操作,如返回S_OK則停止後面的所有操作。根據以上原理,本執行個體要實現Shell擴充就必須要實現一個支援IShellExecuteHook介面的COM組件。

介面聲明

因C#不能像C++那樣用一句#include "shlguid.h"語句就可以完成IShellExecuteHook介面聲明,它必須要求在程式中聲明介面的具體資訊,聲明如下:

[ComImpor,InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("000214FB-0000-0000-C000-000000000046")]
/* Guid("000214FB-0000-0000-C000-000000000046") 相當於shlguid.h中的DEFINE_SHLGUID(IID_IShellExecuteHookW, 0x000214FBL, 0, 0); */
public interface IShellExecuteHook{
[PreserveSig()] /* 允許傳回值為COM HRESULT */
int Execute(SHELLEXECUTEINFO sei);
}

結構聲明

在Execute()方法中有一個SHELLEXECUTEINFO結構體參數sei,接下來要聲明結構體:
[StructLayout(LayoutKind.Sequential)]
public class SHELLEXECUTEINFO {
public int cbSize;
public int fMask;
public int hwnd;
[MarshalAs(UnmanagedType.LPWStr)]
public string lpVerb; /* 動作,如edit,open,print... */
[MarshalAs(UnmanagedType.LPWStr)]
public string lpFile; /* 根據lpVerb的值而定,常為檔案名稱 */
[MarshalAs(UnmanagedType.LPWStr)]
public string lpParameters; /* 參數字串 */
[MarshalAs(UnmanagedType.LPWStr)]
public string lpDirectory; /* 路徑名 */
public int nShow;
public int hInstApp;
public int lpIDList;
public string lpClass;
public int hkeyClass;
public int dwHotKey;
public int hIcon;
public int hProcess;
}

SHELLEXECUTEINFO結構體的元素是不是夠多的,它們的具體說明就不一一介紹了,如果你有空的話可以看看MSDN。

四、實現步驟

介紹了ISellExecuteHook介面的聲明以及SHELLEXECUTEINFO結構體的聲明後,我們就著手實現這個應用執行個體,這個執行個體很簡單,每當Explorer對一個Shell對象執行某動作前將會彈出一個對話方塊,在其上顯示執行的動作內容、對象名以及參數內容。

開啟VS.NET,按下面步驟工作:

1.建立一個空項目(項目名:ExtenShell)。

2.添加一個新類(類名:ExtenShell.cs)。
  
3.將下面代碼作為ExtenShell.cs的內容。

   /* ExtenShell.cs */
   using System;
   using System.Reflection;
   using System.Runtime.InteropServices;
   using System.Windows.Forms;

   [assembly: AssemblyKeyFile(@"..\..\ESKey.snk")] /*密鑰檔案*/
   namespace ShellExtension
   {
     //介面聲明。
     [ComImport,InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("000214FB-0000-0000-C000-000000000046")]
        /* Guid("000214FB-0000-0000-C000-000000000046") 相當於shlguid.h中的DEFINE_SHLGUID(IID_IShellExecuteHookW, 0x000214FBL, 0, 0); */
     public interface IShellExecuteHook
     {
         [PreserveSig()] /* 允許傳回值為COM HRESULT */
         int Execute(SHELLEXECUTEINFO sei);
     }

     //結構聲明。
     [StructLayout(LayoutKind.Sequential)]
     public class SHELLEXECUTEINFO
     {
         public int cbSize;
         public int fMask;
         public int hwnd;
         [MarshalAs(UnmanagedType.LPWStr)]
         public string lpVerb;
         [MarshalAs(UnmanagedType.LPWStr)]
         public string lpFile;
         [MarshalAs(UnmanagedType.LPWStr)]
         public string lpParameters;
         [MarshalAs(UnmanagedType.LPWStr)]
         public string lpDirectory;
         public int nShow;
         public int hInstApp;
         public int lpIDList;
         public string lpClass;
         public int hkeyClass;
         public int dwHotKey;
         public int hIcon;
         public int hProcess;
      }

      [Guid("027F9368-A83E-42cc-85B2-1DC5E23C4608"), ComVisible(true)]
         /* 用Guid產生工具建立一個新的GUID作為類對象的GUID標識。 */
      public class ExtenShell : IShellExecuteHook
      {
           private int S_OK=0;
           private int S_FALSE=1;
           public int Execute(SHELLEXECUTEINFO sei)
           {
               try
               {
                   MessageBox.Show(null, "[ Verb ]: " + sei.lpVerb + "\n[ File ]: " + sei.lpFile + "\n[ Parameters ]:" + sei.lpParameters + "\n[ Directory ]:" + sei.lpDirectory , "ShellExtensionHook",MessageBoxButtons.OK, MessageBoxIcon.Information);

               }
               catch(Exception e)
               {
                   Console.Error.WriteLine("Unknown exception : " + e.ToString());
               }

               return S_FALSE;
               //如果傳回值為S_OK則SHELL將停止對Shell對象的以後的所有動作。
            }
       }
  }

4. 在命令列上運行:sn -k ESKey.snk ( sn.exe在 C:\Programe Files\Microsoft.NET\FrameworkSDK\Bin下可以找到 ),將ESKey.snk添加到項目中。
 
    5. 開啟<項目> --> <屬性>,將輸出類型改成類庫。
  
    6. 編譯完成。
 
    7. 因.NET可控代碼產生的COM組件註冊後要到assembly目錄中尋找實體執行,故應將編譯好的ExtenShell.dll檔案拷貝到c:\Winnt\assembly目錄中。 

8. 註冊組件。在命令列上運行:regasm {項目路徑}\Bin\Debug\ExtenShell.dll。( regasm.exe在c:\Winnt\Microsoft.NET\Framework\v1.0.2914下可以找到)
 
    9.最後,在HKLM\Software\Microsoft\Windows\CurrentVersion\Explorer\ShellExecuteHooks項下建立一個字串值,其名為{027F9368-A83E-42cc-85B2-1DC5E23C4608},值可以為空白也可以加入一串描述性文字。

五、結 束

    這是一個簡單的Shell擴充的例子,雖然不是一個完整的應用,但是作者想通過此執行個體向讀者介紹Shell擴充和.NET平台下的COM組件開發技術,希望它能起拋磚引玉的作用。



相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.