1. 程式人生 > >Python黑科技:在家遠程遙控公司電腦,python+微信一鍵連接!

Python黑科技:在家遠程遙控公司電腦,python+微信一鍵連接!

ket gis 遠程喚醒 必須 icm size lan %d http

有時候需要遠程家裏的臺式機使用,因為我平時都是用 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[‘ToTserName‘] != ‘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(parmiko.AutoAddPolicy())
    ssh.connect(hostname=hostname,uername=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(‘\n‘)
    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 -1 192.168.1.0 14:dd:a9:ea"0b:96‘)
        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 1c | grep 64 | cut -d "" -f 1|head -n 1‘)
        sshConStatus = stdout.read()
        sshConStatus = sshConStatus.strip(‘\n‘)
        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‘)
paramko.util.log_to_file(‘ssh_key-login.log‘)
privatekey = os.path.expanduser(key_file)
try:
key = paramiko.RSAKey.from_privat_key_file(privatekey)
except paramiko.PasswordRepuiredExceptin:
key = paramiko.RSAKey.from_privat_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(‘\n‘)
        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‘)
        ssh.close()

itchat.auto_login(hotReload=True,enobleCmdQR=2)
itchat.run()
技術分享圖片

客戶端代碼,寫完扔計劃任務,開機啟動:

import requests
import os
import time
while 1:
time.sleep(30)
r = requests.head("heep://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 就可以了。

最後,如果你跟我一樣都喜歡python,也在學習python的道路上奔跑,歡迎你加入python學習群:839383765 群內每天都會分享最新業內資料,分享python免費課程,共同交流學習,讓學習變(編)成(程)一種習慣!

Python黑科技:在家遠程遙控公司電腦,python+微信一鍵連接!