国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > .NET > 正文

通過ASP.NET頁面重啟服務器

2024-07-10 13:06:40
字體:
來源:轉載
供稿:網友

最近在設計網站后臺管理系統的時候,想到了是否可以通過頁面重啟windows服務器

到google搜索了一下,找到了一段似乎很普遍的代碼

事實證明,這段代碼在寫桌面應用例如console或者windows form程序的時候可以正常運行,但是通過asp.net調用則無法通過

但是我還是把這段代碼貼出來,因為其中除了個別兩行外,其他的還是重啟服務器的必須代碼

新建一個類,在里面填入如下代碼:

首先是命名空間,調用win api的時候,interopservices不可少:
using system;
using system.runtime.interopservices;
然后是一系列的常量聲明: protected const int se_privilege_enabled = 0x2;
protected const int token_query = 0x8;
protected const int token_adjust_privileges = 0x20;
protected const string se_shutdown_name = "seshutdownprivilege";
protected const int ewx_logoff = 0x0;
protected const int ewx_shutdown = 0x1;
protected const int ewx_reboot = 0x2;
protected const int ewx_force = 0x4;
protected const int ewx_poweroff = 0x8;
protected const int ewx_forceifhung = 0x10;
定義luid結構,注意屬性: [structlayout(layoutkind.sequential, pack=1)]
protected struct luidstruct {
    public int count;
    public long luid;
    public int attr;
}
外部非托管dll的聲明: [dllimport("kernel32.dll", exactspelling=true)]
protected static extern intptr getcurrentprocess();

[dllimport("advapi32.dll", setlasterror=true)]
protected static extern bool openprocesstoken(intptr h, int acc, ref intptr phtok);

[dllimport("advapi32.dll", setlasterror=true)]
protected static extern bool lookupprivilegevalue(string host, string name, ref long pluid);

[dllimport("advapi32.dll", setlasterror=true, exactspelling=true)]
protected static extern bool adjusttokenprivileges(intptr htok, bool disall, ref luidstruct newst, int len, intptr prev, intptr relen);

[dllimport("user32.dll", setlasterror=true, exactspelling=true)]
protected static extern bool exitwindowsex(int flg, int rea);
在nt級的操作系統上,需要先通知windows系統即將關機,并且要獲得關機的權限

以下就是關機、重啟以及注銷的實現: protected static void doexitwindows(int flg) {
    luidstruct tp;
    intptr hproc = getcurrentprocess();
    intptr htok = intptr.zero;

    openprocesstoken(hproc, token_adjust_privileges | token_query, ref htok);
    tp.count = 1;
    tp.luid = 0;
    tp.attr = se_privilege_enabled;
    lookupprivilegevalue(null, se_shutdown_name, ref tp.luid);
    adjusttokenprivileges(htok, false, ref tp, 0, intptr.zero, intptr.zero);
    exitwindowsex(flg, 0);
}

public static void shutdown() {
    doexitwindows(ewx_shutdown);
}

public static void reboot() {
    doexitwindows(ewx_reboot | ewx_force);
}

public static void logoff() {
    doexitwindows(ewx_logoff);
}
至此,重啟代碼結束,這段代碼可以很好地工作在交互環境下,也就是在用戶已經登錄進windows的情況下

但是asp.net是運行在非交互環境下的,查閱msdn,在exitwindowsex函數定義下面發現這樣一段話:


the exitwindowsex function returns as soon as it has initiated the shutdown process. the shutdown or logoff then proceeds asynchronously. the function is designed to stop all processes in the caller's logon session. therefore, if you are not the interactive user, the function can succeed without actually shutting down the computer. if you are not the interactive user, use the initiatesystemshutdown or initiatesystemshutdownex function.

于是得到啟發,發現非交互下重啟服務器不可以用exitwindowsex,需要將其替換成initiatesystemshutdown:

[dllimport("advapi32.dll", setlasterror=true, exactspelling=false)]
protected static extern bool initiatesystemshutdown(string name, string msg, int timeout, bool force, bool reboot);
參數解釋:
name:機器名,用于重啟局域網內的其它機器,如果為 null 則是本機
msg:重啟消息,會顯示在重啟消息框上,在windows 2003和xp中也會作為消息日志被保存
timeout:如果不是0,那么會顯示一個重新消息框,倒計時timeout秒后重啟
force:強制重啟,不等待應用程序提示是否保存工作,對于服務器來說,應該是true
reboot:是否是重啟,如果是false,那么做關機處理,對于服務器,應該是true

先按照文章一開始的方法調用 adjusttokenprivileges 得到privilege,然后在asp.net頁面里面執行: initiatesystemshutdown(null,null,0,true,true);
系統就重啟了

這里有一點說下,如果重啟本機,那么多半會返回service unavailable錯誤,這是因為在asp.net執行結束之前系統已經開始結束各個進程了,當然包括asp.net進程,算是正常表現,雖然看起來有些不太舒服

另外由于目前我只在自己機器上測試通過,所以沒有詳細研究權限問題,所以無法確定在一般服務器上是否可以正常運行

初步只想到可以用權限模擬解決,即在web.config文件system.web節寫上<identity impersonate="true" username="administrator" password="pass">,不過沒有經過確認,有時間會嘗試一下。web.config不是很安全,所以這里可能要借助于dpapi,有點扯遠了,就先到這里吧。

商業源碼熱門下載www.html.org.cn

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 乌兰察布市| 大英县| 青铜峡市| 三原县| 祁阳县| 白城市| 特克斯县| 博野县| 北碚区| 阿尔山市| 渝中区| 宝应县| 南乐县| 许昌市| 拜泉县| 本溪市| 石林| 福贡县| 九龙城区| 都江堰市| 南雄市| 盘山县| 岳阳县| 英超| 临朐县| 海伦市| 崇州市| 广宁县| 阜城县| 高安市| 易门县| 巴楚县| 西吉县| 哈巴河县| 丹寨县| 洛隆县| 娱乐| 辽中县| 北海市| 沙坪坝区| 比如县|