咨询区
roomaroo:
我查阅资料发现有一些可使用 C# 关闭用户电脑的方法,但我觉得都不是很简洁,所以我想在这里寻找一种简单或者使用原生 .NET 关闭的方式。
回答区
Pop Catalin:
很简单,直接用 C# 调用 cmd 执行 shutdown
不就可以了吗? 我觉得这是最简单粗暴的做法,如下代码所示:
Process.Start("shutdown","/s /t 0");
如果不想弹出 cmd 窗口,可以设置属性忽略掉。
var psi = new ProcessStartInfo("shutdown","/s /t 0");
psi.CreateNoWindow = true;
psi.UseShellExecute = false;
Process.Start(psi);
当然你也可以通过 P/Invoke
或者 WMI
的方式调用 Win32 API 去搞定。
Ian R. O'Brien:
这是我在学校时期写的比较粗糙的代码,主要就是用 C# 调用 Win32 API 中的 ExitWindowsEx
方法。
using System.Runtime.InteropServices;
void Shutdown2()
{
const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege";
const short SE_PRIVILEGE_ENABLED = 2;
const uint EWX_SHUTDOWN = 1;
const short TOKEN_ADJUST_PRIVILEGES = 32;
const short TOKEN_QUERY = 8;
IntPtr hToken;
TOKEN_PRIVILEGES tkp;
// Get shutdown privileges...
OpenProcessToken(Process.GetCurrentProcess().Handle,
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, out hToken);
tkp.PrivilegeCount = 1;
tkp.Privileges.Attributes = SE_PRIVILEGE_ENABLED;
LookupPrivilegeValue("", SE_SHUTDOWN_NAME, out tkp.Privileges.pLuid);
AdjustTokenPrivileges(hToken, false, ref tkp, 0U, IntPtr.Zero,
IntPtr.Zero);
// Now we have the privileges, shutdown Windows
ExitWindowsEx(EWX_SHUTDOWN, 0);
}
// Structures needed for the API calls
private struct LUID
{
public int LowPart;
public int HighPart;
}
private struct LUID_AND_ATTRIBUTES
{
public LUID pLuid;
public int Attributes;
}
private struct TOKEN_PRIVILEGES
{
public int PrivilegeCount;
public LUID_AND_ATTRIBUTES Privileges;
}
[DllImport("advapi32.dll")]
static extern int OpenProcessToken(IntPtr ProcessHandle,
int DesiredAccess, out IntPtr TokenHandle);
[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool AdjustTokenPrivileges(IntPtr TokenHandle,
[MarshalAs(UnmanagedType.Bool)]bool DisableAllPrivileges,
ref TOKEN_PRIVILEGES NewState,
UInt32 BufferLength,
IntPtr PreviousState,
IntPtr ReturnLength);
[DllImport("advapi32.dll")]
static extern int LookupPrivilegeValue(string lpSystemName,
string lpName, out LUID lpLuid);
[DllImport("user32.dll", SetLastError = true)]
static extern int ExitWindowsEx(uint uFlags, uint dwReason);
在生产代码中,你应该检查这些 Win32 API 的返回值,这里我为了代码的简洁无视了这些判断。
点评区
哈哈,用C#
操控电脑,这本身就是一个很有意思的东西,我感觉这套题目给了我很多的灵感,要学会擅长用 C# 操作 cmd ,刚好我前段时间给 apk 自动打包,就是用 C# 启动 cmd 调用 apktool
去给 apk 反向编译
,为了就是把私有sqlite塞进去,然后再 正向编译
成apk,这不又让公司的服务提高了一个档次!😁😁😁
技术群:添加小编微信并备注进群
小编微信:mm1552923
公众号:dotNet编程大全