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

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

在服務程序中彈出對話框

2019-11-11 04:38:48
字體:
來源:轉載
供稿:網友
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; }  }   


上一篇:poj1004

下一篇:第三章-MFC運行機制

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩免费看的电影电视剧大全| 国产在线视频欧美| 啪一啪鲁一鲁2019在线视频| 中文字幕日韩专区| 亚洲欧美日韩网| 久久精品中文字幕电影| 久久久久免费视频| 伊人久久综合97精品| 91av福利视频| 久久精彩免费视频| 91美女福利视频高清| 日韩av在线免费播放| 午夜精品三级视频福利| 日本欧美精品在线| 欧美精品电影在线| 在线播放亚洲激情| 日本aⅴ大伊香蕉精品视频| 久久av在线播放| 色无极影院亚洲| 亚洲精品日产aⅴ| 日韩av电影手机在线| 精品偷拍各种wc美女嘘嘘| 国产69精品久久久久9999| 在线亚洲男人天堂| 中文字幕久久久av一区| 97婷婷涩涩精品一区| 亚洲欧洲在线看| 亚洲美腿欧美激情另类| 亚洲伊人久久综合| 国产亚洲aⅴaaaaaa毛片| 精品毛片三在线观看| 亚洲国产97在线精品一区| 精品国产网站地址| 欧美性猛交xxxx| 一本色道久久88精品综合| 欧美午夜激情小视频| 精品久久久久久亚洲精品| 日韩精品在线观看视频| 色偷偷av一区二区三区乱| 精品亚洲一区二区三区在线播放| 国产亚洲人成a一在线v站| 亚洲第一精品久久忘忧草社区| 欧美大码xxxx| 4438全国亚洲精品在线观看视频| 国产一区私人高清影院| 亚洲一区二区福利| 日韩欧美在线中文字幕| 国产日产久久高清欧美一区| 57pao国产精品一区| 久久久久久尹人网香蕉| 日韩电影在线观看中文字幕| 蜜月aⅴ免费一区二区三区| 18性欧美xxxⅹ性满足| 亚洲精品成a人在线观看| 91精品国产综合久久香蕉| 7777免费精品视频| 欧美一区二粉嫩精品国产一线天| 热久久视久久精品18亚洲精品| 精品国产一区二区三区在线观看| 91精品久久久久久久久久久久久| 中文亚洲视频在线| 91免费观看网站| 45www国产精品网站| 亚洲欧美国产制服动漫| 亚洲综合精品伊人久久| 亚洲精品久久久久中文字幕二区| 亚洲iv一区二区三区| 国模极品一区二区三区| 亚洲bt天天射| 成人a免费视频| 国产视频精品va久久久久久| 亚洲午夜女主播在线直播| 欧美裸身视频免费观看| 91国产中文字幕| 亚洲欧美日韩爽爽影院| 国产在线不卡精品| 欧美日韩成人在线视频| 精品国内自产拍在线观看| 91精品国产91久久久久| 久久精品免费电影| 久久91精品国产91久久跳| 国产亚洲视频中文字幕视频| 国产精品吴梦梦| 欧美性猛交xxxxx水多| 69国产精品成人在线播放| 夜夜嗨av色综合久久久综合网| 一区二区成人av| 日本成人精品在线| 国内揄拍国内精品少妇国语| 在线观看国产欧美| 亚洲精品在线不卡| 欧美成人高清视频| 北条麻妃99精品青青久久| 成人444kkkk在线观看| 91精品啪aⅴ在线观看国产| 538国产精品视频一区二区| 久久偷看各类女兵18女厕嘘嘘| 亚洲欧洲成视频免费观看| 亚洲女人天堂av| 在线观看欧美日韩| 日韩美女av在线免费观看| 5566日本婷婷色中文字幕97| 亚洲国产精品久久久久| 久久精品99国产精品酒店日本| 亚洲黄色免费三级| 国内精品久久久久影院优| 九九热精品视频国产| 欧美精品18videosex性欧美| 国产偷国产偷亚洲清高网站| 欧美多人乱p欧美4p久久| 国产精品成av人在线视午夜片| 日韩有码片在线观看| 亚洲欧美国产日韩中文字幕| 国产欧美一区二区三区在线| 国产成人福利夜色影视| 久久国产一区二区三区| 91精品国产91久久久久久不卡| 国产精品久久久久久久久久东京| 视频直播国产精品| 一区二区中文字幕| 中文国产成人精品久久一| 亚洲自拍欧美另类| 欧美视频第一页| 国产精品精品视频| 日韩免费观看在线观看| 美女av一区二区三区| 成人av在线天堂| 日韩精品有码在线观看| 亚洲第一色中文字幕| 国产欧美在线看| 国产成人鲁鲁免费视频a| 久久久日本电影| 久久成人精品电影| 国外成人免费在线播放| 亚洲午夜久久久影院| 日韩av在线不卡| 国产在线精品成人一区二区三区| 国内精品久久久久影院 日本资源| 在线观看91久久久久久| 精品国产精品自拍| 日韩欧美中文在线| 精品视频在线导航| 日韩av中文字幕在线| 亚洲第一免费播放区| 黄色精品在线看| 精品中文字幕在线| 色yeye香蕉凹凸一区二区av| 欧美午夜美女看片| 91精品国产综合久久久久久久久| 国产日韩在线免费| 欧洲成人在线观看| 日韩在线视频免费观看高清中文| 最近日韩中文字幕中文| 九九视频这里只有精品| 国产欧美日韩91| 日韩电影大片中文字幕| 欧美激情18p| 久久天天躁狠狠躁夜夜av| 另类专区欧美制服同性| 久久久久成人精品| 欧美日韩一区二区精品| wwwwwwww亚洲| 国产精品99久久99久久久二8| 成人中文字幕+乱码+中文字幕|