亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

在服務程序中彈出對話框

2019-11-11 04:09:35
字體:
來源:轉載
供稿:網友
http://blog.csdn.net/linux7985/article/details/5694613

先說說在WinXP和Windows2003下用的方法。 第一種方法是在服務進程中啟動一個子進程。用該子進程彈出對話框。.NET的C#代碼大致如下: 

[c-sharp] view plain copypublic static void Show( string msg, string cap, MessageBoxButtons buttons, MessageBoxIcon icon )  {      try      {            PRocess proc = new Process();          proc.StartInfo.FileName = EXE_NAME;          proc.StartInfo.Arguments = string.Format( ARG_FMT, msg, cap, buttons, icon );          proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;            proc.Start();      }      catch { }  }  

這段代碼是啟動一個進程。該進程唯一的目的是顯示一個對話框,大致的代碼如下:

 

[c-sharp] view plain copystatic class Program  {        /// <summary>       /// The main entry point for the application.       /// </summary>       [STAThread]      static void Main( string[] args )      {          try          {              string strMsg = args[0];              string strCap = args[1];              MessageBoxButtons btn = ( MessageBoxButtons )Enum.Parse( typeof( MessageBoxButtons ), args[2] );              MessageBoxIcon icon = ( MessageBoxIcon )Enum.Parse( typeof( MessageBoxIcon ), args[3] );                MessageBox.Show( strMsg, strCap, btn, icon, MessageBoxDefaultButton.Button1, MessageBoxOptions.ServiceNotification );          }          catch { }      }  }  

 

這里的做法是指定子進程的線程模型為STAThread。這就意味著線程的消息是靠一個隱含的窗口來分發。也正因為有這個隱含的窗口,該子進程獲得了交互能力,可以彈出對話框。 不幸的是,在Vista和Windows2008下,用這種方法時,子進程無法成功創建。

 

還有另一種方法,可以不創建子進程,直接在服務進程中顯示對話框。代碼大致如下,由于主要是調用API,這里直接展示C++形式的代碼: 

[cpp] view plain copyHDESK hdeskCurrent;  HDESK hdesk;  HWINSTA hwinstaCurrent;  HWINSTA hwinsta;  hwinstaCurrent = GetProcessWindowStation();  hdeskCurrent = GetThreadDesktop(GetCurrentThreadId());  //Open winsta0  hwinsta = OpenWindowStation("winsta0", FALSE, WINSTA_accessCLipBOARD | WINSTA_ACCESSGLOBALATOMS | WINSTA_CREATEDESKTOP | WINSTA_ENUMDESKTOPS | WINSTA_ENUMERATE | WINSTA_EXITWINDOWS | WINSTA_READATTRIBUTES | WINSTA_READSCREEN | WINSTA_WRITEATTRIBUTES);    SetProcessWindowStation(hwinsta);    //Open default desktop  hdesk = OpenDesktop("default", 0, FALSE, DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS);    SetThreadDesktop(hdesk);    // Show the dialog CMsgDlg dlgMsg;  dlgMsg.DoModal();  

可以看到,這種方法的關鍵是OpenWindowStation、SetProcessWindowStation、OpenDesktop和SetThreadDesktop這四個函數。這種方法的思路是:當前進程所處于的session必須有界面交互能力,這樣才能顯示出對話框。由于第一個交互式用戶會登錄到擁有WinSta0的Session 0,所以,強制性地把服務所在的進程與WinSta0關聯起來,并且打開當前的桌面,把工作線程掛到該桌面上,就可以顯示出對話框。

這種方法在WinXP和Windows2003下工作得不錯,很遺憾,在Vista和Windows2008下,一旦執行到OpenWindowStation,試圖代開WinSta0工作站時,程序就會出異常。

 

為什么會這樣?看來還有一些深層的東西在制約著Vista和Windows2008,使得服務程序無法顯示對話框。

 

首先了解一下程序要具備怎樣的條件才能與界面交互。Windows提供了三類對象:用戶界面對象(User Interface)、GDI對象和內核對象。內核對象有安全性,而前兩者沒有。為了對前兩者提供安全性,通過工作站對象(Window station)和桌面對象(Desktop)來管理用戶界面對象,因為工作站對象和桌面對象有安全特性。簡單說來,工作站是一個帶有安全特性的對象,它與進程相關聯,包含了一個或多個桌面對象。當工作站對象被創建時,它被關聯到調用進程上,并且被賦給當前Session。交互式工作站WinSta0,是唯一一個可以顯示用戶界面,接受用戶輸入的工作站。它被賦給交互式用戶的登錄Session,包含了鍵盤、鼠標和顯示設備。所有其他工作站都是非交互式的,這就意味著它們不能顯示用戶界面,不能接受用戶的輸入。當用戶登錄到一臺啟用了終端服務的計算機上時,每個用戶都會啟動一個Session。每個Session都會與自己的交互式工作站相聯系。桌面是一個帶有安全特性的對象,被包含在一個窗口工作站對象中。一個桌面對象有一個邏輯的顯示區域,包含了諸如窗口、菜單、鉤子等等這樣的用戶界面對象。

 

在Vista之前,之所以可以通過打開Winsta0和缺省桌面顯示對話框,是因為不管是服務還是第一個登錄的交互式用戶,都是登錄到Session 0中。因此,服務程序可以通過強制打開WinSta0和桌面來獲得交互能力。 然而,在Vista和Windows2008中,Session 0專用于服務和其他不與用戶交互的應用程序。第一個登錄進來,可以進行交互式操作的用戶被連到Session 1上。第二個登錄進行的用戶被分配給Session 2,以此類推。Session 0完全不支持要與用戶交互的進程。如果采取在服務進程中啟動子進程來顯示對話框,子對話框將無法顯示;如果采取用OpenWindowStation系統API打開WinSta0的方法,函數調用會失敗??傊琕ista和Windows2008已經堵上了在Session 0中產生界面交互的路。這就是原因所在

 

  那么,是否真的沒法在服務中彈出對話框了呢?對于服務進程自身來說,確實如此,操作系統已經把這條路堵上了。但是,我們想要的并不是“在服務進程中彈出對話框”,我們想要的不過是“當服務出現某些狀況的時候,在桌面上彈出對話框”。既然在   Session 0   中無法彈出對話框,而我們看到的桌面是   Session X   ,并非   Session 0   ,很自然的一個想法是:能不能讓   Session 0   通知其他的   Session   ,讓當前桌面正顯示著的   Session   彈一個對話框呢?    幸運的是,還真可以這樣做。一個   Session   中的進程可以用   WTSSendMessage   ,讓另一個   Session   彈出對話框。   WTSSendMessage   的一個參數是   SessionID   ,目的是指定要彈出對話框的   Session   。為了獲得當前顯示的桌面所在的   SessionID   ,可以用   WTSGetActiveConsoleSessionId   得到這個   SessionID   。代碼大致類似于: 

 

[c-sharp] view plain copypublic static bool Show( string msg, string cap, MessageBoxButtons buttons, MessageBoxIcon icon )  {      try      {          Int32 sessionId = WTSGetActiveConsoleSessionId();          Int32 result = 0;          bool bSuccess = WTSSendMessage( ( IntPtr )0, sessionId, cap, cap.Length, msg, msg.Length, Convert.ToInt32( buttons ) + Convert.ToInt32( icon ), 0, ref result, true );          return bSuccess;      }      catch { return false; }  }   


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲成人黄色在线观看| 在线播放日韩精品| 中文日韩在线视频| 欧美精品九九久久| 欧美日韩精品在线| 国产精品久久电影观看| 欧美大片va欧美在线播放| 欧美高跟鞋交xxxxxhd| 欧美精品久久久久久久免费观看| 国产精品视频在线观看| 精品成人国产在线观看男人呻吟| 激情成人中文字幕| 久久精品国产v日韩v亚洲| 91久久精品国产91久久性色| 国产网站欧美日韩免费精品在线观看| 久久男人资源视频| 日韩av电影在线播放| 成人激情免费在线| 久久久久久香蕉网| 精品无码久久久久久国产| 欧美成年人在线观看| 久久久精品在线| 中文字幕9999| 亚洲日韩中文字幕| 亚洲欧美日韩中文在线| 国产精品免费观看在线| 亚洲娇小xxxx欧美娇小| 久久精视频免费在线久久完整在线看| 欧美日韩中国免费专区在线看| 欧美亚洲激情在线| 日韩精品在线观| 国产一区二区三区在线观看网站| 成人激情电影一区二区| 欧美刺激性大交免费视频| 有码中文亚洲精品| 国产精品自拍视频| 国产欧美一区二区三区在线看| 2023亚洲男人天堂| 国产精品久久网| 国产精品免费久久久久久| 亚洲国内精品视频| 欧美在线不卡区| 欧美黑人视频一区| 国产精品91免费在线| 亚洲综合av影视| 久久免费视频在线| 欧美性精品220| 亚洲男人av电影| 欧美亚洲国产日本| 色噜噜亚洲精品中文字幕| 国内揄拍国内精品少妇国语| 国产精品入口夜色视频大尺度| 一本一本久久a久久精品牛牛影视| 亚洲欧美日韩天堂一区二区| 夜夜躁日日躁狠狠久久88av| 日韩女优人人人人射在线视频| 国产成人精品综合| 中文字幕av一区| 欧美日韩国产成人在线观看| 国产精品视频yy9099| 国产成人av在线| 精品自拍视频在线观看| 成人免费高清完整版在线观看| 欧美激情视频在线免费观看 欧美视频免费一| 亚洲乱码国产乱码精品精天堂| 国产亚洲成av人片在线观看桃| 福利视频一区二区| 欧美成年人在线观看| 爽爽爽爽爽爽爽成人免费观看| 4438全国亚洲精品在线观看视频| 欧美性色xo影院| 日本免费在线精品| 国产日产欧美a一级在线| 欧美一级片久久久久久久| 亚洲人av在线影院| 91精品综合久久久久久五月天| 欧美国产日韩一区| 韩国精品美女www爽爽爽视频| 欧美疯狂xxxx大交乱88av| 国产网站欧美日韩免费精品在线观看| 欧美福利视频在线观看| 欧美精品videosex极品1| 欧美日韩中文字幕日韩欧美| 中文字幕成人精品久久不卡| 国产精品久久久久不卡| 日韩成人中文电影| 久久久久久高潮国产精品视| 97avcom| 亚洲国产又黄又爽女人高潮的| 精品亚洲一区二区三区在线观看| 久久精品青青大伊人av| 欧美在线免费看| 精品国偷自产在线视频| 国产一区二区三区精品久久久| 国产精品美女主播| 在线播放亚洲激情| 国产这里只有精品| 国产suv精品一区二区| 国产美女精品视频免费观看| 国产亚洲精品一区二555| 97精品欧美一区二区三区| 91久久精品久久国产性色也91| 久久中国妇女中文字幕| 久久99久久亚洲国产| 国产精品久久久久免费a∨| 久久露脸国产精品| 国产精品亚洲片夜色在线| 亚洲国产私拍精品国模在线观看| 亚洲激情自拍图| 亚洲摸下面视频| 亚洲电影成人av99爱色| 国产精品天天狠天天看| 91丝袜美腿美女视频网站| 色小说视频一区| 精品无人国产偷自产在线| 一本一本久久a久久精品综合小说| 亚洲成人免费网站| 国产精品视频白浆免费视频| 亚洲国产小视频在线观看| 国产精品一二三在线| 亚洲女人天堂成人av在线| 亚洲第一精品电影| 日韩在线视频观看| 精品久久国产精品| 亚洲毛片一区二区| 亚洲人成在线观看| 日韩电影中文字幕av| 午夜精品一区二区三区视频免费看| 国产精品免费看久久久香蕉| 亚洲天堂男人的天堂| 5566成人精品视频免费| 中文字幕少妇一区二区三区| 激情成人中文字幕| 中文字幕久精品免费视频| 欧美成年人视频网站欧美| 热99久久精品| 精品国偷自产在线| 欧美日韩国产二区| 色樱桃影院亚洲精品影院| 亚洲天堂网站在线观看视频| 黑丝美女久久久| 欧美激情影音先锋| 国产婷婷色综合av蜜臀av| 久久免费视频在线观看| 欧美美最猛性xxxxxx| 国产精品91在线| 亚洲欧美国产精品久久久久久久| 亚洲国产第一页| 欧美激情小视频| 日韩黄色av网站| 久久6精品影院| 欧美孕妇毛茸茸xxxx| 精品国产精品自拍| 狠狠躁天天躁日日躁欧美| 国内伊人久久久久久网站视频| 亚洲tv在线观看| 国产美女主播一区| 久久久久久久久久久免费| 91av在线国产| 久久久亚洲网站| 97视频在线观看免费高清完整版在线观看| 亚洲欧美一区二区三区四区| 成人午夜在线观看| 精品伊人久久97|