我有一个使用本地管理员帐户从服务中启动的应用程序。该应用程序可通过Web浏览器访问,主机PC可通过此界面关闭。
如果用户登录到主机PC并浏览并关闭它,应用程序将退出并关闭PC,如我所料 - 使用ExitWindowsEx()(启用了shutdown特权)。
但是,如果PC已注销,我浏览到它 - 应用程序仍然在服务中运行,并尝试使用ExitWindowsEx()关闭,它返回成功,似乎没有问题,但PC从未关闭下来。
我也尝试过InitiateSystemShutdown(),这种情况很糟糕,并返回错误2! (该系统找不到指定的文件)。
用于启动应用程序的帐户似乎并不重要。
非常感谢任何帮助!
感谢。
答案 0 :(得分:1)
void RebootThisMachine ()
{
if (GrabPrivilege (SE_SHUTDOWN_NAME))
{
if (!InitiateSystemShutdown (NULL,NULL,0,TRUE,TRUE))
{
wsprintf (g_szDebug, TEXT("RebootMachine - ISS failed, error %d"),
GetLastError()) ;
DebugMessage (DEBUG_ERROR, g_szDebug) ;
}
}
else
{
wsprintf (g_szDebug, TEXT("RebootMachine - cannot grab priv, error %d"),
GetLastError()) ;
DebugMessage (DEBUG_ERROR, g_szDebug) ;
}
}
当我从我写的一个小命令行实用程序收到邮件消息时调用它。 InitiateSystemShutdown是服务的正确API,无论是否已登录,它都会重新启动运行该服务的计算机。如果我的(远景)机器没有登录,关机确实需要一段时间,但它最终会起作用(在30-40s之后说“关闭”)。我的服务在LocalSystem下执行。 GrabPrivilege与我之前发布的代码相同。
所以你可以从你想要做的事情 这一事实中获益。我发现您使用的是管理员帐户来运行您的服务。您是否尝试在LocalSystem下运行服务以进行关机测试?也许管理员的权限与LocalSystem的权限不匹配......
答案 1 :(得分:0)
如果我http://www.google.ca/search?hl=en&q=exitwindowsex+service那么我发现的第一件事就是http://www.eggheadcafe.com/software/aspnet/29901267/lockworkstation-and-exitw.aspx,这表明如果您的服务启用了“与桌面交互”标志(已弃用),则会出现问题。
然后人们会在回复上述主题的各种消息中提出修正建议,例如http://www.eggheadcafe.com/conversation.aspx?messageid=29901274&threadid=29901267 ......这样的事情可能会对您有所帮助。
另一种选择,肯定是一种kludge,但它避免使用建议的魔法,可能是运行第二个服务而不与桌面交互:让第二个服务调用ExitWindowsEx ...并使用任何IPC(或者特定于服务的API)从第一个服务(或者可能来自应用程序)触发第二个服务。
答案 2 :(得分:0)
试试这段代码并告诉我们它的作用:
GrabPrivilege (SE_SHUTDOWN_NAME);
ExitWindowsEx (EWX_REBOOT|EWX_FORCE, 0); // or whatever EWX flags you want
辅助功能:
BOOL GrabPrivilege (LPCTSTR lpctPrivName)
{
TOKEN_PRIVILEGES newtkp;
HANDLE hToken;
BOOL bRetVal = FALSE;
if (OpenProcessToken (GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
&hToken))
{
LookupPrivilegeValue (NULL,
lpctPrivName,
&newtkp.Privileges[0].Luid);
newtkp.PrivilegeCount = 1; // one privilege to set
newtkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (AdjustTokenPrivileges (hToken,
FALSE,
&newtkp,
0,
(PTOKEN_PRIVILEGES) NULL,
0))
{
DWORD dwRet = GetLastError();
if (dwRet == ERROR_SUCCESS) bRetVal = TRUE;
}
}
CloseHandle (hToken);
return bRetVal;
}
答案 3 :(得分:0)
您是否尝试过使用 shutdown.exe 工具?它报告了什么错误?
我遇到了与Windows XP x64相同的问题,但我是通过WMI远程进行的,但是关机工具给了我同样的错误(21)。有了这些信息,我遇到了这个修补程序:
http://support.microsoft.com/kb/834100
我无法测试它,因为我目前没有Windows 2003 Server,但也许它会有所帮助。