程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> explorer被殺掉又會重啟的問題

explorer被殺掉又會重啟的問題

編輯:.NET實例教程

聲明:

         本帖原文來自: http://xx.happy369.com/Html/guzhangjj/050528134.htm

                                 和http://xx.happy369.com/Html/guzhangjj/050528298.htm

原文如下:

我很早就發現一個奇怪的現象了,如果你使用任務管理器殺死Explorer.EXE,Windows不會將Explorer.EXE自動喚起,但是如果你自己使用TerminateProcess() 函數結束Explorer.EXE進程,你會發現一個奇怪的現象:被殺死的Explorer.EXE又被Windows自動喚醒了。

在描述具體原因之前,簡單介紹一下Explorer.EXE。Explorer.EXE作為Windows Shell的組件之一,主要的用途包括有:

  1. 顯示桌面、任務欄
  2. 提供圖形化的文件操作方式(例如大家熟知的資源管理器)
  3. ……

總而言之,沒有Explorer.EXE的Windows不是不能運作,而是操作很不方便。

作為Windows Shell重要的一環,Explorer.EXE的啟動由注冊表鍵值(Windows 2000/XP/Server 2003):
鍵:HKEY_LOCAL_MacHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon
鍵名:Shell
默認鍵值:Explorer.EXE

或配置文件system.ini決定(Windows 98/ME):
[Boot]
Shell=Explorer.EXE

需要注意的是,Windows提供了更換Shell的功能,如果上述的配置點不同,那麼Windows會使用其它的Shell,例如把注冊表鍵值更換為cmd.exe,那麼啟動以後你看到的不是圖形化的操作界面而是命令行提示符(很多軟件更換Shell就是這樣變出來的)。如果上述的配置點出現問題,那麼登陸以後你只能看到一個桌面,而桌面上沒有任何的圖標顯示(有部分計算機病毒會這樣操作)。

在回顧了Explorer.EXE的功能以後,下面進入正題,說說Explorer.EXE進程殺死的問題。

由於某些特殊原因,我們需要在某些時候殺死Explorer.EXE進程以達到某些效果,但是在使用中發現,很多程序,包括著名的IceSWord在殺死Explorer.EXE以後,Explorer.EXE都會被Windows自動喚醒。但是如果使用任務管理器(Taskmgr.EXE)或Process Explorer(http://www.sysinternals.com),則沒有這樣的現象,為什麼呢?

對這2個程序的導入表進行分析和動態跟蹤以後,發現這2個程序在結束進程的時候並沒有使用 Undocumented API,使用的還是已經公開的API函數TerminateProcess(),這就很奇怪了,為什麼我們使用TerminateProcess()去結束Explorer.EXE會出現Explorer.EXE在結束以後被Windows自動喚醒的問題而任務管理器和Process Explorer不會呢?

先研究一下 TerminateProcess() 的調用方式:

  1. 以 PROCESS_TERMINATE 方式使用 OpenProcess() API或其他等同方法打開進程句柄
  2. 調用 TerminateProcess() API對被打開的句柄執行終止操作
  3. 使用 CloseHandel() API關閉句柄。

整個流程非常簡單,但是問題到底出在哪裡呢?仔細研究所涉及的API的參數,發現在Platform SDK裡面並沒有對TerminateProcess() API的參數有很相信的解釋,特別是第2個參數說的非常模糊。Platform SDK對TerminateProcess() API是這樣解釋的:

歡迎光臨學網,收藏本篇文章 [1] [2] [3]

$False$

BOOL TerminateProcess(
  HANDLE hProcess,
  UINT uExitCode
);

Parameters
  hProcess
    [in] Handle to the process to terminate.
    The handle must have the PROCESS_TERMINATE Access right.
For more information, see Process Security and Access Rights.
  uExitCode 
    [in] Exit code to be used by the process and threads terminated
as a result of this call. Use the GetExitCodeProcess function to
retrIEve a process''s exit value. Use the GetExitCodeThread function
to retrIEve a thread''s exit value.
   
Return Values
  If the function succeeds, the return value is nonzero.
  If the function fails, the return value is zero. To get extended error
information, call GetLastError.

有什麼特殊的地方嗎?看不出來吧,我也看不出來。但是發現:無論任務管理器還是Process Explorer,在傳入第2個參數:uExitCode的時候,傳入的值總是1。1有什麼特殊的含義嗎?我不知道,因為我沒法得知Windows是否對1有特殊的處理方式。但是從Platform SDK角度看,沒有什麼特殊的發現。

於是我試著創建一個了測試工程用於對TerminateProcess() 的參數進行測試,結果令人大吃一驚:如果我把uExitCode的值設置為1,然後去結束Explorer.EXE,會發現Windows並沒有自動喚醒Explorer.EXE,但是如果我傳入的值是0,則Windows會在Explorer.EXE結束以後自動將Explorer.EXE喚醒。

雖然到目前還是不知道Windows在執行TerminateProcess() 的時候的操作方式(有Windows源代碼就可以知道了),但是經過一些嘗試,關於TerminateProcess() API的一個隱藏點還是暴露了。

 

上次說到當使用TerminateProcess()函數並將參數uExitCode設置為非1時去結束Explorer.EXE進程,Windows會自動喚醒Explorer.EXE進程。今天將繼續討論這個問題。

上次討論到系統啟動的時候,Explorer.EXE進程是由UserInit.EXE進程啟動的,然後UserInit.EXE進程退出(關於這一點可以參考《Windows Internals, 4th》一書關於啟動過程上的介紹),但是對於當我們使用TerminateProcess()函數並將參數uExitCode設置為非1時去結束Explorer.EXE進程這種情況,被喚醒的Explorer.EXE進程的父進程並不是UserInit.EXE,跟蹤發現這個時候UserInit.EXE進程並沒有出現,那麼是誰喚醒了Explorer.EXE進程呢?為什麼會喚醒這個進程呢?

進一步的探索發現,Windows是否喚醒Explorer.EXE進程需要確定2個條件:
1、 TerminateProcess()函數的uExitCode的值
2、 HKEY_LOCAL_MacHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\AutoRestartShell的值
上次說到當uExitCode的值是非1的時候,Windows 將自動重啟Explorer.EXE,但是進一步的研究可以得知,如果AutoRestartShell的值是0的話,無論uExitCode的值是多少Windows均不會自動喚醒Explorer.EXE。

關於AutoRestartShell值的介紹,我查閱了一些資料,得到了下面的一些信息:

歡迎光臨學網,點擊這裡查看更多文章教程 [1] [2] [3]

HKEY_LOCAL_MacHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\AutoRestartShell
類型:REG_DWord
默認值:1
值含義:
   1         如果Windows用戶界面或他的某個組建以外的終止運行,則用戶界面會自動重新啟動。
   0         如果Windows用戶界面或他的某個組建以外的終止運行,則用戶界面不會自動重新啟動。
*注1:這裡說的Windows用戶界面通常指Explorer.EXE
*注2:這個策略適用於Windows 2000/XP/Server 2003

知道了Explorer.EXE自動重啟原因以後,就要說說是誰重新啟動了Explorer.EXE。

是WinLogon.EXE,Windows登錄/注銷等一系列操作的關鍵進程,在偵測到Explorer.EXE停止以後自動重新啟動了Explorer.EXE。

整個大致的流程是這樣的:
  1. 當使用TerminateProcess()函數且uExitCode不為1時去結束Explorer.EXE進程,會有一個消息給SAS(Secure Attention Sequence,關於SAS的解釋請看 MSDN Magazine, 2005年5月號,《Customizing GINA, Part 1》),在這個消息處理函數裡面會檢查uExitCode的值和AutoRestartShell的值,如果發現uExitCode的值是1的話則不進行後面的操作,否則會檢查AutoRestartShell的值,如果是1的話會自動重新啟動Explorer.EXE。表現為由Winlogon.EXE啟動。
  2. 如果TerminateProcess()函數的參數uExitCode為1的話,那麼Windows會認為這個進程結束是graceful的,則不會檢查AutoRestartShell的值。
  3. 自動喚醒的時間是2000毫秒。

至此,關於Explorer.EXE自動重啟的解釋就告一個段落了,在研究過程中得到了眾多朋友的幫助,向他們表示由衷的感謝。希望本文能夠幫助大家對Windows的一些行為有更多的理解。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved