Hi
Just got also a patch for getting package dependencies like the profile
dependencies (actually it uses the same function) because the
0.9.7-test1 won't check for nested package dependencies and uses a
strange comma separated dependency format. The new format is very simple
(analog to the profiles.xml):
<package id=...>
<depends package-id="my-package"/>
<depends package-id="other-package"/>
</package>
Still have to add a way to check against profile dependencies and to
reorder priorities if package dependencies need it to. And we need a
check when we want to remove packages if dependencies are still consistent.
I've also introduced a registry entry in HKLM/Software/WPKG to indicate
the WPKG state to other programs (like our logon script here, which will
inform you that the WPKG service is installing software and you should
hold on a while). This can be turned off (its on by default) by passing
/norunningstate to wpkg.js.
HKLM\Software\WPKG\running can be "true" (REG_SZ) or "false". Our logon
script just polls the value every second until its "false", very easy.
Greets,
Andre
--- wpkg.js Thu Mar 16 19:25:47 2006
+++ wpkg_n.js Mon Mar 20 17:22:26 2006
@@ -59,6 +59,9 @@
* /forceinstall
* Forces installation over existing packages.
*
+ * /norunningstate
+ * Do not export the running state to the registry. (sRegWPKG_Running)
+ *
* /debug
* /verbose
* Prints some debugging info.
@@ -101,6 +104,7 @@
var nonotify = false;
var noreboot = false;
+var exportRunningState = true;
var packagesDocument;
var profilesDocument;
@@ -127,6 +131,8 @@
var settings_file_name = "wpkg.xml";
var sRegPath = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
+// here we indicate our running state
+var sRegWPKG_Running = "HKLM\\Software\\WPKG\\running";
/*******************************************************************************
@@ -205,6 +211,13 @@
forceInstall = false;
}
+ // want to export the state of WPKG to registry?
+ if (isArgSet(argv, "/norunningstate")) {
+ exportRunningState = false;
+ } else {
+ // indicate that we are running
+ setRunningState("true");
+ }
// will use the fso a bit
var fso = new ActiveXObject("Scripting.FileSystemObject");
@@ -403,6 +416,9 @@
message += "/forceinstall\n";
message += " Forces installation over existing packages.\n";
message += "\n";
+ message += "/norunningstate\n";
+ message += " Do not export the running state to the registry.\n";
+ message += "\n";
message += "/debug\n";
message += "/verbose\n";
message += " Prints some debugging info.\n";
@@ -860,6 +876,19 @@
return val;
}
+function setRunningState(statename) {
+ var WshShell = new ActiveXObject("WScript.Shell");
+ var val;
+
+ try {
+ val = WshShell.RegWrite(sRegWPKG_Running, statename);
+ } catch (e) {
+ val = null;
+ }
+
+ return val;
+}
+
/**
* Scans uninstall list for given name.
@@ -1710,34 +1739,54 @@
if (searchArray(packageArray, packageNode)) {
continue;
}
- // Somewhere to store our dependencies
- var depends=null;
+
// sometimes nodes can be null
if (packageNode != null) {
- // add the new node to the array
+ // add package-id dependencies
+ appendPackageDependencies(packageArray, packageNode);
+ // add the new node to the array _after_ adding dependencies
packageArray.push(packageNode);
- depends = packageNode.getAttribute("depends");
+ }
+ }
}
- // Now search all the dependencies
- if ((depends != null) && (depends != "")) {
- var deparray=depends.split(",");
- for (var k=0;k<deparray.length;k++) {
- deppack=trim(deparray[k]);
- var deppkg=packages.selectSingleNode("[EMAIL PROTECTED]'"
+ deppack + "']");
- if (searchArray(packageArray,deppkg)) {
+ return packageArray;
+}
+
+/* nearly the same as appendProfileDependencies() but more relaxed on unknown
+ * or invalid dependencies */
+function appendPackageDependencies(packageArray, packageNode) {
+ appendDependencies(packageArray, packageNode, packages, "package");
+}
+
+function appendDependencies(appendArray, appendNode, sourceArray, sourceName) {
+ // search for package tags in each profile
+ var dependsNodes = appendNode.selectNodes("depends");
+ if (dependsNodes != null) {
+ for (var i = 0; i < dependsNodes.length; i++) {
+ var dependsId = dependsNodes(i).getAttribute(sourceName + "-id");
+ // skip unknown entries
+ if (dependsId == null) continue;
+
+ if (debug) info("Checking " + sourceName + " dependency: " +
dependsId);
+ var dependsNode = sourceArray.selectSingleNode(sourceName + "[EMAIL
PROTECTED]'" +
+ dependsId + "']");
+
+ if (dependsNode == null) {
+ throw new Error(0, "Invalid dependency \"" + dependsId +
+ "\" from " + sourceName + " \"" +
appendNode.getAttribute("id")
+ + "\".");
+ }
+ // duplicate check
+ if (searchArray(appendArray, dependsNode)) {
continue;
} else {
- if ((deppkg != null)) {
- packageArray.push(deppkg);
- }
- }
+ if (debug) info("Add " + sourceName + " dependecy: " +
dependsId);
+ appendArray.push(dependsNode);
+ appendDependencies(appendArray, dependsNode, sourceArray,
sourceName);
}
- } // end search of dependencies
}
}
-
- return packageArray;
}
/**
@@ -1768,30 +1817,7 @@
* array. Recurses into self to get an entire dependency tree.
*/
function appendProfileDependencies(profileArray, profileNode) {
- var dependencyNodes = profileNode.selectNodes("depends");
- for (var i = 0; i < dependencyNodes.length; i++) {
- var dependentId = dependencyNodes(i).getAttribute("profile-id");
-
- // select profile that matches the "profile-id" attribute
- var dependentNode = profiles.selectSingleNode("[EMAIL PROTECTED]'" +
- dependentId + "']");
-
- // if the profile doesn't exist, we have a bad dependency
- if (dependentNode == null) {
- throw new Error(0, "Invalid dependency \"" + dependentId +
- "\" from profile \"" + profileNode.getAttribute("id") + "\".");
- }
-
- // search array for pre-existing profile, we don't want duplicates
- if (searchArray(profileArray, dependentNode)) {
- continue;
- }
-
- // add the new node to the array, and add it's dependencies also
- // (recurse)
- profileArray.push(dependentNode);
- appendProfileDependencies(profileArray, dependentNode);
- }
+ appendDependencies(profileArray, profileNode, profiles, "profile");
}
/**
@@ -2229,6 +2255,10 @@
* Ends program execution with the specified exit code.
*/
function exit(exitCode) {
+ if (exportRunningState) {
+ // reset running state
+ setRunningState("false");
+ }
WScript.Quit(exitCode);
}
/**
begin:vcard
fn:Andre Ilie
n:Ilie;Andre
org:Photonic Sense GmbH;IT NOC
adr:;;Am Goldberg 3;Eisenach;TH;99817;Germany
email;internet:[EMAIL PROTECTED]
title:Systemadministration
tel;work:+49 3691 73 18 0
tel;fax:+49 3691 73 18 79
note:I haven't lost my mind, it's backed up on tape somewhere....
x-mozilla-html:FALSE
url:http://www.photonic-sense.com/
version:2.1
end:vcard