📄 nspostupdatewin.js
字号:
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- *//* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Update Service. * * The Initial Developer of the Original Code is Google Inc. * Portions created by the Initial Developer are Copyright (C) 2005 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Darin Fisher <darin@meer.net> (original author) * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** *//** * This file contains an implementation of nsIRunnable, which may be invoked * to perform post-update modifications to the windows registry and uninstall * logs required to complete an update of the application. This code is very * specific to the xpinstall wizard for windows. */const URI_BRAND_PROPERTIES = "chrome://branding/locale/brand.properties";const KEY_APPDIR = "XCurProcD";const KEY_TMPDIR = "TmpD";const KEY_LOCALDATA = "DefProfLRt";const KEY_PROGRAMFILES = "ProgF";const KEY_UAPPDATA = "UAppData";// see prio.hconst PR_RDONLY = 0x01;const PR_WRONLY = 0x02;const PR_APPEND = 0x10;const PERMS_FILE = 0644;const PERMS_DIR = 0700;const nsIWindowsRegKey = Components.interfaces.nsIWindowsRegKey;var gConsole = null;var gAppUpdateLogPostUpdate = false;//-----------------------------------------------------------------------------/** * Console logging support */function LOG(s) { if (gAppUpdateLogPostUpdate) { dump("*** PostUpdateWin: " + s + "\n"); gConsole.logStringMessage(s); }}/** * This function queries the XPCOM directory service. */function getFile(key) { var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"]. getService(Components.interfaces.nsIProperties); return dirSvc.get(key, Components.interfaces.nsIFile);}/** * Return the full path given a relative path and a base directory. */function getFileRelativeTo(dir, relPath) { var file = dir.clone().QueryInterface(Components.interfaces.nsILocalFile); file.setRelativeDescriptor(dir, relPath); return file;}/** * Creates a new file object given a native file path. * @param path * The native file path. * @return nsILocalFile object for the given native file path. */function newFile(path) { var file = Components.classes["@mozilla.org/file/local;1"] .createInstance(Components.interfaces.nsILocalFile); file.initWithPath(path); return file;}/** * This function returns a file input stream. */function openFileInputStream(file) { var stream = Components.classes["@mozilla.org/network/file-input-stream;1"]. createInstance(Components.interfaces.nsIFileInputStream); stream.init(file, PR_RDONLY, 0, 0); return stream;}/** * This function returns a file output stream. */function openFileOutputStream(file, flags) { var stream = Components.classes["@mozilla.org/network/file-output-stream;1"]. createInstance(Components.interfaces.nsIFileOutputStream); stream.init(file, flags, 0644, 0); return stream;}//-----------------------------------------------------------------------------const PREFIX_FILE = "File: ";function InstallLogWriter() {}InstallLogWriter.prototype = { _outputStream: null, // nsIOutputStream to the install wizard log file /** * Write a single line to the output stream. */ _writeLine: function(s) { s = s + "\r\n"; this._outputStream.write(s, s.length); }, /** * This function creates an empty uninstall update log file if it doesn't * exist and returns a reference to the resulting nsIFile. */ _getUninstallLogFile: function() { var file = getFile(KEY_APPDIR); file.append("uninstall"); if (!file.exists()) return null; file.append("uninstall.log"); if (!file.exists()) file.create(Components.interfaces.nsILocalFile.NORMAL_FILE_TYPE, PERMS_FILE); return file; }, /** * Return the update.log file. Use last-update.log file in case the * updates/0 directory has already been cleaned out (see bug 311302). */ _getUpdateLogFile: function() { function appendUpdateLogPath(root) { var file = root.clone(); file.append("updates"); file.append("0"); file.append("update.log"); if (file.exists()) return file; file = root; file.append("updates"); file.append("last-update.log"); if (file.exists()) return file; return null; } // See the local appdata first if app dir is under Program Files. var file = null; var updRoot = getFile(KEY_APPDIR); var fileLocator = Components.classes["@mozilla.org/file/directory_service;1"] .getService(Components.interfaces.nsIProperties); // Fallback to previous behavior since getting ProgF // (e.g. KEY_PROGRAMFILES) may fail on Win9x. try { var programFilesDir = fileLocator.get(KEY_PROGRAMFILES, Components.interfaces.nsILocalFile); if (programFilesDir.contains(updRoot, true)) { var relativePath = updRoot.QueryInterface(Components.interfaces.nsILocalFile). getRelativeDescriptor(programFilesDir); var userLocalDir = fileLocator.get(KEY_LOCALDATA, Components.interfaces.nsILocalFile).parent; updRoot.setRelativeDescriptor(userLocalDir, relativePath); file = appendUpdateLogPath(updRoot); // When updating from Fx 2.0.0.1 to 2.0.0.3 (or later) on Vista, // we will have to see also user app data (see bug 351949). if (!file) file = appendUpdateLogPath(getFile(KEY_UAPPDATA)); } } catch (e) {} // See the app dir if not found or app dir is out of Program Files. if (!file) file = appendUpdateLogPath(getFile(KEY_APPDIR)); return file; }, /** * Read update.log to extract information about files that were * newly added for this update. */ _readUpdateLog: function(logFile, entries) { var stream; try { stream = openFileInputStream(logFile). QueryInterface(Components.interfaces.nsILineInputStream); var line = {}; while (stream.readLine(line)) { var data = line.value.split(" "); if (data[0] == "EXECUTE" && data[1] == "ADD") { // The uninstaller requires the path separator to be "\" and // relative paths to start with a "\". var relPath = "\\" + data[2].replace(/\//g, "\\"); entries[relPath] = null; } } } finally { if (stream) stream.close(); } }, /** * Read install_wizard log files to extract information about files that were * previously added by the xpinstall installer and software update. */ _readXPInstallLog: function(logFile, entries) { var stream; try { stream = openFileInputStream(logFile). QueryInterface(Components.interfaces.nsILineInputStream); function fixPath(path, offset) { return path.substr(offset).replace(appDirPath, ""); } var appDir = getFile(KEY_APPDIR); var appDirPath = appDir.path; var line = {}; while (stream.readLine(line)) { var entry = line.value; // This works with both the entries from xpinstall (e.g. Installing: ) // and from update (e.g. installing: ) var searchStr = "nstalling: "; var index = entry.indexOf(searchStr); if (index != -1) { entries[fixPath(entry, index + searchStr.length)] = null; continue; } searchStr = "Replacing: "; index = entry.indexOf(searchStr); if (index != -1) { entries[fixPath(entry, index + searchStr.length)] = null; continue; } searchStr = "Windows Shortcut: "; index = entry.indexOf(searchStr); if (index != -1) { entries[fixPath(entry + ".lnk", index + searchStr.length)] = null; continue; } } } finally { if (stream) stream.close(); } }, _readUninstallLog: function(logFile, entries) { var stream; try { stream = openFileInputStream(logFile). QueryInterface(Components.interfaces.nsILineInputStream); var line = {}; var searchStr = "File: "; while (stream.readLine(line)) { var index = line.value.indexOf(searchStr); if (index != -1) { var str = line.value.substr(index + searchStr.length); entries.push(str); } } } finally { if (stream) stream.close(); } }, /** * This function initializes the log writer and is responsible for * translating 'update.log' and the 'install_wizard' logs to the NSIS format. */ begin: function() { var updateLog = this._getUpdateLogFile(); if (!updateLog) return; var newEntries = { }; this._readUpdateLog(updateLog, newEntries); try { const nsIDirectoryEnumerator = Components.interfaces.nsIDirectoryEnumerator; const nsILocalFile = Components.interfaces.nsILocalFile; var prefixWizLog = "install_wizard"; var uninstallDir = getFile(KEY_APPDIR); uninstallDir.append("uninstall"); var entries = uninstallDir.directoryEntries.QueryInterface(nsIDirectoryEnumerator); while (true) { var wizLog = entries.nextFile; if (!wizLog) break; if (wizLog instanceof nsILocalFile && !wizLog.isDirectory() && wizLog.leafName.indexOf(prefixWizLog) == 0) { this._readXPInstallLog(wizLog, newEntries); wizLog.remove(false); } } } catch (e) {} if (entries) entries.close(); var uninstallLog = this._getUninstallLogFile(); var oldEntries = []; this._readUninstallLog(uninstallLog, oldEntries); // Prevent writing duplicate entries in the log file for (var relPath in newEntries) { if (oldEntries.indexOf(relPath) != -1) delete newEntries[relPath]; } if (newEntries.length == 0) return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -