文字描述比較少建钥,有遇到問題可以V本人。
公司wifi需要登錄認(rèn)證網(wǎng)頁(yè)虐沥,手動(dòng)輸入賬號(hào)和密碼熊经,驗(yàn)證完成后,才能開始上網(wǎng)欲险。如果電腦合蓋镐依,或者睡眠。再次打開需要重新在打開網(wǎng)頁(yè)天试,輸入賬號(hào)密碼槐壳,連接。就和我們?cè)贙FC或者是機(jī)場(chǎng)秋秤、酒店宏粤,連接了wifi會(huì)彈出一個(gè)認(rèn)證的窗口。
首先想到的是把url的請(qǐng)求地址拿出來灼卢,通過curl的請(qǐng)求去完成認(rèn)證绍哎。
這個(gè)有一個(gè)問題是當(dāng)Captive Network Assistant
彈出的時(shí)候,網(wǎng)絡(luò)會(huì)被攔截鞋真,這個(gè)英語翻譯成中文的意思強(qiáng)制網(wǎng)絡(luò)助理
崇堰。只要有這個(gè)彈窗在,網(wǎng)絡(luò)都會(huì)被終止(沒有實(shí)際性的原理,親測(cè)是網(wǎng)絡(luò)被攔截)最早是使用sleepwatcher來執(zhí)行海诲,當(dāng)mac喚醒的時(shí)候繁莹,執(zhí)行腳本。
有個(gè)問題就是當(dāng)切換網(wǎng)絡(luò)的時(shí)候特幔,就沒辦法執(zhí)行腳本了咨演。只能在喚起的時(shí)候使用
解決方案
使用hammerspoon+lua+applescript來解決
思路
- 監(jiān)聽網(wǎng)絡(luò)切換和電腦的喚醒、解鎖
- 監(jiān)聽到事件蚯斯,查找是否有目標(biāo)wifi在薄风,如果有,強(qiáng)制連接目標(biāo)wifi
- 監(jiān)聽
Captive Network Assistant
的彈窗拍嵌,如果彈窗存在遭赂,執(zhí)行applescript的腳本,自動(dòng)輸入賬號(hào)密碼
安裝hammerspoon
- 使用brew安裝
沒有安裝過brew的話可以先執(zhí)行
/usr/bin/ruby -e "$(curl -fsSL https://cdn.jsdelivr.net/gh/ineo6/homebrew-install/install)"
然后安裝
brew install hammerspoon --cask
- 下載app横辆,自行百度或者官網(wǎng)下載撇他。這邊就不做更多的說明
- 安裝完成后,頂部會(huì)有一個(gè)錘子的圖標(biāo)狈蚤,點(diǎn)擊紅框部分給到權(quán)限困肩。可以開機(jī)的時(shí)候就啟動(dòng)hammerspoon
-
小技巧炫惩,可以把圖標(biāo)也隱藏僻弹。通過command + 空格,喚起搜索他嚷,搜索ha開頭蹋绽,可以再打開設(shè)置界面。
image.png
image.png -
在~目錄下可以看到有這個(gè)文件筋蓖。hammerspoon會(huì)先執(zhí)行init.lua
image.png
開發(fā)環(huán)境
init.lua 判斷了如果是自己的mac卸耘,才會(huì)執(zhí)行自動(dòng)更新腳本。這樣只要有修改粘咖,hammerspoon的控制臺(tái)就會(huì)有l(wèi)og蚣抗,方便做調(diào)試
require "wifi.wifi"
if (hs.host.localizedName() == 'Radish') then
local pathwatcher = require "hs.pathwatcher"
local alert = require "hs.alert"
-- 開啟自動(dòng)重載配置文件
function autoReload()
function reloadConfig(files)
doReload = false
for _, file in pairs(files) do
if file:sub(-4) == ".lua" then
doReload = true
end
end
if doReload then
hs.reload()
end
end
pathwatcher.new(os.getenv("HOME") .. "/.hammerspoon", reloadConfig):start()
end
autoReload()
end
wifi
wifi的腳本思路和上面所述的一樣。主要監(jiān)聽了
監(jiān)聽電腦休眠和喚醒
和wifi發(fā)生改變
和創(chuàng)建應(yīng)用程序監(jiān)控器
瓮下。喚醒的時(shí)候翰铡,去掃描后臺(tái)有沒有目標(biāo)WIFINAME
,有的話讽坏,就連接目標(biāo)wifi锭魔,執(zhí)行applescript腳本
local WIFINAME = "Dianei";
-- local USERNAME = "1111"
-- local PASSWORD = "2222"
-- 異步執(zhí)行shell
function asyncSheel(cmd, callback)
hs.task.new("/bin/sh", function(exitCode, stdOut, stdErr)
if exitCode ~= 0 then
print("Error executing command: " .. stdErr)
callback()
else
print("Command output: " .. stdOut)
callback(stdOut)
end
end, {"-c", cmd}):start()
end
-- 執(zhí)行shell腳本
function shell(cmd)
local success,obj,descriptor = hs.osascript.applescript(string.format('do shell script "%s"', cmd))
return success,obj,descriptor
end
-- 判斷網(wǎng)絡(luò)是否連接
function isNet()
local success,obj,descriptor = shell("ping -o -t 1 baidu.com")
if (success and obj ~= nil and string.find(descriptor, '1 packets received')~= nil) then
return true
else
return false
end
end
function wifiCallback(watcher, message, interface)
local ssid = hs.wifi.currentNetwork(interface)
if (ssid ~= nil and ssid == WIFINAME) then
print("當(dāng)前wifi列表中存在"..ssid)
-- scan()
end
end
function caffeinateCallback(event)
if event == hs.caffeinate.watcher.screensDidSleep then
-- 屏幕休眠(屏保開啟)
print("screensDidSleep")
elseif event == hs.caffeinate.watcher.screensDidWake then
-- 屏幕喚醒
print("screensDidWake")
elseif event == hs.caffeinate.watcher.screensDidLock then
print("screensDidLock")
elseif event == hs.caffeinate.watcher.screensDidUnlock then
-- 屏幕解鎖
print("screensDidUnlock")
-- 強(qiáng)制開啟wifi的按鈕
asyncSheel("networksetup -setairportpower en0 on", function()
print('強(qiáng)制開啟了wifi按鈕')
-- 后臺(tái)掃描WiFi熱點(diǎn)
hs.wifi.backgroundScan(function(networks)
-- 處理掃描結(jié)果
print("wifi 掃描完成")
for i, network in ipairs(networks) do
if (network.ssid == WIFINAME or network.bssid == WIFINAME) then
print("找到 wifi名字了")
-- 連接wifi 等待cna的彈窗
hs.wifi.associate(WIFINAME, "")
break
end
end
end)
end)
elseif event == hs.caffeinate.watcher.systemWillSleep then
print("systemWillSleep")
elseif event == hs.caffeinate.watcher.systemDidWake then
print("systemDidWake")
elseif event == hs.caffeinate.watcher.systemWillPowerOff then
print("systemWillPowerOff")
elseif event == hs.caffeinate.watcher.systemDidPowerOn then
print("systemDidPowerOn")
end
end
-- 應(yīng)用程序激活事件處理
function applicationCallback(name, event, app)
-- and event == hs.application.watcher.launched
if name == "Captive Network Assistant" or name == "強(qiáng)制網(wǎng)絡(luò)助理" then
-- 啟動(dòng)
-- print(hs.application.watcher.launched)
-- -- 激活
-- print(hs.application.watcher.activated)
-- 在 Captive Network Assistant 打開時(shí)自動(dòng)輸入賬號(hào)密碼
if event == hs.application.watcher.activated then
print("激活cna了 ~ ")
asyncSheel("osascript ~/.hammerspoon/wifi/cna.applescript", function(e)
print("執(zhí)行完畢")
local haveNet = isNet()
if (haveNet == true) then
hs.alert.show(WIFINAME.."網(wǎng)絡(luò)已連接")
end
end)
end
end
end
-- 監(jiān)聽電腦休眠和喚醒
hs.caffeinate.watcher.new(caffeinateCallback):start()
-- wifi發(fā)生改變
hs.wifi.watcher.new(wifiCallback):start()
-- 創(chuàng)建應(yīng)用程序監(jiān)控器
hs.application.watcher.new(applicationCallback):start()
function getDianneiWifi()
return hs.window.filter.new(false):setAppFilter("Captive Network Assistant", { currentSpace = true, allowTitles = "加入“Dianei”" }):getWindows()
end
-- hs.application:getWindow(title)
-- function launchOrNextWindow(name, showName)
-- local findName = showName or name
-- local appName = hs.application.frontmostApplication():name()
-- print("appName")
-- print(appName)
-- if findName ~= appName then
-- hs.application.launchOrFocus(name)
-- else
-- -- local wlist = getWinList(findName)
-- -- local wcount = #wlist
-- -- if wcount > 1 then
-- -- hs.eventtap.keyStroke({'cmd'}, '`')
-- -- else
-- -- local win = wlist[1]
-- -- if win:isMinimized() then win:unminimize() else win:minimize() end
-- -- end
-- end
-- end
-- function mapLaunch(key, name, showName)
-- hs.hotkey.bind({}, key, function()
-- launchOrNextWindow(name, showName)
-- end)
-- end
-- mapLaunch('f1', 'Google Chrome')
-- launchOrNextWindow('iTerm', 'iTerm2')
applescript
需要注意的是,vscode中默認(rèn)是UTF-8的編碼路呜,applescript要設(shè)置為GB2312迷捧。不然有中文的會(huì)識(shí)別不了
global WIFINAME
global USERNAME
global USERPASSWORD
global ROOPNUM
global DELAYTIME
global NOTWIFI
set WIFINAME to "xxxx"
set USERNAME to "xxx"
set USERPASSWORD to "xxxx"
set ROOPNUM to 5
set DELAYTIME to 0.5
set roopCount to 0
repeat while roopCount < ROOPNUM
if isNet() = true then
log "net connct success"
my closeDianei()
exit repeat
else
if my getCNAAlert() = 1 then
log "find cna"
-- begin connect
my connectWIFI()
end if
set roopCount to roopCount + 1
end if
end repeat
on closeDianei()
tell application "System Events"
-- 是否存在 CNA 彈窗
if exists (process "Captive Network Assistant") then
-- 進(jìn)入CNA的進(jìn)程
tell process "Captive Network Assistant"
-- 是否存在dianei的wifi連接彈窗
if exists (window "加入“Dianei”") then
-- 進(jìn)入dianeiwif連接的彈窗
tell window "加入“Dianei”"
-- 進(jìn)入U(xiǎn)I界面
if exists (button "完成") then
click button "完成"
end if
if exists (button "取消") then
click button "取消"
end if
end tell
end if
end tell
end if
end tell
end closeDianei
on getCNAAlert()
-- 系統(tǒng)事件
tell application "System Events"
if exists (process "Captive Network Assistant") then
return 1
else
return 2
end if
end tell
end getCNAAlert
on connectWIFI()
-- 系統(tǒng)事件
tell application "System Events"
-- 是否存在 CNA 彈窗
if exists (process "Captive Network Assistant") then
-- 進(jìn)入CNA的進(jìn)程
tell process "Captive Network Assistant"
-- 是否存在dianei的wifi連接彈窗
if exists (window "加入“Dianei”") then
-- 進(jìn)入dianeiwif連接的彈窗
tell window "加入“Dianei”"
-- 進(jìn)入U(xiǎn)I層級(jí) 從這個(gè)命令去找 entire contents 找到對(duì)應(yīng)想要的名稱织咧。比如用戶名 密碼 注銷等等
if exists (UI element 1 of scroll area 1 of group 1 of group 2) then
-- UI層架
tell UI element 1 of scroll area 1 of group 1 of group 2
set groupTag to 0
repeat while groupTag < 50
try
if my isNet() = true then
exit repeat
else
if exists (text field 1 of group 1 of group groupTag) then
log "開始自動(dòng)輸入用戶名和密碼"
-- 用戶名
tell group 1 of group groupTag
set value of attribute "AXFocused" of text field 1 to true
set value of text field 1 to USERNAME
end tell
-- 密碼
tell group 2 of group groupTag
set value of attribute "AXFocused" of text field 1 to true
set value of text field 1 to USERPASSWORD
end tell
-- 勾選框
tell group (groupTag + 1)
click checkbox 1
end tell
-- 登錄按鈕
tell group (groupTag + 2)
click button "登錄"
end tell
exit repeat
else
set groupTag to groupTag + 1
end if
end if
end try
end repeat
end tell
end if
end tell
end if
end tell
end if
end tell
end connectWIFI
on isNet()
try
set pingResult to do shell script "ping -o -t 1 baidu.com"
if pingResult contains "1 packets received" then
return true
else
return false
end if
on error
return false
end try
end isNet