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

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

在服務程序中彈出對話框

2019-11-11 05:15:26
字體:
來源:轉載
供稿:網友
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的方法,函數調用會失敗??傊?,Vista和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
欧美日韩一区二区免费视频| 亚洲天堂第一页| 国产精品视频一| 91探花福利精品国产自产在线| 成人深夜直播免费观看| 91精品国产九九九久久久亚洲| 日韩av在线免费观看| 精品国产91久久久久久| 亚洲人成网站免费播放| 国产精品亚洲片夜色在线| 亚洲国产精品久久久| 性欧美办公室18xxxxhd| 尤物精品国产第一福利三区| 国产亚洲精品日韩| 夜夜躁日日躁狠狠久久88av| 国产69精品久久久久9999| 亚洲精品视频免费| 精品中文视频在线| 国产日韩换脸av一区在线观看| 色综合91久久精品中文字幕| 欧美一区二粉嫩精品国产一线天| 亚洲成人激情图| 日韩国产欧美区| 亚洲在线一区二区| 亚洲在线一区二区| 精品国产乱码久久久久久天美| 欧美日本在线视频中文字字幕| 亚洲性无码av在线| 国产精品久久久久久久美男| 91视频九色网站| 欧美日韩国产中文字幕| 亚洲综合一区二区不卡| 国产深夜精品福利| 欧美日韩亚洲激情| 久久精品亚洲热| 91精品国产99久久久久久| 欧美另类极品videosbest最新版本| 亚洲欧洲国产伦综合| 亚洲自拍av在线| 日产精品久久久一区二区福利| 久久久久久久网站| 91夜夜未满十八勿入爽爽影院| 午夜精品久久久久久久男人的天堂| 欧美老妇交乱视频| 国产成人精品久久二区二区| 久久综合亚洲社区| 亚洲第一二三四五区| 国产精品第10页| 国产精品日日做人人爱| 97精品国产91久久久久久| 国产精品久久中文| 91香蕉嫩草影院入口| 91九色国产视频| 欧美综合在线观看| 97精品国产97久久久久久春色| 久久精品国产69国产精品亚洲| 亚洲精品资源美女情侣酒店| 91高潮在线观看| 欧美中文字幕第一页| 国模精品系列视频| 国产福利精品在线| 国产精选久久久久久| 这里只有视频精品| 欧美性videos高清精品| 国产日韩欧美电影在线观看| 国产精品成人av性教育| 国产精品69久久久久| 日韩av网站在线| 亚洲少妇中文在线| 日韩精品有码在线观看| 日韩中文字幕在线播放| 亚洲福利视频网| 成人福利免费观看| 孩xxxx性bbbb欧美| 国产成人精品日本亚洲专区61| 中文字幕日韩av| 午夜精品久久久久久99热软件| 日韩在线国产精品| 久久视频在线直播| 国产成人av在线播放| 久久精品国产久精国产一老狼| 欧美色videos| 日韩欧美成人区| 亚洲3p在线观看| 91精品国产亚洲| 精品国产欧美一区二区五十路| 国产午夜精品理论片a级探花| 国产精品r级在线| 亚洲精品久久久久久久久久久久久| 亚洲自拍小视频| 国产精品wwwwww| www国产精品视频| 日本aⅴ大伊香蕉精品视频| 日韩视频一区在线| 久热99视频在线观看| 亚洲午夜女主播在线直播| 日韩乱码在线视频| 91精品国产亚洲| 欧美性xxxxxxxxx| 日韩精品高清视频| 国产成人jvid在线播放| 久久久免费观看| 成人久久久久久| 亚洲天堂免费在线| 久久精品国产免费观看| 日韩av在线免费观看一区| 中文字幕日韩在线视频| 欧美贵妇videos办公室| 韩日精品中文字幕| 欧美激情一区二区三区高清视频| 亚洲激情 国产| 亚洲男女自偷自拍图片另类| 91伊人影院在线播放| 国产综合福利在线| 久久噜噜噜精品国产亚洲综合| 久久久这里只有精品视频| 国产精品国产三级国产专播精品人| 视频一区视频二区国产精品| 亚洲天堂色网站| 日韩美女激情视频| 人人爽久久涩噜噜噜网站| 欧美巨猛xxxx猛交黑人97人| 欧美最近摘花xxxx摘花| 亚洲码在线观看| 欧美又大粗又爽又黄大片视频| 精品久久久久久久久久久久| 日韩福利伦理影院免费| 久久国产精品影视| 亚洲级视频在线观看免费1级| 日本精品免费一区二区三区| 日本精品性网站在线观看| 久久久亚洲天堂| 成人信息集中地欧美| 久久久久久久成人| 国产日产久久高清欧美一区| 欧美人成在线视频| 国产精品女人久久久久久| 欧美极品美女视频网站在线观看免费| 日韩毛片中文字幕| 欧美自拍大量在线观看| 欧美性猛交xxxx久久久| 欧美国产在线视频| 欧美日韩另类在线| 国产激情999| 九九精品在线播放| 最新的欧美黄色| 亚洲国产精品悠悠久久琪琪| 动漫精品一区二区| 色综合伊人色综合网站| 国产精品www| 日韩视频免费在线观看| 粉嫩av一区二区三区免费野| 亚洲一区二区三区成人在线视频精品| 国产欧美日韩综合精品| 国产一区二区三区久久精品| 亚洲精品久久久久国产| 亚洲欧美日韩爽爽影院| 北条麻妃一区二区在线观看| 日韩中文字幕不卡视频| 中文字幕视频在线免费欧美日韩综合在线看| 日韩av影院在线观看| 久久91精品国产91久久久| 欧美电影第一页| 懂色aⅴ精品一区二区三区蜜月|