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

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

在服務程序中彈出對話框

2019-11-11 04:41:52
字體:
來源:轉載
供稿:網友
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
亚洲一区二区三区久久| 久久久精品久久久| 国产精品老女人视频| 精品久久久久国产| 黄色成人av在线| 国产高清视频一区三区| 成人精品视频久久久久| 午夜免费日韩视频| 日本中文字幕久久看| 国产精品一区二区三| 国产成人jvid在线播放| 国产成人综合一区二区三区| 日韩国产中文字幕| 精品欧美国产一区二区三区| 国产精品国产三级国产专播精品人| 久久不射电影网| 国产精品尤物福利片在线观看| 国产成人精品视频| 国产极品jizzhd欧美| 国产精品久久久久久亚洲调教| 92国产精品久久久久首页| 亚洲欧美日韩久久久久久| 精品性高朝久久久久久久| 亚洲国产日韩欧美在线99| 一区二区三区在线播放欧美| 中文字幕日韩在线播放| 成人a视频在线观看| 欧美在线视频一二三| 国产精品69久久| 亚洲人午夜精品| 久久久噜噜噜久久中文字免| 91中文字幕一区| 亚洲午夜未删减在线观看| 色久欧美在线视频观看| 国产成人久久久精品一区| 亚洲免费影视第一页| 97在线免费观看视频| xvideos国产精品| 国产精品成人观看视频国产奇米| 在线精品国产欧美| 国产精品国模在线| 91在线观看欧美日韩| 久久久久久999| 国产精品一区二区三| 欧美夜福利tv在线| 日韩av中文字幕在线| 国产综合在线视频| 久久久av电影| 欧美日韩一区二区免费在线观看| 久久久久久久国产| 国产精品旅馆在线| 国产在线一区二区三区| 国产精品三级美女白浆呻吟| 成人av.网址在线网站| 北条麻妃在线一区二区| 国产精品福利久久久| 欧美激情视频播放| 欧美日韩高清区| 亚洲的天堂在线中文字幕| 美女国内精品自产拍在线播放| 亚洲美女av黄| 亚洲欧美日韩直播| 日本一区二区在线免费播放| 亚洲欧美国产高清va在线播| 久久久久亚洲精品国产| 欧美中在线观看| 欧美视频13p| 日韩美女激情视频| 国产成人精品网站| 国产v综合ⅴ日韩v欧美大片| 欧美寡妇偷汉性猛交| 97在线视频免费看| 黄色91在线观看| 国产精品久久久久久久久免费看| 亚洲精品一区二三区不卡| 97在线观看视频国产| 国产成人欧美在线观看| 日韩中文字幕在线看| 色999日韩欧美国产| 国产精品热视频| 午夜伦理精品一区| 中文字幕日韩专区| 国产精品中文字幕在线| 国产精品一区二区性色av| 欧美亚洲国产日本| 国产精品久久久久久久久粉嫩av| 欧美日本黄视频| 亚洲图片在线综合| 成人免费看黄网站| 国产精品三级在线| www.国产一区| 国产美女久久精品香蕉69| 性色av香蕉一区二区| 亚洲精品福利资源站| 亚洲精品一区av在线播放| 久久天天躁狠狠躁夜夜躁2014| 亚洲免费福利视频| 日韩美女中文字幕| 奇米四色中文综合久久| 亚洲欧美在线免费| 国产综合福利在线| 欧美中文在线视频| 亚洲国产精品成人va在线观看| 欧美日韩久久久久| 久久久久亚洲精品成人网小说| 国产精品久久久久久网站| 中文字幕精品在线视频| 欧美视频在线观看 亚洲欧| 亚洲白拍色综合图区| 国产精品偷伦视频免费观看国产| 最近2019免费中文字幕视频三| 国产成人在线精品| 亚洲人精品午夜在线观看| 国产一区二区在线免费| 成人激情视频在线| 国产精品三级美女白浆呻吟| 精品成人国产在线观看男人呻吟| 欧美国产日韩中文字幕在线| 国产主播精品在线| 91精品久久久久久久久久| 日韩av网址在线| 久久精品影视伊人网| 久久久精品免费| 热99精品里视频精品| 久久久久99精品久久久久| 欧美精品videosex极品1| 日本一区二区三区四区视频| 91精品久久久久久久久中文字幕| 日本亚洲精品在线观看| 欧美性猛交xxxx免费看漫画| 成人激情视频在线观看| 91精品视频大全| 91经典在线视频| 一区二区三区回区在观看免费视频| 97视频在线观看视频免费视频| 欧美一区二区大胆人体摄影专业网站| 性金发美女69hd大尺寸| 欧美激情在线有限公司| 亚洲国产精品网站| 91国偷自产一区二区三区的观看方式| 欧美日韩国产一区二区| 日本欧美国产在线| 亚洲最新中文字幕| 午夜精品美女自拍福到在线| 伊人久久免费视频| 亚洲一区二区精品| 国产精品美女在线| 中文字幕一区二区精品| 精品亚洲夜色av98在线观看| 日韩一区二区久久久| 亚洲国产精品久久精品怡红院| 国产乱人伦真实精品视频| 亚洲国产成人久久| 性欧美xxxx| 午夜精品三级视频福利| 亚洲欧美中文日韩在线v日本| 国产精品免费久久久| 日韩精品视频在线| 欧美激情中文字幕乱码免费| 日韩精品中文字幕有码专区| 98精品在线视频| 日韩精品在线私人| 欧美综合国产精品久久丁香| 国产精品爽爽爽|