学了三个月C#,这是我第一个真正动过脑子的程序。目的是设置只允许儿子在星期六或星期天的下午用电脑2小时,而且每小时之间还要休息一段时间。我使用了Win7设置一个普通权限的用户名给儿子。并兴冲冲的设计了一个控制台程序,本以为一个EXE文件可以很绿色很环保,可是问题来了,不管怎么搞,程序都是执行后即退出DOS窗口,Timer也就不会继续计时,那怕1000毫秒都不计。以下为程序:
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Timers;
using System.Runtime.InteropServices;
using System.Threading;
namespace ShutDownComputer
{
class Program
{
static void Main(string[] args)
{
string userName = Environment.UserName;
//识别用户名,进入星期判断
if (userName == "binhan")
Times.ShutdownOfWeek();
}
}
class Times
{
private static System.Timers.Timer aTimer;
//Timer事件
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
//一小时一到,即运行注销
Shutdown.DoExitWin(Shutdown.EWX_FORCE | Shutdown.EWX_LOGOFF);
}
//判断是否星期六、星期日,若是即进入时间区间判断
public static void ShutdownOfWeek()
{
int dayOfWeek = (int)DateTime.Now.DayOfWeek;
if (dayOfWeek == 6 || dayOfWeek == 0)
ShutdownOfTime();
else
Shutdown.DoExitWin(Shutdown.EWX_FORCE | Shutdown.EWX_LOGOFF);
}
//时间区间判断
public static void ShutdownOfTime()
{
//读取系统当前时间
DateTime NowTime = new DateTime();
NowTime = DateTime.Now;
//设置允许使用的时间区间
DateTime EachTime1 = new DateTime(NowTime.Year, NowTime.Month, NowTime.Day, 12, 30, 00);
DateTime EachTime2 = new DateTime(NowTime.Year, NowTime.Month, NowTime.Day, 13, 30, 00);
DateTime EachTime3 = new DateTime(NowTime.Year, NowTime.Month, NowTime.Day, 15, 30, 00);
DateTime EachTime4 = new DateTime(NowTime.Year, NowTime.Month, NowTime.Day, 16, 30, 00);
aTimer = new System.Timers.Timer();
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.AutoReset = false;
aTimer.Interval = 3600000;
if (NowTime >= EachTime1 && NowTime <= EachTime2)
{
aTimer.Enabled = true;
}
else
{
if (NowTime >= EachTime3 && NowTime <= EachTime4)
{
aTimer.Enabled = true;
}
else
Shutdown.DoExitWin(Shutdown.EWX_FORCE | Shutdown.EWX_LOGOFF);
}
}
}
//这是网上搜来的利用P/Invoke 调用窗口API的关机、重启、注销程序
class Shutdown
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct TokPriv1Luid
{
public int Count;
public long Luid;
public int Attr;
}
[DllImport("kernel32.dll", ExactSpelling = true)]
internal static extern IntPtr GetCurrentProcess();
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok);
[DllImport("advapi32.dll", SetLastError = true)]
internal static extern bool LookupPrivilegeValue(string host, string name, ref long pluid);
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall,
ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);
[DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
internal static extern bool ExitWindowsEx(int flg, int rea);
internal const int SE_PRIVILEGE_ENABLED = 0x00000002;
internal const int TOKEN_QUERY = 0x00000008;
internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
internal const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege";
internal const int EWX_LOGOFF = 0x00000000;
internal const int EWX_SHUTDOWN = 0x00000001;
internal const int EWX_REBOOT = 0x00000002;
internal const int EWX_FORCE = 0x00000004;
internal const int EWX_POWEROFF = 0x00000008;
internal const int EWX_FORCEIFHUNG = 0x00000010;
public static void DoExitWin(int flg)
{
bool ok;
TokPriv1Luid tp;
IntPtr hproc = GetCurrentProcess();
IntPtr htok = IntPtr.Zero;
ok = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
tp.Count = 1;
tp.Luid = 0;
tp.Attr = SE_PRIVILEGE_ENABLED;
ok = LookupPrivilegeValue(null, SE_SHUTDOWN_NAME, ref tp.Luid);
ok = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
ok = ExitWindowsEx(flg, 0);
}
}
}