チュートリアルなどの資料では、 install.js 中でファイルをインストールする場合は registerChrome(SKIN, ...);
のように CONTENT
, LOCALE
, SKIN
の各フラグを指定するということになっています。が、これらのフラグを指定しただけだと、ユーザー別のインストールはできません。マルチユーザーの OS などでは、管理者権限が必要になります。
現在のユーザープロファイルに対しファイルをインストールするには、 registerChrome(SKIN | PROFILE_CHROME, ...);
のように PROFILE_CHROME
フラグを付け加えれば OK です。
最も単純な例は、以下のようなものです。ここでは getFolder()
関数でユーザープロファイルのディレクトリを取得し、そこにファイルをコピーした後、インストールを行っています。
var err = initInstall('hogehoge', 'hogehoge', '1.0'),
UChrome = getFolder('Current User', 'chrome');
setPackageFolder(UChrome);
addFile('gashu.org', 'hogehoge.jar', UChrome, '');
registerChrome(SKIN | PROFILE_CHROME, getFolder(UChrome, 'hogehoge.jar'), '');
if (err == SUCCESS) performInstall(); else cancelInstall(err);
これで、 InstallTriger.installChrome()
でスキンなどをインストールするのと同じ結果になります。
PROFILE_CHROME
フラグとDELAYED_CHROME
フラグは同時に指定してはいけません。同時に指定するとファイルの登録が行われなくなってしまいます。この二つは互いに排他的に使う必要があります。
Mozilla 1.3 およびそれ以前のバージョン(含むNetscape 7.0 )では、ファイルのコピー・登録はできるものの overlayinfo が認識されないという大きな問題があります。古いmozilla用のインストールスクリプトでは、スキンや独自の XUL アプリケーションなど overlayinfo を利用する必要がないパッケージの場合にのみ、PROFILE_CHROME
を使うようにしましょう。
通常、prefs.jsに記憶するタイプの設定は、デフォルトの値を以下の書式で定義し、Mozillaをインストールしたフォルダのdefaultsフォルダ内・prefフォルダにmy_app.jsのような名前で置いておくことで、自動認識させることが出来ます。
pref("my_app.global.count", 0);
pref("my_app.func1.enable", true);
pref("my_app.func2.enable", true);
pref("my_app.dir", "c:\\temp\\");
ただしこのフォルダには、管理者権限がないとファイルをインストールできません。ユーザー権限でインストーラを実行する場合、他のファイルはプロファイルディレクトリにインストールすればOKですが、このデフォルトの設定ファイルだけはインストールできないことになってしまいます。
デフォルトの設定ファイルをユーザー権限でのインストール内容に含める場合、デフォルトの設定ファイルもプロファイルディレクトリ内に置き、以下の要領で自力で内容を読み込む必要があると思われます。
function loadDefaultPrefs()
{
// インストールしたデフォルトの設定ファイルの位置を得る
// ユーザープロファイルディレクトリのchromeディレクトリにあるものと仮定
const DIR = Components.classes['@mozilla.org/file/directory_service;1'].getService(Components.interfaces.nsIProperties);
var dir = DIR.get('UChrm', Components.interfaces.nsILocalFile);
var tempLocalFile = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
tempLocalFile.initWithPath(dir.path);
var uri;
const IOService = Components.classes['@mozilla.org/network/io-service;1'].getService(Components.interfaces.nsIIOService);
try {
uri = IOService.newFileURI(tempLocalFile).spec;
}
catch(e) { // [[interchangeability for Mozilla 1.1]]
uri = IOService.getURLSpecFromFile(tempLocalFile);
}
if (!uri.match(/\/$/)) uri += '/';
uri += 'my_app.js';
// ファイルの内容をテキスト(UTF-16)として読み込む
try {
var fileHandler = IOService.getProtocolHandler('file').QueryInterface(Components.interfaces.nsIFileProtocolHandler);
tempLocalFile = fileHandler.getFileFromURLSpec(uri);
}
catch(e) { // [[interchangeability for Mozilla 1.1]]
try {
tempLocalFile = IOService.getFileFromURLSpec(uri);
}
catch(ex) { // [[interchangeability for Mozilla 1.0.x]]
tempLocalFile = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
IOService.initFileFromURLSpec(tempLocalFile, uri);
}
}
if (!tempLocalFile.exists()) return;
var defPref = '';
var stream = Components.classes['@mozilla.org/network/file-input-stream;1'].createInstance(Components.interfaces.nsIFileInputStream);
try {
stream.init(tempLocalFile, 1, 0, false); // open as "read only"
var scriptableStream = Components.classes['@mozilla.org/scriptableinputstream;1'].createInstance(Components.interfaces.nsIScriptableInputStream);
scriptableStream.init(stream);
var fileSize = scriptableStream.available();
var fileContents = scriptableStream.read(fileSize);
scriptableStream.close();
stream.close();
defPref = fileContents;
}
catch(e) {
return;
}
// 設定ファイルの内容を解釈するための関数を用意する
const DEFPREF = Components.classes['@mozilla.org/preferences-service;1'].getService(Components.interfaces.nsIPrefService).getDefaultBranch(null);
function pref(aPrefstring, aValue) {
switch (typeof aValue)
{
case 'string':
var nsISupportsString = ('nsISupportsWString' in Components.interfaces) ? Components.interfaces.nsISupportsWString : Components.interfaces.nsISupportsString;
var string = ('@mozilla.org/supports-wstring;1' in Components.classes) ?
Components.classes['@mozilla.org/supports-wstring;1'].createInstance(nsISupportsString) :
Components.classes['@mozilla.org/supports-string;1'].createInstance(nsISupportsString);
string.data = aValue ;
DEFPREF.setComplexValue(aPrefstring, nsISupportsString, string);
break;
case 'number':
DEFPREF.setIntPref(aPrefstring, parseInt(aValue));
break;
default:
DEFPREF.setBoolPref(aPrefstring, aValue);
break;
}
}
// 内容を解釈する
eval(defPref);
}