Chrome-eject が
この先生きのこるには
Who am I ?
はせがわようすけ
• http://utf-8.jp/
• 顔文字でJavaScript書いたり
• 顔文字で86バイナリ書いたり

@hasegawayosuke http://utf-8.jp/
Chrome-eject ?

@hasegawayosuke http://utf-8.jp/
Chrome-eject ?

@hasegawayosuke http://utf-8.jp/
Chrome-eject uses NPAPI
NPAPI plugin
• Netscape Plugin API
• DLL形式でブラウザの機能を拡張
• Flash Player, Silverlight, ...
• http://www.slideshare.net/TNaruto/npapi-26722229
NPAPI plugin in Chrome Extension
• JavaScriptだけで出来ないことを実現
• Chrome拡張の制約を超えて何でも可能
• でもDLL書かないと…
@hasegawayosuke http://utf-8.jp/
NPWIN32
• 何度もDLL書くのイヤだ
• 何でもできるNPAPI DLLを書いた
• JSから任意のWin32APIを呼び出せる
• PerlのWin32::APIみたいなもの

@hasegawayosuke http://utf-8.jp/
Chrome-eject uses NPAPI
// manifest.json
"plugins" : [ { "path" : "win32api.dll", "public" : false } ]
// background.html
<embed type="application/x-win32api-dynamic-call" id="p" hidden="true" />
var npwin32;
var mciSendString;
document.addEventListener( "DOMContentLoaded", function (){
chrome.browserAction.onClicked.addListener( function( tab ){
if( npwin32 === undefined ){
npwin32 = document.getElementById( "p" );
}
if( mciSendString === undefined ){
mciSendString = npwin32.import( "winmm.dll",
"DWORD mciSendStringW( LPCWSTR, DWORD, UINT, DWORD )"
);
}
if( mciSendString){
var r = mciSendString( "set cdaudio door open", 0, 0, 0 );
}
} );
} );

@hasegawayosuke http://utf-8.jp/
NPWIN32 - callback
// import DLL functions
var EnumWindows = npwin32.import(
"user32.dll", "BOOL EnumWindows( CALLBACK, DWORD )" );
var GetWindowText = npwin32.import(
"user32.dll", "INT GetWindowTextW( DWORD, LPWSTR, INT )" );
// create CALLBACK object
var func = npwin32.callback(
function ( hwnd, lparam ){
var buf = new Array( 257 ).join( " " ); // space * 256
if( GetWindowText( hwnd, buf, 256 ) ){
alert( hwnd + " : " + GetwindowText.arg( 1 ) );
}
},
"BOOL (DWORD, DWORD)"
);
EnumWindows( func, 0 );

@hasegawayosuke http://utf-8.jp/
“Goodbye to Our Friend NPAPI”

@hasegawayosuke http://utf-8.jp/
NPAPI
plugins

N
P
A
P
I
告
別
式
How do I eject without NPAPI?
Native Messaging API

@hasegawayosuke http://utf-8.jp/
How do I eject without NPAPI?
Native Messaging API
• http://developer.chrome.com/extensions
/messaging.html#native-messaging
• Chrome拡張と実行ファイル間でstdioを通じて
通信できる
• 事前にmanifestファイルをレジストリに登録
する必要がある
• しかもHKLM!

(☝ ՞

՞)☝気軽にejectできない!
@hasegawayosuke http://utf-8.jp/
おっ?
なんかAPI追加されてる!?
How do I eject without NPAPI?

キタ━━━━(゚∀゚)━━━━ !!!!!
@hasegawayosuke http://utf-8.jp/
chrome.system.storage
• ストレージデバイスの情報を取得
chrome.system.storage.getInfo(
function( devices ){
console.log( devices );
}
);
DVD-ROMデバイス

え? fixed?

@hasegawayosuke http://utf-8.jp/
chrome.system.storage
• とりあえずejectしてみる
chrome.system.storage.getInfo(
function( devices ){
devices.forEach( function( device ){
if( device.capacity == 0 ){
chrome.system.storage.ejectDevice(
device.id,
function ( result ){
console.log( result );
}
);
}
} );
}
result === "failure"
);
@hasegawayosuke http://utf-8.jp/
chrome.system.storage
• Chrome 30+ で使える(はず)
• CD-ROMドライブでも ”removable” ではなく
“fixed” が返ってくる
• ejectDevice 失敗する

(☝ ՞

՞)☝やっぱりejectできない!
@hasegawayosuke http://utf-8.jp/
なんとか eject したい!

拡張に実行ファイル入れておいて、
ダウンロードさせてそれを実行だ!
How do I eject ?
• 拡張のなかにejectするWSHファイル(*.vbs)を
含めておく
• chrome.downloads.download APIを使ってvbs
をローカルにダウンロードさせる
• chrome.downloads.open APIを使ってダウン
ロードしたvbsファイルを実行する
• うまくいけば eject 完了!

@hasegawayosuke http://utf-8.jp/
chrome.downloads

@hasegawayosuke http://utf-8.jp/
chrome.downloads
var url = chrome.extension.getURL( "eject.vbs" );
chrome.downloads.download( {
url : url,
filename : "./" +
url.replace( /^chrome-extension:///, "" ),
conflictAction : "overwrite"
}, function( id ){
if( id === undefined ) return;
setTimeout( function(){
chrome.downloads.open( id );
chrome.downloads.erase( { id : id } );
}, 2000 );
} );
いまいち動きがおかしい。donloadのcallbackが呼ばれてすぐだとファ
イルを開けないので2秒待ちを入れている

@hasegawayosuke http://utf-8.jp/
eject.vbs
Dim
Dim
Dim
Set
Set

wmp
drives
i
wmp = CreateObject( "WMPlayer.OCX" )
drives = wmp.cdromCollection

For i = 0 To drives.Count - 1
drives.Item( i ).Eject
Next

@hasegawayosuke http://utf-8.jp/
DEMO
Conclusion - how to eject from Chrome Extension
• NPAPIは今後使えない
• Native MessagingはNPAPIほど気軽には使いに
くい
• chrome.system.storageはいまいちおかしい
• chrome.downloadsはZoneIdつけてくれる
• もう少し待てばもっとejectしやすくなるは
ず!

(☝ ՞

՞)☝ウイーン

Special Thanks to @Akkiesoft and Eject-command Users Group
@hasegawayosuke http://utf-8.jp/

Chrome-eject がこの先生きのこるには

  • 1.
  • 2.
    Who am I? はせがわようすけ • http://utf-8.jp/ • 顔文字でJavaScript書いたり • 顔文字で86バイナリ書いたり @hasegawayosuke http://utf-8.jp/
  • 3.
  • 4.
  • 5.
    Chrome-eject uses NPAPI NPAPIplugin • Netscape Plugin API • DLL形式でブラウザの機能を拡張 • Flash Player, Silverlight, ... • http://www.slideshare.net/TNaruto/npapi-26722229 NPAPI plugin in Chrome Extension • JavaScriptだけで出来ないことを実現 • Chrome拡張の制約を超えて何でも可能 • でもDLL書かないと… @hasegawayosuke http://utf-8.jp/
  • 6.
    NPWIN32 • 何度もDLL書くのイヤだ • 何でもできるNPAPIDLLを書いた • JSから任意のWin32APIを呼び出せる • PerlのWin32::APIみたいなもの @hasegawayosuke http://utf-8.jp/
  • 7.
    Chrome-eject uses NPAPI //manifest.json "plugins" : [ { "path" : "win32api.dll", "public" : false } ] // background.html <embed type="application/x-win32api-dynamic-call" id="p" hidden="true" /> var npwin32; var mciSendString; document.addEventListener( "DOMContentLoaded", function (){ chrome.browserAction.onClicked.addListener( function( tab ){ if( npwin32 === undefined ){ npwin32 = document.getElementById( "p" ); } if( mciSendString === undefined ){ mciSendString = npwin32.import( "winmm.dll", "DWORD mciSendStringW( LPCWSTR, DWORD, UINT, DWORD )" ); } if( mciSendString){ var r = mciSendString( "set cdaudio door open", 0, 0, 0 ); } } ); } ); @hasegawayosuke http://utf-8.jp/
  • 8.
    NPWIN32 - callback //import DLL functions var EnumWindows = npwin32.import( "user32.dll", "BOOL EnumWindows( CALLBACK, DWORD )" ); var GetWindowText = npwin32.import( "user32.dll", "INT GetWindowTextW( DWORD, LPWSTR, INT )" ); // create CALLBACK object var func = npwin32.callback( function ( hwnd, lparam ){ var buf = new Array( 257 ).join( " " ); // space * 256 if( GetWindowText( hwnd, buf, 256 ) ){ alert( hwnd + " : " + GetwindowText.arg( 1 ) ); } }, "BOOL (DWORD, DWORD)" ); EnumWindows( func, 0 ); @hasegawayosuke http://utf-8.jp/
  • 9.
    “Goodbye to OurFriend NPAPI” @hasegawayosuke http://utf-8.jp/
  • 10.
  • 11.
    How do Ieject without NPAPI? Native Messaging API @hasegawayosuke http://utf-8.jp/
  • 12.
    How do Ieject without NPAPI? Native Messaging API • http://developer.chrome.com/extensions /messaging.html#native-messaging • Chrome拡張と実行ファイル間でstdioを通じて 通信できる • 事前にmanifestファイルをレジストリに登録 する必要がある • しかもHKLM! (☝ ՞ ՞)☝気軽にejectできない! @hasegawayosuke http://utf-8.jp/
  • 13.
  • 14.
    How do Ieject without NPAPI? キタ━━━━(゚∀゚)━━━━ !!!!! @hasegawayosuke http://utf-8.jp/
  • 15.
    chrome.system.storage • ストレージデバイスの情報を取得 chrome.system.storage.getInfo( function( devices){ console.log( devices ); } ); DVD-ROMデバイス え? fixed? @hasegawayosuke http://utf-8.jp/
  • 16.
    chrome.system.storage • とりあえずejectしてみる chrome.system.storage.getInfo( function( devices){ devices.forEach( function( device ){ if( device.capacity == 0 ){ chrome.system.storage.ejectDevice( device.id, function ( result ){ console.log( result ); } ); } } ); } result === "failure" ); @hasegawayosuke http://utf-8.jp/
  • 17.
    chrome.system.storage • Chrome 30+で使える(はず) • CD-ROMドライブでも ”removable” ではなく “fixed” が返ってくる • ejectDevice 失敗する (☝ ՞ ՞)☝やっぱりejectできない! @hasegawayosuke http://utf-8.jp/
  • 18.
  • 19.
    How do Ieject ? • 拡張のなかにejectするWSHファイル(*.vbs)を 含めておく • chrome.downloads.download APIを使ってvbs をローカルにダウンロードさせる • chrome.downloads.open APIを使ってダウン ロードしたvbsファイルを実行する • うまくいけば eject 完了! @hasegawayosuke http://utf-8.jp/
  • 20.
  • 21.
    chrome.downloads var url =chrome.extension.getURL( "eject.vbs" ); chrome.downloads.download( { url : url, filename : "./" + url.replace( /^chrome-extension:///, "" ), conflictAction : "overwrite" }, function( id ){ if( id === undefined ) return; setTimeout( function(){ chrome.downloads.open( id ); chrome.downloads.erase( { id : id } ); }, 2000 ); } ); いまいち動きがおかしい。donloadのcallbackが呼ばれてすぐだとファ イルを開けないので2秒待ちを入れている @hasegawayosuke http://utf-8.jp/
  • 22.
    eject.vbs Dim Dim Dim Set Set wmp drives i wmp = CreateObject("WMPlayer.OCX" ) drives = wmp.cdromCollection For i = 0 To drives.Count - 1 drives.Item( i ).Eject Next @hasegawayosuke http://utf-8.jp/
  • 23.
  • 24.
    Conclusion - howto eject from Chrome Extension • NPAPIは今後使えない • Native MessagingはNPAPIほど気軽には使いに くい • chrome.system.storageはいまいちおかしい • chrome.downloadsはZoneIdつけてくれる • もう少し待てばもっとejectしやすくなるは ず! (☝ ՞ ՞)☝ウイーン Special Thanks to @Akkiesoft and Eject-command Users Group @hasegawayosuke http://utf-8.jp/