本代码用于远程重启水星无线路由一体机MD898N,硬件版本v2,固件版本0.8.0 1.0 v1003.0 Build 140216。

由于需要,需要用C#实现对这台机器的定时重启,根据chrome开发者工具的抓包结果,发现新版的固件不支持直接的base认证,但是原理一样,只是把用base64加密过的密码存在cookies中了(今年开始更新后的固件都是这种登录方式),发送http请求时候带上这个cookies即可通过认证!

具体代码如下:

	string passwd = "12345678";   // 路由器登录密码
	string routeIP = "192.168.1.1";  // 路由器IP
	byte[] bytes = Encoding.Default.GetBytes(passwd);
	string base64str = Convert.ToBase64String(bytes);
 
	string url = "http://" + ip + "/cgi?7";
	HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
	req.Referer = "http://" + ip + "/";
	req.Method = "POST";
	req.CookieContainer = new CookieContainer();
	req.CookieContainer.Add(new Uri(url), new Cookie("Authorization", "Basic " + base64str));
	req.ContentType = "text/plain";
	string payload = "[ACT_REBOOT#0,0,0,0,0,0#0,0,0,0,0,0]0,0\r\n";  // 抓包后发现在请求中携带这个字符串即可让路由器重启
	byte[] pl = Encoding.UTF8.GetBytes(payload);
	req.ContentLength = pl.Length;
	Stream s = req.GetRequestStream();
	s.Write(pl, 0, pl.Length);
	s.Close();
	req.GetResponse();

在C# WebBrowser控件插入JS代码,并执行!亲测可用!

	HtmlElement script = webBrowser.Document.CreateElement("script");
	script.SetAttribute("type", "text/javascript");
	script.SetAttribute("text", "function _func(){alert('OK')}");
	HtmlElement head = webBrowser.Document.Body.AppendChild(script);
	webBrowser.Document.InvokeScript("_func");

附赠一段javascript清除当前站点cookies的代码:

function _cleancookies() {
	var keys = document.cookie.match(/[^ =;]+(?=\=)/g);
	if (keys) {
		for (var i = keys.length; i--;) document.cookie = keys[i] + '=0;expires=' + new Date(0).toUTCString()
	}
}

昨天写了《C# 实现假关机》,发现其中的办法对Win7不适应,还是会被强制关掉。今天想到另一种方法,在鼠标即将点击开始菜单关机按钮的时候,把鼠标的消息拦截下来,然后我们的程序收到这个消息,处理一下,比如关闭显示器,然后把消息丢弃掉,这样关机按钮的消息就收不到,自然就不会关机了。这样的好处是,系统收不到关机消息,自然没有强制关闭那个窗口了。

这里要用到钩子HOOK,需要用Form,完整代码如下:

using System;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;
 
namespace HookShutdown
{
    public partial class FormMain : Form
    {
        internal enum HookType
        {
            MsgFilter = -1,
            JournalRecord = 0,
            JournalPlayback = 1,
            Keyboard = 2,
            GetMessage = 3,
            CallWndProc = 4,
            CBT = 5,
            SysMsgFilter = 6,
            Mouse = 7,
            Hardware = 8,
            Debug = 9,
            Shell = 10,
            ForegroundIdle = 11,
            CallWndProcRet = 12,
            KeyboardLL = 13,
            MouseLL = 14
        }
        internal delegate IntPtr HookProc(int code, int wparam, IntPtr lparam);
        public struct POINT
        {
            public int x;
            public int y;
        }
 
        public struct MSLLHOOKSTRUCT
        {
            public POINT pt;
            public uint mouseData;
            public uint flags;
            public uint time;
            public int dwExtraInfo;
        }
 
        private IntPtr m_NextHookPtr = IntPtr.Zero;
        private IntPtr m_Handle = IntPtr.Zero;
        private IntPtr _handle = IntPtr.Zero;
        private uint trayWndThreadId = 0;
 
        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr GetModuleHandle(string lpModuleName);
        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
        [DllImport("User32.dll")]
        static extern void UnhookWindowsHookEx(IntPtr handle);
        [DllImport("User32.dll", SetLastError = true)]
        static extern IntPtr SetWindowsHookEx(HookType hookType, HookProc lpfn, IntPtr hMod, uint dwThreadId);
        [DllImport("User32.dll")]
        static extern IntPtr CallNextHookEx(IntPtr handle, int code, int wparam, IntPtr lparam);
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
        [DllImport("user32.dll")]
        static extern IntPtr WindowFromPoint(POINT Point);
        [DllImport("user32.dll", SetLastError = true)]
        static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId);
        [DllImport("kernel32.dll")]
        static extern uint GetLastError();
 
        [DllImport("user32.dll")]
        static extern bool BlockInput(bool fBlockIt);
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
 
        const UInt32 WM_SYSCOMMAND = 0x0112;
        const UInt32 SC_MONITORPOWER = 0xF170;
 
        public FormMain()
        {
            InitializeComponent();
 
            IntPtr hWnd = FindWindow("Shell_TrayWnd", (string)null);
            if (hWnd != IntPtr.Zero)
            {
                uint procID = 0;
                trayWndThreadId = GetWindowThreadProcessId(hWnd, out procID);
                InstallHook();//安装钩子
            }
        }
 
        ~FormMain()
        {
            UnInstallHook();//卸载钩子
        }
 
        private void InstallHook()
        {
            HookProc hookProc = new HookProc(IdentyFormHookProc);
            this.m_NextHookPtr = SetWindowsHookEx(HookType.MouseLL, hookProc, GetModuleHandle(
                        Process.GetCurrentProcess().MainModule.ModuleName
                        ), 0);
            //if(m_NextHookPtr == IntPtr.Zero)
            //    MessageBox.Show(GetLastError().ToString());
        }
        private void UnInstallHook()
        {
            if (this.m_NextHookPtr != IntPtr.Zero)
            {
                UnhookWindowsHookEx(this.m_NextHookPtr);
            }
        }
 
        private IntPtr IdentyFormHookProc(int code, int wparam, IntPtr lparam)
        {
            switch (wparam)
            {
                case (int)MsgType.WM_LBUTTONDOWN:
                case (int)MsgType.WM_LBUTTONUP:
                    MSLLHOOKSTRUCT msll = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lparam, typeof(MSLLHOOKSTRUCT));
                    IntPtr hWnd = WindowFromPoint(msll.pt);
                    if (hWnd != IntPtr.Zero)
                    {
                        uint procID = 0;
                        if (trayWndThreadId == GetWindowThreadProcessId(hWnd, out procID)) // 如果窗口线程是开始菜单所在的窗口线程
                        {
                            StringBuilder wndText = new StringBuilder(256);
                            GetWindowText(hWnd, wndText, 256);
                            if (wndText.ToString() == "关机") // 如果鼠标点击的是关机按钮
                            {
                                BlockInput(true);
                                SendMessage(this.Handle, WM_SYSCOMMAND, (IntPtr)SC_MONITORPOWER, (IntPtr)2); // 关闭显示器
                                return (IntPtr)1;
                            }
                        }
                    }
                    break;
            }
            return CallNextHookEx(this.m_NextHookPtr, code, wparam, lparam);
        }
    }
}

注意:1.把开始菜单的电源按钮默认为 关机
2.要使得BlockInput这个函数有效,也就是在关闭显示器后中断鼠标键盘输入,程序要运行在管理员权限下
3.要恢复原有的关机,退出程序即可。

用HOOK实现Win7下假关机

使用本代码,你可以实现在点下Windows关机键后,屏幕关闭,鼠标键盘暂时不能唤醒屏幕,让人以为已经关闭了电脑!
时间所限,仅列出关键代码,你可以在此基础上添加上显示假的关机屏幕,以实现以假乱真效果!

导入Win32 API三个函数

        [DllImport("kernel32.dll")]
        static extern bool SetProcessShutdownParameters(uint dwLevel, uint dwFlags); // 设置进程相对于其它进程的关闭优先级
        [DllImport("user32.dll")]
        static extern bool BlockInput(bool fBlockIt); // 禁用键盘鼠标
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam); //用于发送关闭显示器消息
        const UInt32 WM_SYSCOMMAND = 0x0112;
        const UInt32 SC_MONITORPOWER = 0xF170;

下面是主要代码

        public FormMain()
        {
            InitializeComponent();
            Microsoft.Win32.SystemEvents.SessionEnding += SessionEndingEvent;
 
            SetProcessShutdownParameters(0x480, 0);
        }
 
        ~FormMain()
        {
            Microsoft.Win32.SystemEvents.SessionEnding -= SessionEndingEvent;
        }
 
        private void SessionEndingEvent(object sender, SessionEndingEventArgs e)
        {
            SessionEndReasons endReasons = e.Reason;
            BlockInput(true);
            SendMessage(this.Handle, WM_SYSCOMMAND, (IntPtr)SC_MONITORPOWER, (IntPtr)2);
            e.Cancel = true;
        }

注意:Microsoft.Win32.SystemEvents.SessionEnding事件需要在Form窗体下才有效,不然这么简单的程序我还是习惯写成控制台的。程序在接收到系统关机信息后,先用BlockInput切断键盘鼠标输入,然后关闭显示器。SetProcessShutdownParameters的目的是保证次程序最先收到关机消息。

如何恢复输入?MSDN说 Presse CTRL+ALT+DEL!

Win7 下是阻止不了关机的!Win7下可以参考这个 《用hook实现win7下假关机》

转载注明:http://www.shenyaocn.com/c-实现假关机/

感觉路由器在睡觉的时候就不用开着无线了,关了还可以减少辐射(不能全关了,因为还有电脑需要有线)。苦于家里用的是水星MW300r,而且硬件以及缩水到v9.1版了,SoC还是QCA开头的,改完内存和Flash依然没有Openwrt刷,这样自然不能设定定时关闭无线了。又不想再买台可以刷的路由器,就想到如题所说的方法,刚好家里有台电脑是24小时开着(功耗很低),又是用网线连着路由器,就想着能不能在里面设定一个计划任务来定时开关MW300r的无线。

用C#编写如下程序,代码:

private static string rounterIP = System.Configuration.ConfigurationManager.AppSettings["RounterIP"];
private static string rounterUser = System.Configuration.ConfigurationManager.AppSettings["RounterUser"];
private static string rounterPasswd = System.Configuration.ConfigurationManager.AppSettings["RounterPasswd"];
 
static void Main(string[] args)
{
	try
	{
		bool wlanON = true;
		foreach (string arg in args)
		{
			if(arg.Equals("-s", StringComparison.CurrentCultureIgnoreCase))
				wlanON = false;
		}
 
		byte[] bytes = Encoding.Default.GetBytes(rounterUser + ":" + rounterPasswd);
		string base64str = Convert.ToBase64String(bytes);
 
		string url = "http://" + rounterIP + "/userRpm/WlanNetworkRpm.htm?broadcast=2&brlssid=&brlbssid=&detctwds=1&keytype=1&wepindex=1&keytext=&Save=%B1%A3+%B4%E6";
		if (wlanON)
			url += "&ap=1";
 
		HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
		req.Referer = "http://" + rounterIP + "/userRpm/WlanNetworkRpm.htm";
		req.Headers.Add(HttpRequestHeader.Authorization, "Basic " + base64str);
		req.Method = "GET";
		req.GetResponse();
		Console.WriteLine("WiFi已" + (wlanON ? "打开" : "关闭"));
	}
	catch (Exception e)
	{
		Console.Write(e.Message);
	}
	Thread.Sleep(5000);
}

注意前面三行依次是路由器IP,用户名和登录密码,可根据实际修改!编成命令行程序,后面加个-s参数是关闭无线的,不加那个参数就是打开无线,然后配置一下计划任务就OK了!

此程序在硬件版本9.1固件版本1.0.8 Build 130719下测试通过!其它固件版本可能需要重启路由器后才能生效!

转载注明:http://www.shenyaocn.com/?p=132