04月23日
sleep/awakeを検出してUSBドライバを再認識させる方法(試せるソース付き)
先日記載したsleep復帰後にUSBマウスが認識しなくなる件、
shellで実行するのは、スマートじゃないなぁと思い、いろいろ方法を探っていました。
スリープから復帰したらコマンドを打ち込む必要がない状態で、もとに戻る!方法を
目指します。
shellで実行するのは、スマートじゃないなぁと思い、いろいろ方法を探っていました。
スリープから復帰したらコマンドを打ち込む必要がない状態で、もとに戻る!方法を
目指します。
sleep/awakeを検出し、処理をさせることができる2つのアプリがありました。
1. PowerManager http://dssw.co.uk/powermanager/standard/index.html
49.95USD・・・Too expensive!高いです><
2. sleepwatcher http://www.bernhard-baehr.de
こちらは無料みたいです。
デーモンとして常駐させるプログラムですね、ルート権限与えたくないなぁ・・・
PowerManagerのようなことができるのだとすると、実は簡単な方法でイベントを検出できるのでは?と思い、Apple DeveloperのIO Kit(IOKitFundamentals_j)に関する資料を読んでみました。
ふと、思いついたキーワードで検索したところ、いい情報がありました。
このブログにAppleScriptを使って、イベントを検出する方法が明記されていました。
さっそく、AppleScriptエディタで参考にしたスクリプトを編集し、復帰のイベントで
USBドライバのunload/loadを行うようにします。
-- main.scpt
-- Cocoa-AppleScript Applet
--
-- Copyright 2011 {Your Company}. All rights reserved.
-- This is the main script for a Cocoa-AppleScript Applet.
-- You can put the usual script applet handlers here.
set |center| to my NSWorkspace's sharedWorkspace()'s notificationCenter()
--|center|'s addObserver_selector_name_object_(me, "notify:", missing value, missing value) --すべて通知する
|center|'s addObserver_selector_name_object_(me, "NSWorkspaceWillSleep:", "NSWorkspaceWillSleepNotification", missing value)
|center|'s addObserver_selector_name_object_(me, "NSWorkspaceDidWake:", "NSWorkspaceDidWakeNotification", missing value)
on message(title, subtitle, msg)
set notification to my NSUserNotification's alloc()'s init()
set notification's title to title
set notification's subtitle to subtitle
set notification's |informativeText| to msg
my NSUserNotificationCenter's defaultUserNotificationCenter()'s deliverNotification_(notification)
end message
on notify_(notification)
message("", "", notification's |name|)
end notify_
on NSWorkspaceWillSleep_(notification)
message("スリープ", "", "")
end NSWorkspaceWillSleep_
on NSWorkspaceDidWake_(notification)
message("スリープ解除", "", "")
do shell script "cd /System/Library/Extensions ; sudo kextunload MicrosoftMouse.kext/Contents/PlugIns/MicrosoftMouseUSB.kext; sudo kextload MicrosoftMouse.kext/Contents/PlugIns/MicrosoftMouseUSB.kext" with administrator privileges
end NSWorkspaceDidWake_
スクリプトを実行(アプリケーション実行)して、macbook pro late2012をスリープ、復帰させてイベントを検出できていることを確認します。
通知センタに通知が届いています。
管理者実行(administrator privileges)指定しているので、ダイアログで管理者パスワードの入力が
表示されました。
パスワードを入力することで
sleep/awakeを検出してUSBドライバを再認識させることができました。
ハードウェアに関係するアプリの多くは、カーネル拡張機能を使って実現しているものが多いです。
kextunload、kextloadは、macのカーネル拡張機能のアンロード、ロードコマンドです。
今回は、awakeを検出して、ロード済みカーネル拡張機能を再ロードすることでUSBドライバを再認識させました。
sleep/awakeを検出してUSBドライバを再認識させる参考になれば幸いです。
コメントシステムを利用したくない方はお問い合わせからお願いします。
2013.8.19 DISQUS(外部コメントサービス)の利用を開始しました。
Facebook, google, Twitter等のアカウントで投稿可能です。