Witam
Próbuję zamknąć system z poziomu Metrowej aplikacji. Napisałem taki kod z użyciem ApiUnlock:
public struct TOKEN_PRIVILEGES
{
public UInt32 PrivilegeCount;
public LUID_AND_ATTRIBUTES Privileges;
}
public struct LUID_AND_ATTRIBUTES
{
public LUID Luid;
public UInt32 Attributes;
}
public struct LUID
{
public UInt32 LowPart;
public Int32 HighPart;
}
public const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
public const int TOKEN_QUERY = 0x00000008;
public const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege";
public const int SE_PRIVILEGE_ENABLED = 0x00000002;
public const int EWX_SHUTDOWN = 0x00000001;
public const int EWX_FORCE = 0x00000004;
public const int SHTDN_REASON_MAJOR_OPERATINGSYSTEM = 0x00020000;
public const int SHTDN_REASON_MINOR_UPGRADE = 0x00000003;
public const uint SHTDN_REASON_FLAG_PLANNED = 0x80000000;
public unsafe delegate bool OpenProcessTokenFunction(
void* ProcessHandle,
UInt32 DesiredAccess,
void** TokenHandle);
public unsafe delegate void* GetCurrentProcessFunction();
public unsafe delegate bool LookupPrivilegeValueFunction(
[MarshalAs(UnmanagedType.LPWStr)] string lpSystemName,
[MarshalAs(UnmanagedType.LPWStr)] string lpName,
LUID* lpLuid);
public unsafe delegate bool AdjustTokenPrivilegesFunction(
void* TokenHandle,
bool DisableAllPrivileges,
TOKEN_PRIVILEGES* NewState,
UInt32 BufferLength,
TOKEN_PRIVILEGES* PreviousState,
UInt32* ReturnLength);
public unsafe delegate UInt32 GetLastErrorFunction();
public unsafe delegate bool ExitWindowsExFunction(
uint uFlags,
UInt32 dwReason);
private unsafe bool shutdown()
{
var OpenProcessToken = ApiUnlocker.GetWin32Function<OpenProcessTokenFunction>("Advapi32.dll", "OpenProcessToken");
var GetCurrentProcess = ApiUnlocker.GetWin32Function<GetCurrentProcessFunction>("Kernel32.dll", "GetCurrentProcess");
var LookupPrivilegeValue = ApiUnlocker.GetWin32Function<LookupPrivilegeValueFunction>("Advapi32.dll", "LookupPrivilegeValueW");
var AdjustTokenPrivileges = ApiUnlocker.GetWin32Function<AdjustTokenPrivilegesFunction>("Advapi32.dll", "AdjustTokenPrivileges");
var GetLastError = ApiUnlocker.GetWin32Function<GetLastErrorFunction>("Kernel32.dll", "GetLastError");
var ExitWindowsEx = ApiUnlocker.GetWin32Function<ExitWindowsExFunction>("User32.dll", "ExitWindowsEx");
void *hToken;
TOKEN_PRIVILEGES tkp;
// Get a token for this process.
if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
return (false);
// Get the LUID for the shutdown privilege.
LookupPrivilegeValue(null, SE_SHUTDOWN_NAME,
&tkp.Privileges.Luid);
tkp.PrivilegeCount = 1; // one privilege to set
tkp.Privileges.Attributes = SE_PRIVILEGE_ENABLED;
// Get the shutdown privilege for this process.
AdjustTokenPrivileges(hToken, false, &tkp, 0,
(TOKEN_PRIVILEGES*)null, (uint*)0);
if (GetLastError() != 0)
return false;
// Shut down the system and force all applications to close.
if (!ExitWindowsEx(EWX_SHUTDOWN | EWX_FORCE,
SHTDN_REASON_MAJOR_OPERATINGSYSTEM |
SHTDN_REASON_MINOR_UPGRADE |
SHTDN_REASON_FLAG_PLANNED))
return false;
//shutdown was successful
return true;
}
Funkcja ExitWindowsEx
zwraca 0
(GetLastError()
== 0
).
Popełniłem gdzieś błąd czy po prostu z poziomu Metro nie da się zamknąć systemu?