在家想远程公司电脑?Python +微信一键连接
作者 | 阿文
转载自 CSDN(ID:CSDNnews)
有时候需要远程家里的台式机使用,因为我平时都是用 MAC 多,但是远程唤醒只能针对局域网,比较麻烦,于是我想用微信实现远程唤醒机器。
准备工作
本程序主要是实现远程管理 Windows10操作系统的开机和关机:
在 Windows机器的相同内网中放一个 Linux 主机,我这里用树莓派代替,如果你是用 OpenWrt 之类的路由器也可以。
Linux 主机需要能够远程访问,我这里是有 FRP 将树莓派的端口映射到我的公网 Linux 主机上。所以可以随时远程 SSH 过去。
Windows 机器的网卡必须是有线连接,支持网络唤醒功能。
开机实现思路
首先通过微信发送开机指令,这里我使用的是 itchat 程序会调用 Paramiko 库去 SSH 远程到内网的树莓派执行 WakeOnLan 命令去唤醒 Windows 主机。
pi@raspberrypi:~ $ wakeonlan -i 192.168.1.0 14:dd:a9:ea:0b:96
Sending magic packet to 192.168.1.0:9 with 14:dd:a9:ea:0b:96
程序会通过 ICMP 协议, ping 下需要唤醒的目标主机然后进行过滤,一个正常的 ICMP 包是64字节,过滤打印出这个64。
例如 ping 百度:
➜ ~ ping www.baidu.com
PING www.a.shifen.com (180.97.33.108): 56 data bytes
64 bytes from 180.97.33.108: icmp_seq=0 ttl=53 time=8.865 ms
64 bytes from 180.97.33.108: icmp_seq=1 ttl=53 time=9.206 ms
64 bytes from 180.97.33.108: icmp_seq=2 ttl=53 time=8.246 ms
用一段 Linux 命令去过滤是否有64,这里为啥要用 head -n 1 呢?
因为有可能会出现2行,经过测试,我们只需要取64这个值就可以了:
ping 192.168.1.182 -c 1 | grep 64 | cut -d " " -f 1|head -n 1
如果有则表示开机成功已经联网了,返回开机成功,否则程序继续往下走,去唤醒,然后在 ping 一次确认是否开机,如果为是则返回开机成功,否则返回失败。程序执行成功后,在我的网站根目录创建一个 shutdown 文件,用于后面的关机操作:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import itchat
import paramiko
import os
import time
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
hostname = ''
username = ''
port =
key_file = '/home/fangwenjun/.ssh/id_rsa'
filename = '/home/fangwenjun/.ssh/known_hosts'
@itchat.msg_register(itchat.content.TEXT)
def text_reply(msg):
if msg['ToUserName'] != 'filehelper': return
if msg['Text'] == u'开机':
paramiko.util.log_to_file('ssh_key-login.log')
privatekey = os.path.expanduser(key_file)
try:
key = paramiko.RSAKey.from_private_key_file(privatekey)
except paramiko.PasswordRequiredException:
key = paramiko.RSAKey.from_private_key_file(privatekey,key_file_pwd)
ssh = paramiko.SSHClient()
ssh.load_system_host_keys(filename=filename)
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname=hostname,username=username,pkey=key,port=port)
#执行唤醒命令
stdin,stdout,stderr=ssh.exec_command('ping 192.168.1.182 -c 1 | grep 64 | cut -d " " -f 1|head -n 1')
sshCheckOpen = stdout.read()
sshCheckOpen =sshCheckOpen.strip(' ')
print type(sshCheckOpen)
print sshCheckOpen
#进行判断,如果为64,则说明 ping 成功,说明设备已经在开机状态,程序结束,否则执行唤醒
if sshCheckOpen == '64':
connect_ok_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
itchat.send(connect_ok_time+u'设备已经开机', toUserName='filehelper')
else:
ssh_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
itchat.send(ssh_time+u'开始连接远程主机', toUserName='filehelper')
stdin,stdout,stderr=ssh.exec_command('wakeonlan -i 192.168.1.0 14:dd:a9:ea:0b:96')
wakeonlan_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
itchat.send(wakeonlan_time+u'执行唤醒,等待设备开机联网', toUserName='filehelper')
#由于开机需要一些时间去启动网络,所以这里等等60s
time.sleep(60)
#执行 ping 命令,-c 1 表示只 ping 一下,然后过滤有没有64,如果有则获取64传给sshConStatus
stdin,stdout,stderr=ssh.exec_command('ping 192.168.1.182 -c 1 | grep 64 | cut -d " " -f 1|head -n 1')
sshConStatus = stdout.read()
sshConStatus =sshConStatus.strip(' ')
print type(sshConStatus)
print sshConStatus
#进行判断,如果为64,则说明 ping 成功,设备已经联网,可以进行远程连接了,否则发送失败消息
if sshConStatus == '64':
connect_ok_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
itchat.send(connect_ok_time+u'设备唤醒成功,您可以远程连接了', toUserName='filehelper')
else:
connect_err_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
itchat.send(connect_err_time+u'设备唤醒失败,请检查设备是否连接电源', toUserName='filehelper')
ssh.close()
#在网站根目录创建一个空文件,命名为 shutdown
os.system('touch /www/shutdown')
print '执行开机消息成功'
关机部分实现
当接收关机指令时,程序会去删除网站根目录的 shutdown 文件,客户端我写了几行代码,去通过 Requests 库每隔30s 发送 HTTP head 请求去判断文件是否是404,如果是404 这说明文件不存在,调用系统关机操作,执行关机。
然后 SSH 到树莓派去 ping 目标主机,如果返回为空,则说明关机成功,否则关机失败。这只是针对 Windows 的关机,如果目标主机是 Linux 则简单多了:
if msg['Text'] == u'关机':
#删除网站根目录的shutdown 文件
rmfile = os.system('rm -rf /www/shutdown')
if rmfile == 0:
print '执行关机消息成功'
shutdown_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
itchat.send(shutdown_time+u'正在关机....', toUserName='filehelper')
paramiko.util.log_to_file('ssh_key-login.log')
privatekey = os.path.expanduser(key_file)
try:
key = paramiko.RSAKey.from_private_key_file(privatekey)
except paramiko.PasswordRequiredException:
key = paramiko.RSAKey.from_private_key_file(privatekey,key_file_pwd)
ssh = paramiko.SSHClient()
ssh.load_system_host_keys(filename=filename)
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname=hostname,username=username,pkey=key,port=port)
itchat.send(shutdown_time+u'正在确认设备是否完成关机操作,大约需要等待60s.', toUserName='filehelper')
#等等60秒后确认,因为关机需要一段时间,如果设置太短,可能网络还没断开
time.sleep(60)
stdin,stdout,stderr=ssh.exec_command('ping 192.168.1.182 -c 1 | grep 64 | cut -d " " -f 1|head -n 1')
sshConStatus = stdout.read()
sshConStatus =sshConStatus.strip(' ')
print type(sshConStatus)
print sshConStatus
#如果获取的值为空,则说明已经关机,否则关机失败
if sshConStatus != '64':
shutdown_success_err_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
itchat.send(shutdown_success_err_time+u'关机成功', toUserName='filehelper')
else:
shutdown_err_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
itchat.send(shutdown_err_time+u'关机失败,请连接桌面检查客户端程序是否正常执行', toUserName='filehelper')
ssh.close()
itchat.auto_login(hotReload=True,enableCmdQR=2)
itchat.run()
客户端代码,写完扔计划任务,开机启动:
import requests
import os
import time
while 1:
time.sleep(30)
r = requests.head("https://awen.me/shutdown")
print r.status_code
if r.status_code == 404:
os.system("shutdown -s -t 5")
使用 TeamViewer 连接:
缺点
网页端微信必须一直登录,不方便,这个就需要微信不能断网了。
WakeOnLan 是广播 MAC 地址的,貌似不能返回是否成功没,所以还是要 ping 主机看看通不通,判断下。
需要一个树莓派做跳板机,否则也不能唤醒内网设备。
如果只允许自己控制最好是使用文件助手来发送消息,因为默认情况下,任何人都可以给你发送指令开机。
Windows需要安装TeamViewer并且设置为开机自动启动以及绑定账号设置无人值守模式。这样方便远程,如果是Linux 则不需要开启 ssh 就可以了。
代码地址:https://github.com/monkey-wenjun/wchatwakeonlan
文章内的代码如果有 Bug,后续更新都在 GitHub 上,完整代码请参考 GitHub ,此文章代码不再更新。
原文:https://awen.me/post/3709919605.html
(本文为AI科技大本营转载文章,转载请微信联系原作者)
群招募
扫码添加小助手微信,回复:公司+研究方向(学校+研究方向),邀你加入技术交流群。技术群审核较严,敬请谅解。
推荐阅读:
优秀开发者必备技能包:Python调试器
十大经典排序算法动画与解析,看我就够了
访问量最高超7百万的Stack Overflow问题竟然是...
新鲜开源:基于TF2.0的深度强化学习平台
交易机器人春天已来?先看完这篇再说吧
程序员求职新思路:互联网巨鳄瓜分 ToB 资源全公开
移动开发还有未来吗?
全面剖析企业私有云
月入5万,程序员夫人们过上"贵妇"生活了吗?
点击“阅读原文”,查看历史精彩文章。
相关文章:

Python 语法相关知识
系统相关的信息模块: import syssys.argv 是一个 list,包含所有的命令行参数. sys.stdout sys.stdin sys.stderr 分别表示标准输入输出,错误输出的文件对象. sys.stdin.readline() 从标准输入读一行 sys.stdout.write("a") 屏幕输出a sys.exit(exit_code) 退出程序 s…

【Qt】 error: LNK1107: 文件无效或损坏: 无法在 0x310 处读取
编译Qt程序使用动态库时,报错 error: LNK1107: 文件无效或损坏: 无法在 0x310 处读取 原因 链接时,使用的dll,而不是lib。 lib是编译时需要的,dll是运行时需要的。 windows下动态库和静态库 动态库:生成动态库时…

Red5安装与入门 与FMS配置
转自:http://www.rosoo.net/a/Media/Streaming/201010/10343.html red5安装时出现问题解决:http://www.cnblogs.com/phinecos/archive/2007/11/26/973109.htmlred5安装设置: 首先需要安装Red5运行所需的java研发环境jdk,我所有的文件都保存到…

面试必备|带你彻底搞懂Python生成器
2019年人工智能系统学: https://edu.csdn.net/topic/ai30?utm_sourceai100_bw 作者 | Rocky0429 转载自 Python空间(ID:Devtogether) 写在之前 Python 的高级语言特性一直是我们学习 Python 的一个难点,大部分人并没有做到熟练的…

Kubecon 2017大会Google高级产品经理David Aronchick访谈:机器学习和Kubernetes
\看新闻很累?看技术新闻更累?试试下载InfoQ手机客户端,每天上下班路上听新闻,有趣还有料!\\\在德克萨斯州奥斯汀市举办的Kubecon大会已于近日闭幕,会议吸引了超过4000名工程师,Kubernetes成为了…

【Qt】Qt程序查看动态链接库(windows)
windows下使用dumpbin查看Qt程序运行时需要链接的动态库 打开终端 打开Qt自带的MSVC终端 如:Qt 5.10.0 64-bit forDesktop(MSVC 2017) 查看dumpbin命令 dumpbin微软官网说明 https://docs.microsoft.com/zh-cn/cpp/build/reference/dumpbin-options 直接输入命令dumpbin…

MSN 无法登录 错误代码 8007007e
故障原因: 发生这个错误的原因是一些朋友在网上下载了独立MSN提取包版本进行安装的,因为这个提取包只包含了Windows Live Messenger 2009,却缺少Windows Live Communications Platform,所以造成无法登录的问题。 解决办法…

你不知道的Vue响应式原理
文章首发于github Blog。 本文根据Vue源码v2.x进行分析。这里只梳理最源码中最主要的部分,略过非核心的一些部分。响应式更新主要涉及到Watcher,Dep,Observer这几个主要类。 本文主要弄清楚以下几个容易搞混的问题: Watcher&#…

优秀开发者必备技能包:Python调试器
作者 | Roky0429 来源 | Python空间(ID:Devtogether) 人工智能的现状及今后发展趋势如何? https://edu.csdn.net/topic/ai30?utm_sourcecsdn_bw 写在之前 不管是之前搞 acm 用 c/c 写算法还是后来用 Python 写代码,我发现在程…

【Qt】dumpbin详解
dumpbin简介 DUMPBIN是在Windows平台下用于显示COFF格式文件信息的一个命令行工具。你可以使用DUMPBIN去显示COFF格式的文件信息,比如像vc编译器生成的目标文件(obj),可执行文件(exe)和动态链接库…

感悟Windows7
Win7已经逐渐在中国电脑用户中普遍起来,绝大多数人对其新增的功能很升级的功能都很是好评,接下来就将简略总结一下我对此系统使用的一些感想。 l 界面更加体现以人为本的思想。更加赏心悦目并且选择更加多元化。比如桌面小工具就有了更多的选择并且还可…

【Qt】Qt5在ubuntu16.04无法输入中文解决方式
参考博客 https://blog.csdn.net/linux_2016/article/details/52356576 博客中没有修改库的执行权限 解决方法 安装:fcitx-frontend-qt5 sudo apt-get install fcitx-frontend-qt5 拷贝动态库到Qt安装目录下的两个目录中 cp /usr/lib/x86_64-linux-gnu/qt5/p…

拿下中科大的计算机课程全靠它了!
整理 | 琥珀 出品 | AI科技大本营(ID: rgznai100) 人工智能的现状及今后发展趋势如何? https://edu.csdn.net/topic/ai30?utm_sourcecsdn_bw 中国科学技术大学,简称“中科大”,是国内有名的 985、211 重点高校。近年…

【阿里Q3财报:阿里云去年营收破百亿,亚洲市场遥遥领先】
2月1号晚间,阿里巴巴公布2018财年第三季度财报,阿里云保持持续强劲的增长,季度营收同比增长104%到35.99亿元。2017年累计营收突破百亿,达112亿,这是国内首次出现百亿规模的云计算服务商,在亚洲市场遥遥领先…

“神仙”打架,“凡人”遭殃
神仙是啥?古时神话时代举手翻江倒海的人物啊,那神仙打架是啥后果,相信大家心里都有个底吧。那现代社会的“神仙”是啥?那就是有钱有权的大人物或者商家,那真是让咱仰望的对象啊~ 话说最近这360跟QQ的巅峰对决&am…

120种小狗图像傻傻分不清?用fastai训练一个分类器
作者:一杯奶茶的功夫 链接:https://www.jianshu.com/p/ab35ed21df87 程序员转行学什么语言? https://edu.csdn.net/topic/ai30?utm_sourcecsdn_bw 这篇文章会讲解如何制作能够分类120种小狗的图像分类器。 这篇文章中所讲述的内容都是基于…

View_01_LayoutInflater的原理、使用方法
View_01_LayoutInflater的原理、使用方法 本篇博客是郭神博客Android视图状态及重绘流程分析,带你一步步深入了解View(一)的读书笔记的笔记。 LayoutInflater简单介绍 setContentView()内部是使用LayoutInflater来完毕载入布局的。setContent…

【ubuntu】在ubuntu下无法输出拼音输入法中的中括号“【” 和 “】”的解决方法
问题 在新装的ubuntu16.04中,打不出中括号【】,而变成 “”和“「” 解决方法 修改文件/usr/share/fcitx/data/punc.mb.zh_CN sudo vi /usr/share/fcitx/data/punc.mb.zh_CN将18、19行改为如下内容 18 [ 【 19 ] 】

配置数据源和分页
1.tomcat的版本,最好不要是安装版的,要解压缩的,不然无法连接数据源。2.conf》context.xml<Resource name"hotel" auth"Container" type"javax.sql.DataSource" driverClassName"oracle.jdbc.…

售价1万7的华为Mate X很贵吗?
整理 | 琥珀 出品 | AI科技大本营(ID: rgznai100) 60s测试:你是否适合转型人工智能? https://edu.csdn.net/topic/ai30?utm_sourcecxrs_bw 继三星之后,网友们期待已久的华为终于忍不住宣布了一系列重磅消息ÿ…

【C】数组数组初始化总结
C数组初始化总结 发现一个新方法,可以分段初始化数组 eg:int arrayC[MAX_LEN] {[1 … 5]9, [6 … 9] 8}; 代码如下 #include <stdio.h> #define MAX_LEN 10int main (int argc, char *argv[]) { //不初始化,参数值随机分配 //[0][0…

Golang的反射reflect深入理解和示例
[TOC] Golang的反射reflect深入理解和示例 【记录于2018年2月】 编程语言中反射的概念 在计算机科学领域,反射是指一类应用,它们能够自描述和自控制。也就是说,这类应用通过采用某种机制来实现对自己行为的描述(self-representati…

如何读取多个文件,文件后缀名不一致,不过类似source.1 source.2 source.3等
#include <stdio.h> #include <stdlib.h> //为了使用exit() char *itoa(int num,char *str,int radix); int main() { int ch; FILE* fp; // char fname[50]"scan1.source.2100"; //用于存放文件名 char fname[20]"source."; …

AtCoder Petrozavodsk Contest 001
第一场apc,5H的持久战,我当然水几个题就睡了 A - Two Integers Time limit : 2sec / Memory limit : 256MB Score : 100 points Problem Statement You are given positive integers X and Y. If there exists a positive integer not greater than 1018…

【Qt】使用QCamera获取摄像头,并使用图像视图框架QGraphics*来显示
代码下载 https://download.csdn.net/download/u010168781/10373174 #####头文件 #ifndef CAMERATEST_H#define CAMERATEST_H#include <QMainWindow> #include <QGraphicsView> #include <QKeyEvent> #include <QTimer>namespace Ui { class Camera…

CVPR 2019收录论文ID公开,你上榜了吗?
整理 | 琥珀 出品 | AI科技大本营(ID: rgznai100) 计算机视觉和模式识别大会 CVPR(Conference on Computer Vision and Pattern Recognition)作为人工智能领域计算机视觉方向的重要学术会议,每年都会吸引全球最顶尖的…

什么是 prelink
2019独角兽企业重金招聘Python工程师标准>>> Most programs require libraries to function. Libraries can be integrated into a program once, by a linker, when it is compiled (static linking) or they can be integrated when the program is run by a load…

PythonR爬取分析赶集网北京二手房数据(附详细代码)
本文转载自数据森麟(ID:shujusenlin) 作者介绍:徐涛,19年应届毕业生,专注于珊瑚礁研究,喜欢用R各种清洗数据。 知乎:parkson 如何挑战百万年薪的人工智能! https://edu.csdn.net/t…

【Qt】QCloseEvent的使用小结
问题描述 在程序中使用QCloseEvent时,有时没有反应,没有关闭程序。 原因 经测试只有在界面起来以后,使用event->accept()才能关闭程序 测试如下 在构造函数中调用close() 在构造函数中调用close()时,会触发QCloseEvent事件,但是程序界面没有关闭。 使用按钮触发…

Java反射 - 私有字段和方法
尽管普遍认为通过Java Reflection可以访问其他类的私有字段和方法。 这并不困难。 这在单元测试中可以非常方便。 本文将告诉你如何。 访问私有字段 要访问私有字段,您需要调用Class.getDeclaredField(String name)或Class.getDeclaredFields…