如何用代碼開啟系統的“運行”對話方塊
這個問題我很早之前就知道了,但今天要用的時候,居然給忘了,查了好半天才搞出來,所以這裡有必要記錄一下,另外也可以瞭解一下COM的調用及C#4.0中的Dynamic Lookup。
所謂“運行”對話方塊,就是開始菜單裡的那個運行,其快速鍵為Windows+R,相信很多人都用過,我這裡介紹三種方法來開啟“運行”對話方塊:
一、類比按鍵
由於.NET類庫裡的SendKeys類貌似不能發送Windows鍵,所以這裡我使用Win32 API:keybd_event:
[DllImport("user32")]
public static extern void keybd_event(
byte bVk,//按鍵的虛擬鍵碼
byte bScan,
int dwFlags,//0表示按下,2表示抬起
int dwExtraInfo
);
//類比Windows+R
keybd_event(0x5B, 0, 0, 0);
keybd_event((byte)'R', 0, 0, 0);
keybd_event((byte)'R', 0, 2, 0);
keybd_event(0x5B, 0, 2, 0);
二、Shell32.dll裡有一個未公開的API,無函數名,序號為61,其形式如下
[DllImport("shell32",EntryPoint="#61",CharSet=CharSet.Unicode)]//#61代表序號為61的函數;字元集要設成Unicode,否則可能會是亂碼
public static extern void RunDialog( //設定了EntryPoint之後,函數名可任取
IntPtr hwndOwner, //所有者視窗控制代碼
IntPtr hIcon, //要顯示的表徵圖控制代碼
string lpstrDirectory, //“瀏覽”按鈕的目錄,該目錄下的檔案可省略路徑
string lpstrTitle, //視窗標題的文字
string lpstrDescription, //視窗上的文本描述
uint uFlags //樣式
);
另外,如果要在C++裡用序號調用函數,請將MAKEINTRESOURCE( num )作為函數名傳遞給GetProcAddress函數。
三、Shell32.dll裡有一個COM函數(這個dll裡既有Win32 API,又有COM)FileRun,調用COM中的函數有兩種方式,我分別給予介紹:
1.引用
該方式很簡單,跟調用.NET函數差不多:
添加對shell32.dll的引用。
代碼如下:
Shell32.Shell s = new Shell32.Shell();
s.FileRun();
實際上Shell32.Shell是個介面,之所以能夠執行個體化,是因為它有一個Attribute:
CoClass(typeof(ShellClass))
所以也可以這樣:
Shell32.ShellClass sc=new Shell32.ShellClass();
sc.FileRun();
不過這段代碼在VS2010裡編不過,估計是因為C#4.0裡有個“內嵌類型”的概念。
2.反射
COM也可以反射,但是只限於調用,不能查詢成員:
Type t = Type.GetTypeFromProgID("Shell.Application");
object obj = Activator.CreateInstance(t);
t.InvokeMember("FileRun", BindingFlags.InvokeMethod, null, obj, null);
而如果在C#4.0裡,由於有Dynamic Lookup的存在,可以這樣:
Type t = Type.GetTypeFromProgID("Shell.Application");
dynamic obj = Activator.CreateInstance(t);
obj.FileRun();