想要实现自动关机,找到了ExitWindwsEx,不过只能实现注销功能,查了下才知道和权限有关,我不知道如何实现,找了下,只找到了一点和C#相关的代码如下,说是实现自动关机的:internal class TokenAdjuster
{
[DllImport("user32.dll")]
internal static extern bool ExitWindowsEx(int uFlags,int dwReserved); // PInvoke stuff required to set/enable security privileges
[DllImport("advapi32", SetLastError=true)]
[SuppressUnmanagedCodeSecurity]
static extern int OpenProcessToken(
   IntPtr ProcessHandle, // handle to process
   int DesiredAccess, // desired access to process
   ref IntPtr TokenHandle // handle to open access token
); [DllImport("kernel32", SetLastError=true)]
[SuppressUnmanagedCodeSecurity]
static extern bool CloseHandle(IntPtr handle); [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
[SuppressUnmanagedCodeSecurity]
static extern int AdjustTokenPrivileges(
    IntPtr TokenHandle,
    int DisableAllPrivileges,
    IntPtr NewState,
int BufferLength,
IntPtr PreviousState,
ref int ReturnLength); [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
[SuppressUnmanagedCodeSecurity]
static extern bool LookupPrivilegeValue(
string lpSystemName,
string lpName,
ref LUID lpLuid); [StructLayout(LayoutKind.Sequential)]
internal struct LUID 
{
internal int LowPart;
internal int HighPart;
} [StructLayout(LayoutKind.Sequential)]
internal struct LUID_AND_ATTRIBUTES 
{
LUID Luid;
int Attributes;
} [StructLayout(LayoutKind.Sequential)]
internal struct _PRIVILEGE_SET 
{
int PrivilegeCount;
int Control;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=1)] // ANYSIZE_ARRAY = 1
LUID_AND_ATTRIBUTES [] Privileges;
} [StructLayout(LayoutKind.Sequential)]
internal struct TOKEN_PRIVILEGES
{
internal int PrivilegeCount;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=3)]
internal int[] Privileges;
} const int SE_PRIVILEGE_ENABLED = 0x00000002;
const int TOKEN_ADJUST_PRIVILEGES = 0X00000020;
const int TOKEN_QUERY = 0X00000008;
const int TOKEN_ALL_ACCESS = 0X001f01ff;
const int PROCESS_QUERY_INFORMATION = 0X00000400; public static bool SetPrivilege (string privilege, bool enablePrivilege)
{
bool retval = false;
int ltkpOld = 0;
IntPtr hToken = IntPtr.Zero;
TOKEN_PRIVILEGES tkp = new TOKEN_PRIVILEGES();
tkp.Privileges = new int[3];
TOKEN_PRIVILEGES tkpOld = new TOKEN_PRIVILEGES();
tkpOld.Privileges = new int[3];
LUID tLUID = new LUID();
tkp.PrivilegeCount = 1;
if (enablePrivilege)
tkp.Privileges[2] = SE_PRIVILEGE_ENABLED;
else
tkp.Privileges[2] = 0;
if(LookupPrivilegeValue(null , privilege , ref tLUID))
{
Process proc = Process.GetCurrentProcess();
if(proc.Handle != IntPtr.Zero) 
{
if (OpenProcessToken(proc.Handle, TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,ref hToken) != 0) 
{
tkp.PrivilegeCount = 1;
tkp.Privileges[2] = SE_PRIVILEGE_ENABLED;
tkp.Privileges[1] = tLUID.HighPart;
tkp.Privileges[0] = tLUID.LowPart;
const int bufLength = 256;
IntPtr tu = Marshal.AllocHGlobal(ufLength );
Marshal.StructureToPtr(tkp, tu, true);
if(AdjustTokenPrivileges(hToken, 0, tu, bufLength, IntPtr.Zero, ref ltkpOld) != 0)
{
// successful AdjustTokenPrivileges doesn't mean privilege could be changed
int iError = Marshal.GetLastWin32Error();
if (iError == 0)
{
retval = true; // Token changed
}
else
{
throw new ApplicationException(iError.ToString());
}
}
TOKEN_PRIVILEGES tokp = (TOKEN_PRIVILEGES) Marshal.PtrToStructure(tu,
typeof(TOKEN_PRIVILEGES) );
Marshal.FreeHGlobal( tu );
}
}
}
if (hToken != IntPtr.Zero)
{
CloseHandle(hToken);
}
return retval;
}
}不过看了之后,实在是有点云里雾里,不知道这个能不能实现,如果能,请问如何用?不能的话,正确的该如何写呢??

解决方案 »

  1.   

    快速关机:
    Process.Start("cmd.exe","/c shutdown -s -t 0 -f");
      

  2.   


    我把代码放这里了,测试通过的
    http://www.dreamup.net/~xoop/rental30/home/13565654545/closexp.htm
      

  3.   

    参看
    http://community.csdn.net/Expert/topicview.asp?id=1704985
      

  4.   

    快速关机:
    Process.Start("cmd.exe","/c shutdown -s -t 0 -f");同意   简单.
      

  5.   

    快速关机:
    Process.Start("cmd.exe","/c shutdown -s -t 0 -f");这个只对winXP有用,其它系统就不可以了,例如2000
      

  6.   

    我记得就是一条语句就能搞定,当时我是2000,不过现在的机器里没装.net,没法找到了
      

  7.   

    你那条语句必须要在C:\WINDOWS\system32下有个shutdown.exe的文件才可以用的,XP系统大多都有这个文件,2000系统一般都没有,不过没有可以copy一个进去也可以。
    Process.Start("cmd.exe","/c shutdown -s -t 0 -f");这条语句要添加对System.Diagnostics命名空间的引用才能用。它的效果跟你在 开始-运行 里运行shutdown -s -t 0 -f是一样的。0是时间,秒为单位,指多少秒后关机。
      

  8.   

    BOOL MySystemShutdown()
    {
       HANDLE 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[0].Luid); 
     
       tkp.PrivilegeCount = 1;  // one privilege to set    
       tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 
     
       // Get the shutdown privilege for this process. 
     
       AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, 
            (PTOKEN_PRIVILEGES)NULL, 0); 
     
       if (GetLastError() != ERROR_SUCCESS) 
          return FALSE; 
     
       // Shut down the system and force all applications to close. 
     
       if (!ExitWindowsEx(EWX_SHUTDOWN | EWX_FORCE, 0)) 
          return FALSE;    return TRUE;
    }
    这是msdn中exitwindowsex的例子,相信你已经看过,上面的C#代码是完成其中的权限设置部分的。你说所的只能注销的问题不是权限问题,if (!ExitWindowsEx(EWX_SHUTDOWN | EWX_FORCE, 0)) 一句中的参数用EWX_POWEROFF即可。