C# Windows Server 2012 R2上ExitWindowsEx与标准用户的行为差异
我正在写一个C程序,它调用C# Windows Server 2012 R2上ExitWindowsEx与标准用户的行为差异,c#,admin,windows-server-2012-r2,reboot,C#,Admin,Windows Server 2012 R2,Reboot,我正在写一个C程序,它调用ExitWindowsEx重新启动计算机。使用此代码,我提升了权限。该程序在Windows 7和10上运行良好,但在标准用户的Windows Server 2012 R2上失败。如果我以管理员身份运行程序,但系统只是注销并直接返回登录页面 关闭的安全策略 未添加标准用户。此用户没有重新启动权限。这就是我无法重新启动的原因吗 我试图用管理员权限调用shutdown.exe进程,操作系统可能会重新启动。调用函数ExitWindowsEx和启动进程“shutdown.exe
ExitWindowsEx
重新启动计算机。使用此代码,我提升了权限。该程序在Windows 7和10上运行良好,但在标准用户的Windows Server 2012 R2上失败。如果我以管理员身份运行程序,但系统只是注销并直接返回登录页面
关闭的安全策略
未添加标准用户。此用户没有重新启动权限。这就是我无法重新启动的原因吗
我试图用管理员权限调用shutdown.exe进程,操作系统可能会重新启动。调用函数ExitWindowsEx
和启动进程“shutdown.exe”有什么区别?
附上我的代码:
static void RebootComputer()
{
IntPtr tokenHandle = IntPtr.Zero;
try
{
// get process token
if (!NativeMethods.OpenProcessToken(Process.GetCurrentProcess().Handle,
TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
out tokenHandle))
{
throw new Win32Exception(Marshal.GetLastWin32Error(),
"Failed to open process token handle");
}
// lookup the shutdown privilege
NativeMethods.TOKEN_PRIVILEGES tokenPrivs = new NativeMethods.TOKEN_PRIVILEGES();
tokenPrivs.PrivilegeCount = 1;
tokenPrivs.Privileges = new NativeMethods.LUID_AND_ATTRIBUTES[1];
tokenPrivs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!NativeMethods.LookupPrivilegeValue(null,
SE_SHUTDOWN_NAME,
out tokenPrivs.Privileges[0].Luid))
{
throw new Win32Exception(Marshal.GetLastWin32Error(),
"Failed to open lookup shutdown privilege");
}
// add the shutdown privilege to the process token
if (!NativeMethods.AdjustTokenPrivileges(tokenHandle,
false,
ref tokenPrivs,
0,
IntPtr.Zero,
IntPtr.Zero))
{
throw new Win32Exception(Marshal.GetLastWin32Error(),
"Failed to adjust process token privileges");
}
// reboot
if (!NativeMethods.ExitWindowsEx(NativeMethods.ExitWindows.ShutDown,
NativeMethods.ShutdownReason.MajorApplication |
NativeMethods.ShutdownReason.MinorInstallation |
NativeMethods.ShutdownReason.FlagPlanned))
{
throw new Win32Exception(Marshal.GetLastWin32Error(),
"Failed to reboot system");
}
}
catch (Exception e)
{
WriteSystemEventLog("Failed to reboot the computer. Exception Message: 0x" + e.HResult.ToString("x")+"\r\n" + e.Message);
}
finally
{
// close the process token
if (tokenHandle != IntPtr.Zero)
{
NativeMethods.CloseHandle(tokenHandle);
}
}
}
// call shutdown.exe works
static void Reboot()
{
var psi = new ProcessStartInfo("shutdown", "/r /t 0");
psi.CreateNoWindow = false;
psi.UseShellExecute = false;
Process.Start(psi);
}
NativeMethod:
[StructLayout(LayoutKind.Sequential)]
public struct LUID
{
public uint LowPart;
public int HighPart;
}
[StructLayout(LayoutKind.Sequential)]
public struct LUID_AND_ATTRIBUTES
{
public LUID Luid;
public uint Attributes;
}
public struct TOKEN_PRIVILEGES
{
public uint PrivilegeCount;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public LUID_AND_ATTRIBUTES[] Privileges;
}
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ExitWindowsEx(ExitWindows uFlags,
ShutdownReason dwReason);
[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool OpenProcessToken(IntPtr ProcessHandle,
uint DesiredAccess,
out IntPtr TokenHandle);
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool LookupPrivilegeValue(string lpSystemName,
string lpName,
out LUID lpLuid);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CloseHandle(IntPtr hObject);
[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool AdjustTokenPrivileges(IntPtr TokenHandle,
[MarshalAs(UnmanagedType.Bool)]bool DisableAllPrivileges,
ref TOKEN_PRIVILEGES NewState,
uint Zero,
IntPtr Null1,
IntPtr Null2);
可能会向我们展示一些您的代码吗?旁注:由于您的代码与MSDN上的代码基本相同(来自的示例),您还可以链接到它以使其看起来更权威(并非MSDN总是正确的,只是Win32 API的位置)