Berechnung der superseded updates (Teil 1)

Berechnung der superseded updates (Teil 1)

Postby hbuhrmester » 03.08.2015, 12:41

Eine bessere Methode zur Berechnung der superseded updates (Teil 1)

Das Problem: Ein wichtiger Schritt bei der Berechnung der superseded updates ist die Zuordnung von Bundle-RevisionIds, Update-RevisionIds und FileIds. Doch mit der gegenwärtigen Methode stimmt diese Zuordnung manchmal nicht.

Das kann man am besten an einer minimalen Beispieldatei demonstrieren:

Beispiel_1.xml
Code: Select all
<?xml version="1.0" encoding="utf-8"?>
<OfflineSyncPackage>
  <Updates>
    <Update RevisionId="50" IsBundle="true" />
    <Update RevisionId="49">
      <PayloadFiles>
        <File Id="a=" />
      </PayloadFiles>
      <BundledBy>
        <Revision Id="50" />
      </BundledBy>
    </Update>
    <Update RevisionId="48">
      <PayloadFiles>
        <File Id="b=" />
      </PayloadFiles>
      <BundledBy>
        <Revision Id="50" />
      </BundledBy>
    </Update>
    <Update RevisionId="47">
      <PayloadFiles>
        <File Id="c=" />
      </PayloadFiles>
      <BundledBy>
        <Revision Id="50" />
      </BundledBy>
    </Update>
    <Update RevisionId="46" IsBundle="true" />
    <Update RevisionId="45">
      <PayloadFiles>
        <File Id="d=" />
      </PayloadFiles>
      <BundledBy>
        <Revision Id="46" />
      </BundledBy>
    </Update>
    <Update RevisionId="44">
      <PayloadFiles>
        <File Id="e=" />
      </PayloadFiles>
      <BundledBy>
        <Revision Id="46" />
      </BundledBy>
    </Update>
    <Update RevisionId="43">
      <PayloadFiles>
        <File Id="f=" />
      </PayloadFiles>
      <BundledBy>
        <Revision Id="46" />
      </BundledBy>
    </Update>
    <Update RevisionId="42" IsBundle="true" />
    <Update RevisionId="41">
      <PayloadFiles>
        <File Id="g=" />
      </PayloadFiles>
      <BundledBy>
        <Revision Id="42" />
      </BundledBy>
    </Update>
    <Update RevisionId="40">
      <PayloadFiles>
        <File Id="h=" />
      </PayloadFiles>
      <BundledBy>
        <Revision Id="42" />
      </BundledBy>
    </Update>
    <Update RevisionId="39">
      <PayloadFiles>
        <File Id="i=" />
      </PayloadFiles>
      <BundledBy>
        <Revision Id="42" />
      </BundledBy>
    </Update>
  </Updates>
</OfflineSyncPackage>


Bundle-Records und Update-Records stehen in der XML-Datei auf derselben Hierarchieebene und sind beide vom Typ "Update". Bundle-Records haben aber das Attribut IsBundle="true", und sie enthalten zusätzliche Informationen zu den nachfolgenden Update-Records.

Update-Records wiederum haben einen Rückverweis "BundledBy" auf den darüberstehenden Bundle-Record. Update-Records enthalten jeweils ein "PayloadFile". Alle Records enthalten noch weitere Elemente, zum Beispiel für die verwendete Sprache, aber diese habe ich für das minimale Beispiel weggelassen.

Die XSLT-Datei ExtractUpdateRevisionAndFileIds.xsl extrahiert nun die RevisionIds und File-Ids. Für die erste Beispieldatei sieht das Ergebnis so aus:

Code: Select all
$ xmlstarlet transform ExtractUpdateRevisionAndFileIds.xsl Beispiel_1.xml
#50#
#49#,a=
#48#,b=
#47#,c=
#46#
#45#,d=
#44#,e=
#43#,f=
#42#
#41#,g=
#40#,h=
#39#,i=


Danach kommt im Skript eine Schleife, bei der Bundle-RevisionIds und Update-RevisionIds einander zugeordnet werden: Wenn eine RevisionId alleine in einer Zeile steht, dann gilt sie als Bundle-RevisionId und wird an die nachfolgenden Zeilen mit Update-RevisionIds angefügt. Die Datei BundledUpdateRevisionAndFileIds.txt sieht für dieses erste Beispiel dann so aus:

Code: Select all
#50#
#49#,a=;#50#
#48#,b=;#50#
#47#,c=;#50#
#46#
#45#,d=;#46#
#44#,e=;#46#
#43#,f=:#46#
#42#
#41#,g=;#42#
#40#,h=;#42#
#39#,i=;#42#


Allerdings kann auch ein Bundle-Record Referenzen für EulaFiles enthalten. Wenn man ein solches Element in den Bundle-Record mit der RevisionId 46 einfügt, sieht die Beispieldatei so aus:

Beispiel_2.xml
Code: Select all
<?xml version="1.0" encoding="utf-8"?>
<OfflineSyncPackage>
  <Updates>
    <Update RevisionId="50" IsBundle="true" />
    <Update RevisionId="49">
      <PayloadFiles>
        <File Id="a=" />
      </PayloadFiles>
      <BundledBy>
        <Revision Id="50" />
      </BundledBy>
    </Update>
    <Update RevisionId="48">
      <PayloadFiles>
        <File Id="b=" />
      </PayloadFiles>
      <BundledBy>
        <Revision Id="50" />
      </BundledBy>
    </Update>
    <Update RevisionId="47">
      <PayloadFiles>
        <File Id="c=" />
      </PayloadFiles>
      <BundledBy>
        <Revision Id="50" />
      </BundledBy>
    </Update>
    <Update RevisionId="46" IsBundle="true">
      <EulaFiles>
        <File Id="xxx=" />
      </EulaFiles>
    </Update>
    <Update RevisionId="45">
      <PayloadFiles>
        <File Id="d=" />
      </PayloadFiles>
      <BundledBy>
        <Revision Id="46" />
      </BundledBy>
    </Update>
    <Update RevisionId="44">
      <PayloadFiles>
        <File Id="e=" />
      </PayloadFiles>
      <BundledBy>
        <Revision Id="46" />
      </BundledBy>
    </Update>
    <Update RevisionId="43">
      <PayloadFiles>
        <File Id="f=" />
      </PayloadFiles>
      <BundledBy>
        <Revision Id="46" />
      </BundledBy>
    </Update>
    <Update RevisionId="42" IsBundle="true" />
    <Update RevisionId="41">
      <PayloadFiles>
        <File Id="g=" />
      </PayloadFiles>
      <BundledBy>
        <Revision Id="42" />
      </BundledBy>
    </Update>
    <Update RevisionId="40">
      <PayloadFiles>
        <File Id="h=" />
      </PayloadFiles>
      <BundledBy>
        <Revision Id="42" />
      </BundledBy>
    </Update>
    <Update RevisionId="39">
      <PayloadFiles>
        <File Id="i=" />
      </PayloadFiles>
      <BundledBy>
        <Revision Id="42" />
      </BundledBy>
    </Update>
  </Updates>
</OfflineSyncPackage>


Die XSLT-Datei ExtractUpdateRevisionAndFileIds.xsl unterscheidet allerdings nicht zwischen PayloadFiles und EulaFiles. Beide haben eine FileId, und alle FileIds werden gleichermaßen ausgegeben. Damit sieht die Ausgabe so aus:

Code: Select all
$ xmlstarlet transform ExtractUpdateRevisionAndFileIds.xsl Beispiel_2.xml
#50#
#49#,a=
#48#,b=
#47#,c=
#46#,xxx=
#45#,d=
#44#,e=
#43#,f=
#42#
#41#,g=
#40#,h=
#39#,i=


Nach der Zuordnung von Bundle-RevisionIds und Update-RevisionIds in der anschließenden Programmschleife hat die Datei BundledUpdateRevisionAndFileIds.txt den Inhalt:

Code: Select all
#50#
#49#,a=;#50#
#48#,b=;#50#
#47#,c=;#50#
#46#,xxx=;#50#
#45#,d=;#50#
#44#,e=;#50#
#43#,f=;#50#
#42#
#41#,g=;#42#
#40#,h=;#42#
#39#,i=;#42#


Der Bundle-Record 46 wird nun als Update-Record interpretiert. Die Bundle-RevisionId 46 wird unterschlagen und in der weiteren Auswertung nicht mehr berücksichtigt. Statt dessen wird die Bundle-RevisionId 50 an die Zeile mit dem Bundle-Record 46 und an die drei nachfolgenden Zeilen mit Update-Records angefügt.

Da die Bundle-Records bestimmen, welche Dateien als superseded gelten, kann es am Ende zu Unstimmigkeiten kommen.
hbuhrmester
 
Posts: 525
Joined: 11.10.2013, 20:59

Eine bessere Lösung (Teil 2)

Postby hbuhrmester » 03.08.2015, 12:45

Besser wäre es, wenn man alle drei Felder aus demselben Datensatz extrahiert. Denn die Update-Records enthalten ja die eigene RevisionId, die File-Id für das PayloadFile und einen Rückverweis auf den darüberstehenden Bundle-Record.

Für die zweite Beispieldatei könnte der Aufruf mit XMLStarlet so aussehen:

Code: Select all
xmlstarlet select \
--text \
--template \
--match "OfflineSyncPackage/Updates/Update" \
--output "#" --value-of "@RevisionId" --output "#," \
--value-of "PayloadFiles/File/@Id" --output ";" \
--output "#" --value-of "BundledBy/Revision/@Id" --output "#" \
--nl \
Beispiel_2.xml


Das Ergebnis sieht dann so aus:

Code: Select all
#50#,;##
#49#,a=;#50#
#48#,b=;#50#
#47#,c=;#50#
#46#,;##
#45#,d=;#46#
#44#,e=;#46#
#43#,f=;#46#
#42#,;##
#41#,g=;#42#
#40#,h=;#42#
#39#,i=;#42#


Damit hat man die Datei BundledUpdateRevisionAndFileIds.txt in nur einem Schritt geschrieben und kann sich die anschließende Programmschleife im Skript sparen.

Noch geschickter ist es, wenn man als Match den Pfad "OfflineSyncPackage/Updates/Update/BundledBy/Revision" auswählt. Denn in einzelnen Fällen kann das Element "BundledBy" mehrere unterschiedliche Rückverweise enthalten, oder derselbe Rückverweis kommt doppelt vor.

Code: Select all
xmlstarlet select \
--text \
--template \
--match "OfflineSyncPackage/Updates/Update/BundledBy/Revision" \
--output "#" --value-of "../../@RevisionId" --output "#," \
--value-of "../../PayloadFiles/File/@Id" --output ";" \
--output "#" --value-of "@Id" --output "#" \
--nl \
MinimalesBeispiel2.xml


Die Datei BundledUpdateRevisionAndFileIds.txt enthält dann nur noch die Update-Records mit allen drei Feldern:

Code: Select all
#49#,a=;#50#
#48#,b=;#50#
#47#,c=;#50#
#45#,d=;#46#
#44#,e=;#46#
#43#,f=;#46#
#41#,g=;#42#
#40#,h=;#42#
#39#,i=;#42#
hbuhrmester
 
Posts: 525
Joined: 11.10.2013, 20:59

Common Problems: Namespaces and default namespace (Teil 3)

Postby hbuhrmester » 03.08.2015, 12:50

Wenn man das mit der richtigen Datei package.xml ausprobiert, wird man allerdings feststellen, dass es so einfach nicht geht. Das Problem ist, dass die Datei package.xml eine default namespace verwendet, die an das oberste Element gebunden ist. Dieses Problem wird in der Dokumentation zu XMLStarlet in einem eigenen Kapitel beschrieben:

http://xmlstar.sourceforge.net/doc/UG/ch05.html

Wenn man die Beispieldatei entsprechend erweitert, würde sie so aussehen:

Beispiel_3.xml
Code: Select all
<?xml version="1.0" encoding="utf-8"?>
<OfflineSyncPackage xmlns="http://schemas.microsoft.com/msus/2004/02/OfflineSync">
  <Updates>
    <Update RevisionId="50" IsBundle="true" />
    <Update RevisionId="49">
      <PayloadFiles>
        <File Id="a=" />
      </PayloadFiles>
      <BundledBy>
        <Revision Id="50" />
      </BundledBy>
    </Update>
    <Update RevisionId="48">
      <PayloadFiles>
        <File Id="b=" />
      </PayloadFiles>
      <BundledBy>
        <Revision Id="50" />
      </BundledBy>
    </Update>
    <Update RevisionId="47">
      <PayloadFiles>
        <File Id="c=" />
      </PayloadFiles>
      <BundledBy>
        <Revision Id="50" />
      </BundledBy>
    </Update>
    <Update RevisionId="46" IsBundle="true">
      <EulaFiles>
        <File Id="xxx=" />
      </EulaFiles>
    </Update>
    <Update RevisionId="45">
      <PayloadFiles>
        <File Id="d=" />
      </PayloadFiles>
      <BundledBy>
        <Revision Id="46" />
      </BundledBy>
    </Update>
    <Update RevisionId="44">
      <PayloadFiles>
        <File Id="e=" />
      </PayloadFiles>
      <BundledBy>
        <Revision Id="46" />
      </BundledBy>
    </Update>
    <Update RevisionId="43">
      <PayloadFiles>
        <File Id="f=" />
      </PayloadFiles>
      <BundledBy>
        <Revision Id="46" />
      </BundledBy>
    </Update>
    <Update RevisionId="42" IsBundle="true" />
    <Update RevisionId="41">
      <PayloadFiles>
        <File Id="g=" />
      </PayloadFiles>
      <BundledBy>
        <Revision Id="42" />
      </BundledBy>
    </Update>
    <Update RevisionId="40">
      <PayloadFiles>
        <File Id="h=" />
      </PayloadFiles>
      <BundledBy>
        <Revision Id="42" />
      </BundledBy>
    </Update>
    <Update RevisionId="39">
      <PayloadFiles>
        <File Id="i=" />
      </PayloadFiles>
      <BundledBy>
        <Revision Id="42" />
      </BundledBy>
    </Update>
  </Updates>
</OfflineSyncPackage>


Die Dokumentation zu XMLStarlet schlägt zwei mögliche Workarounds vor:
  1. Man kann die namespace-Deklaration einfach wieder löschen. Das hat keine erkennbaren Konsequenzen.
  2. Man definiert ein eigenes Alias für die Namespace und fügt sie als Präfix an alle Pfadelemente an. Damit sieht der xmlstarlet select Befehl so aus:

Code: Select all
xmlstarlet select -N __="http://schemas.microsoft.com/msus/2004/02/OfflineSync" \
--text \
--template \
--match "__:OfflineSyncPackage/__:Updates/__:Update/__:BundledBy/__:Revision" \
--output "#" --value-of "../../@RevisionId" --output "#," \
--value-of "../../__:PayloadFiles/__:File/@Id" --output ";" \
--output "#" --value-of "@Id" --output "#" \
--nl \
Beispiel_3.xml


Das Ergebnis ist dasselbe wie im letzten Beispiel.

Code: Select all
#49#,a=;#50#
#48#,b=;#50#
#47#,c=;#50#
#45#,d=;#46#
#44#,e=;#46#
#43#,f=;#46#
#41#,g=;#42#
#40#,h=;#42#
#39#,i=;#42#
hbuhrmester
 
Posts: 525
Joined: 11.10.2013, 20:59

Bestimmung der superseded RevisionIds (Teil 4)

Postby hbuhrmester » 03.08.2015, 12:53

Die zweite Ausgangsdatei für die Berechnung der superseded Updates ist eine Liste mit den superseded RevisionIds.

Bundle-Records enthalten ein Element mit dem Namen "SupersededBy", wenn sie durch andere Bundles ersetzt werden. Im folgenden Beispiel werden die beiden Bundle-Records 46 und 42 durch den Bundle-Record 50 ersetzt.

Beispiel_4.xml
Code: Select all
<?xml version="1.0" encoding="utf-8"?>
<OfflineSyncPackage xmlns="http://schemas.microsoft.com/msus/2004/02/OfflineSync">
  <Updates>
    <Update RevisionId="50" IsBundle="true" />
    <Update RevisionId="49">
      <PayloadFiles>
        <File Id="a=" />
      </PayloadFiles>
      <BundledBy>
        <Revision Id="50" />
      </BundledBy>
    </Update>
    <Update RevisionId="48">
      <PayloadFiles>
        <File Id="b=" />
      </PayloadFiles>
      <BundledBy>
        <Revision Id="50" />
      </BundledBy>
    </Update>
    <Update RevisionId="47">
      <PayloadFiles>
        <File Id="c=" />
      </PayloadFiles>
      <BundledBy>
        <Revision Id="50" />
      </BundledBy>
    </Update>
    <Update RevisionId="46" IsBundle="true">
      <EulaFiles>
        <File Id="xxx=" />
      </EulaFiles>
      <SupersededBy>
        <Revision Id="50" />
      </SupersededBy>
    </Update>
    <Update RevisionId="45">
      <PayloadFiles>
        <File Id="d=" />
      </PayloadFiles>
      <BundledBy>
        <Revision Id="46" />
      </BundledBy>
    </Update>
    <Update RevisionId="44">
      <PayloadFiles>
        <File Id="e=" />
      </PayloadFiles>
      <BundledBy>
        <Revision Id="46" />
      </BundledBy>
    </Update>
    <Update RevisionId="43">
      <PayloadFiles>
        <File Id="f=" />
      </PayloadFiles>
      <BundledBy>
        <Revision Id="46" />
      </BundledBy>
    </Update>
    <Update RevisionId="42" IsBundle="true">
      <SupersededBy>
        <Revision Id="50" />
      </SupersededBy>
    </Update>
    <Update RevisionId="41">
      <PayloadFiles>
        <File Id="g=" />
      </PayloadFiles>
      <BundledBy>
        <Revision Id="42" />
      </BundledBy>
    </Update>
    <Update RevisionId="40">
      <PayloadFiles>
        <File Id="h=" />
      </PayloadFiles>
      <BundledBy>
        <Revision Id="42" />
      </BundledBy>
    </Update>
    <Update RevisionId="39">
      <PayloadFiles>
        <File Id="i=" />
      </PayloadFiles>
      <BundledBy>
        <Revision Id="42" />
      </BundledBy>
    </Update>
  </Updates>
</OfflineSyncPackage>


Die superseded Bundle-Records und ihre RevisionIds lassen sich leicht ausfiltern:

Code: Select all
xmlstarlet select -N __="http://schemas.microsoft.com/msus/2004/02/OfflineSync" \
--text \
--template \
--match "__:OfflineSyncPackage/__:Updates/__:Update/__:SupersededBy" \
--output "#" --value-of "../@RevisionId" --output "#" \
--nl \
Beispiel_4.xml


Als Ergebnis erhält man die beiden superseded RevisionIds:

Code: Select all
#46#
#42#


Damit hat man auch die Datei ValidSupersededRevisionIds.txt in nur einem Schritt geschrieben.
hbuhrmester
 
Posts: 525
Joined: 11.10.2013, 20:59

Übersetzung in XSLT-Dateien (Teil 5)

Postby hbuhrmester » 03.08.2015, 12:59

Mit dem Befehl xmlstarlet select kann man xsl-Transformationen leicht auf der Kommandozeile ausprobieren, mit einer vereinfachten Syntax. Wenn man mit dem Ergebnis zufrieden ist, kann man daraus wieder XSLT-Dateien erzeugen. Das geht in XMLStarlet sogar automatisch, indem man zusätzlich die Option --comp angibt. Allerdings ist der so erzeugte Code unnötig kompliziert.

Kompakte Versionen für die beiden XSL-Transformationen wären:

extract-bundled-revision-ids.xsl
Code: Select all
<?xml version="1.0"?>
<!-- Author: H. Buhrmester -->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:__="http://schemas.microsoft.com/msus/2004/02/OfflineSync" version="1.0">
  <xsl:output omit-xml-declaration="yes" indent="no" method="text" />
  <xsl:template match="/">
    <xsl:for-each select="__:OfflineSyncPackage/__:Updates/__:Update/__:BundledBy/__:Revision">
      <xsl:text>#</xsl:text>
      <xsl:value-of select="../../@RevisionId" />
      <xsl:text>#,</xsl:text>
      <xsl:value-of select="../../__:PayloadFiles/__:File/@Id" />
      <xsl:text>;#</xsl:text>
      <xsl:value-of select="@Id" />
      <xsl:text>#</xsl:text>
      <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>


extract-superseded-bundle-revision-ids.xsl
Code: Select all
<?xml version="1.0"?>
<!-- Author: H. Buhrmester -->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:__="http://schemas.microsoft.com/msus/2004/02/OfflineSync" version="1.0">
  <xsl:output omit-xml-declaration="yes" indent="no" method="text" />
  <xsl:template match="/">
    <xsl:for-each select="__:OfflineSyncPackage/__:Updates/__:Update/__:SupersededBy">
      <xsl:text>#</xsl:text>
      <xsl:value-of select="../@RevisionId" />
      <xsl:text>#</xsl:text>
      <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>


Zum einfachen Ausprobieren unter Windows muss man alle Dateien in dasselbe Verzeichnis legen:

Code: Select all
CScript /E:vbs XSLT.vbs Beispiel_4.xml extract-bundled-revision-ids.xsl BundledUpdateRevisionAndFileIds.txt
CScript /E:vbs XSLT.vbs Beispiel_4.xml extract-superseded-bundle-revision-ids.xsl ValidSupersededRevisionIds.txt

CScript /E:vbs XSLT.vbs package.xml extract-bundled-revision-ids.xsl BundledUpdateRevisionAndFileIds.txt
CScript /E:vbs XSLT.vbs package.xml extract-superseded-bundle-revision-ids.xsl ValidSupersededRevisionIds.txt
hbuhrmester
 
Posts: 525
Joined: 11.10.2013, 20:59

Referenz: Struktur der Datei package.xml (Teil 6)

Postby hbuhrmester » 03.08.2015, 13:01

Mit XMLStarlet kann man sich auch die Struktur einer XML-Datei ausgeben lassen, um einen Überblick über alle Elemente und Attribute zu bekommen:

Alle Elemente:

Code: Select all
$ xmlstarlet el -u package.xml
OfflineSyncPackage
OfflineSyncPackage/FileLocations
OfflineSyncPackage/FileLocations/FileLocation
OfflineSyncPackage/Updates
OfflineSyncPackage/Updates/Update
OfflineSyncPackage/Updates/Update/BundledBy
OfflineSyncPackage/Updates/Update/BundledBy/Revision
OfflineSyncPackage/Updates/Update/Categories
OfflineSyncPackage/Updates/Update/Categories/Category
OfflineSyncPackage/Updates/Update/EulaFiles
OfflineSyncPackage/Updates/Update/EulaFiles/File
OfflineSyncPackage/Updates/Update/EulaFiles/File/Language
OfflineSyncPackage/Updates/Update/Languages
OfflineSyncPackage/Updates/Update/Languages/Language
OfflineSyncPackage/Updates/Update/PayloadFiles
OfflineSyncPackage/Updates/Update/PayloadFiles/File
OfflineSyncPackage/Updates/Update/Prerequisites
OfflineSyncPackage/Updates/Update/Prerequisites/Or
OfflineSyncPackage/Updates/Update/Prerequisites/Or/UpdateId
OfflineSyncPackage/Updates/Update/Prerequisites/UpdateId
OfflineSyncPackage/Updates/Update/SupersededBy
OfflineSyncPackage/Updates/Update/SupersededBy/Revision


Alle Elemente und Attribute:

Code: Select all
$ xmlstarlet el -a package.xml | LC_ALL=C sort -u
OfflineSyncPackage
OfflineSyncPackage/@CreationDate
OfflineSyncPackage/@MinimumClientVersion
OfflineSyncPackage/@PackageId
OfflineSyncPackage/@PackageVersion
OfflineSyncPackage/@ProtocolVersion
OfflineSyncPackage/@SourceId
OfflineSyncPackage/@xmlns
OfflineSyncPackage/FileLocations
OfflineSyncPackage/FileLocations/FileLocation
OfflineSyncPackage/FileLocations/FileLocation/@Id
OfflineSyncPackage/FileLocations/FileLocation/@IsIncluded
OfflineSyncPackage/FileLocations/FileLocation/@Url
OfflineSyncPackage/Updates
OfflineSyncPackage/Updates/Update
OfflineSyncPackage/Updates/Update/@CreationDate
OfflineSyncPackage/Updates/Update/@DefaultLanguage
OfflineSyncPackage/Updates/Update/@DeploymentAction
OfflineSyncPackage/Updates/Update/@DownloadPriority
OfflineSyncPackage/Updates/Update/@IsBundle
OfflineSyncPackage/Updates/Update/@IsLeaf
OfflineSyncPackage/Updates/Update/@IsSoftware
OfflineSyncPackage/Updates/Update/@RevisionId
OfflineSyncPackage/Updates/Update/@RevisionNumber
OfflineSyncPackage/Updates/Update/@UpdateId
OfflineSyncPackage/Updates/Update/BundledBy
OfflineSyncPackage/Updates/Update/BundledBy/Revision
OfflineSyncPackage/Updates/Update/BundledBy/Revision/@Id
OfflineSyncPackage/Updates/Update/Categories
OfflineSyncPackage/Updates/Update/Categories/Category
OfflineSyncPackage/Updates/Update/Categories/Category/@Id
OfflineSyncPackage/Updates/Update/Categories/Category/@Type
OfflineSyncPackage/Updates/Update/EulaFiles
OfflineSyncPackage/Updates/Update/EulaFiles/File
OfflineSyncPackage/Updates/Update/EulaFiles/File/@Id
OfflineSyncPackage/Updates/Update/EulaFiles/File/Language
OfflineSyncPackage/Updates/Update/EulaFiles/File/Language/@Name
OfflineSyncPackage/Updates/Update/Languages
OfflineSyncPackage/Updates/Update/Languages/Language
OfflineSyncPackage/Updates/Update/Languages/Language/@Name
OfflineSyncPackage/Updates/Update/PayloadFiles
OfflineSyncPackage/Updates/Update/PayloadFiles/File
OfflineSyncPackage/Updates/Update/PayloadFiles/File/@Id
OfflineSyncPackage/Updates/Update/Prerequisites
OfflineSyncPackage/Updates/Update/Prerequisites/Or
OfflineSyncPackage/Updates/Update/Prerequisites/Or/UpdateId
OfflineSyncPackage/Updates/Update/Prerequisites/Or/UpdateId/@Id
OfflineSyncPackage/Updates/Update/Prerequisites/UpdateId
OfflineSyncPackage/Updates/Update/Prerequisites/UpdateId/@Id
OfflineSyncPackage/Updates/Update/SupersededBy
OfflineSyncPackage/Updates/Update/SupersededBy/Revision
OfflineSyncPackage/Updates/Update/SupersededBy/Revision/@Id
hbuhrmester
 
Posts: 525
Joined: 11.10.2013, 20:59

Re: Berechnung der superseded updates (Teil 1)

Postby WSUSUpdateAdmin » 06.08.2015, 11:52

Hallo Hartmut,

Wahnsinn, was Du Dir da für eine Arbeit gemacht hast!
Das ist mehr Doku zu diesem doch recht komplexen Thema, als ich aus der Zeit der Entwicklung übrig behalten habe...

Es wird einige Zeit dauern, bis ich das alles durchgesehen habe, zumal ich momentan etwas weniger Zeit fürs OU investieren kann als sonst.

Wenn ich es richtig verstehe, treten die Diskrepanzen zwar systematisch, aber eher sporadisch, in Verbindung mit den EulaFiles, auf.
Dadurch können wohl Updates fälschlicherweise als "superseded" ausgefiltert werden, richtig?
Möglicherweise wurden auch durch diesen Effekt Einträge in der Datei "ExcludeList-superseded-exclude.txt" nötig, die ja glücklicherweise recht übersichtlich ist.

Ich werde mich noch einmal mit diesen Berechnungen beschäftigen, aber es kann, wie gesagt, etwas dauern.

Vielen Dank nochmal und viele Grüße,
Torsten
WSUSUpdateAdmin
Administrator
 
Posts: 2245
Joined: 07.07.2009, 14:38

Korrekturen (Teil 7)

Postby hbuhrmester » 07.08.2015, 14:04

Bei der Berechnung der Datei ValidSupersededRevisionIds.txt muss noch eine Korrektur gemacht werden: Bundle-Records können ein Element "SupersededBy" mit einer oder mehreren RevisionIds enthalten, doch manchmal existieren diese RevisionIds überhaupt nicht!

Zum Beispiel beschreibt der folgende Bundle-Report Updates für Windows 7:

Code: Select all
    <Update CreationDate="2013-02-12T18:00:00Z" DefaultLanguage="en" UpdateId="2b9685d2-cf2d-474e-b0c7-07cfe9a858b9" RevisionNumber="201" RevisionId="7053294" IsLeaf="true" IsBundle="true">
      <Categories>
        <Category Type="Company" Id="56309036-4c77-4dd9-951a-99ee9c246a94"/>
        <Category Type="Product" Id="bfe5b177-a086-47a0-b102-097e4fa1f807"/>
        <Category Type="Product" Id="fdfe8200-9d98-44ba-a12a-772282bf60ef"/>
        <Category Type="Product" Id="f4b9c883-f4db-4fb5-b204-3343c11fa021"/>
        <Category Type="ProductFamily" Id="6964aab4-c5b5-43bd-a17d-ffb4346a8e1d"/>
        <Category Type="UpdateClassification" Id="0fa1201d-4330-4fa8-8ae9-b877473b6441"/>
      </Categories>
      <Prerequisites>
        <UpdateId Id="ffedbe02-187f-4a17-aefc-605f4c44ffbc"/>
        <UpdateId Id="59653007-e2e9-4f71-8525-2ff588527978"/>
        <Or>
          <UpdateId Id="8998699c-434c-4222-b880-855ea4421d2c"/>
          <UpdateId Id="d7f1d4f3-8c9b-4ca5-964a-ffb09b8ef369"/>
          <UpdateId Id="28eb9ce9-b17c-4a99-904a-88214399ac5e"/>
        </Or>
        <UpdateId Id="0fa1201d-4330-4fa8-8ae9-b877473b6441"/>
        <Or>
          <UpdateId Id="bfe5b177-a086-47a0-b102-097e4fa1f807"/>
          <UpdateId Id="fdfe8200-9d98-44ba-a12a-772282bf60ef"/>
          <UpdateId Id="f4b9c883-f4db-4fb5-b204-3343c11fa021"/>
        </Or>
      </Prerequisites>
      <SupersededBy>
        <Revision Id="13941260"/>
        <Revision Id="16506826"/>
      </SupersededBy>
    </Update>


Doch die beiden angegebenen superseding RevisionIds "13941260" und "16506826" existieren nicht. Das muss ein Bug in der Datei package.xml sein.

Die Korrektur erfolgt in drei Schritten:

  1. Aus superseded Bundle-Records werden die Paare aus superseding und superseded RevisionIds extrahiert.
  2. Eine Liste mit allen existierenden Bundle-RevisionIds wird erstellt.
  3. Die erste Liste wird mit der zweiten abgeglichen. Dadurch werden die superseding RevisionIds validiert, aber gleichzeitig auch die verbundenen superseded RevisionIds.

Das perfekte Werkzeug für diese Art von Abgleich ist "join":
https://en.wikipedia.org/wiki/Join_%28Unix%29

Die GNU-Version von join gehört zu den Core Utilities:
https://en.wikipedia.org/wiki/GNU_Core_Utilities

Anders als grep und FindStr.exe sucht join nicht zeilenweise nach Übereinstimmungen, sondern versteht die Unterteilung von Datensätzen in Datenfelder, wie sie zum Beispiel in CSV-formatierten Textdateien vorliegen.

Üblicherweise werden die ersten Felder zweier Dateien miteinander verbunden. Bei übereinstimmenden Werten in beiden Dateien wird das erste Feld ausgegeben, und dann die restlichen Felder beider Dateien. Man kann die Ausgabe aber auch steuern, um zum Beispiel nur das zweite Feld der ersten Datei auszugeben.

Es gibt dazu drei Vorbedingungen:
  1. Beide Dateien müssen nach dem verbindenden Feld sortiert sein. Dabei setzt join anscheinend die Standard-Sortierung "C" voraus, währende GNU sort die Locale berücksichtigt und bei Zahlen eine "natürliche" Sortierung versucht. Eine natürliche Sortierung könnte bedeuten, dass 11 vor 100 kommt, und 101 vor 1000. Aber das verträgt sich anscheinend nicht mit join.
  2. Üblicherweise ist das verbindende Feld das erste Feld in beiden Dateien. Deshalb ist es manchmal sinnvoll, die Reihenfolge der Felder zu ändern: in der Datei BundledUpdateRevisionAndFileIds.txt sollte die Bundle-RevisionId das erste Feld sein.
  3. Man muss überall dasselbe Trennzeichen verwenden, also zum Beispiel überall Kommas.

Damit sieht der Ansatz so aus (bis zur Bestimmung aller superseded URLs):

Code: Select all
#!/bin/bash

# Sample implementation for the calculation of superseded updates.
export LC_ALL=C

xmlstarlet select -N __="http://schemas.microsoft.com/msus/2004/02/OfflineSync" \
    --text \
    --template \
    --match "__:OfflineSyncPackage/__:Updates/__:Update/__:SupersededBy/__:Revision" \
    --output "#" --value-of "@Id" --output "#," \
    --output "#" --value-of "../../@RevisionId" --output "#" \
    --nl \
    package.xml |
    sort --unique \
    > superseding-and-superseded-revision-ids.txt

xmlstarlet select -N __="http://schemas.microsoft.com/msus/2004/02/OfflineSync" \
    --text \
    --template \
    --match "__:OfflineSyncPackage/__:Updates/__:Update[@IsBundle='true']" \
    --output "#" --value-of "@RevisionId" --output "#" \
    --nl \
   package.xml |
   sort --unique \
    > existing-bundle-revision-ids.txt

join -t ',' -o 1.2 \
    superseding-and-superseded-revision-ids.txt \
    existing-bundle-revision-ids.txt |
    sort --unique \
    > ValidSupersededRevisionIds.txt

xmlstarlet select -N __="http://schemas.microsoft.com/msus/2004/02/OfflineSync" \
    --text \
    --template \
    --match "__:OfflineSyncPackage/__:Updates/__:Update/__:BundledBy/__:Revision" \
    --output "#" --value-of "@Id" --output "#," \
    --output "#" --value-of "../../@RevisionId" --output "#," \
    --value-of "../../__:PayloadFiles/__:File/@Id" \
    --nl \
    package.xml |
    sort --unique \
    > BundledUpdateRevisionAndFileIds.txt

join -t ',' -o 2.3 \
    ValidSupersededRevisionIds.txt \
    BundledUpdateRevisionAndFileIds.txt |
    sort --unique \
    > SupersededFileIds.txt

xmlstarlet select -N __="http://schemas.microsoft.com/msus/2004/02/OfflineSync" \
    --text \
    --template \
    --match "__:OfflineSyncPackage/__:FileLocations/__:FileLocation" \
    --if "contains(@Url, 'http://') and contains(@Url, '/update/software/secu/') and not(contains(@Url, 'MUI') or contains(@Url, 'Mui') or contains(@Url, 'mui')) and (contains(@Url, '.cab') or contains(@Url, '.exe'))" \
        --value-of "@Id" --output "," \
        --value-of "@Url" --nl \
    --break \
    package.xml |
    sort --unique \
    > UpdateCabExeIdsAndLocations.txt

join -t ',' -o 2.2 \
    SupersededFileIds.txt \
    UpdateCabExeIdsAndLocations.txt \
    > ExcludeListLocations-superseded-all.txt
hbuhrmester
 
Posts: 525
Joined: 11.10.2013, 20:59

Übersetzung in XSLT-Dateien (Teil 8)

Postby hbuhrmester » 07.08.2015, 15:13

Für eine Übersetzung der xmlstarlet-select-Befehle in der Beispielimplementation braucht man nun vier XSLT-Dateien:

extract-superseding-and-superseded-revision-ids.xsl
Code: Select all
<?xml version="1.0"?>
<!-- Author: H. Buhrmester -->
<!-- Filename: extract-superseding-and-superseded-revision-ids.xsl -->
<!-- This file extracts the following fields: -->
<!-- Field 1: Superseding Bundle RevisionId (unverified; in rare cases this RevisionId may not exist) -->
<!-- Field 2: Superseded Bundle RevisionId -->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:__="http://schemas.microsoft.com/msus/2004/02/OfflineSync" version="1.0">
  <xsl:output omit-xml-declaration="yes" indent="no" method="text" />
  <xsl:template match="/">
    <xsl:for-each select="__:OfflineSyncPackage/__:Updates/__:Update/__:SupersededBy/__:Revision">
      <xsl:text>#</xsl:text>
      <xsl:value-of select="@Id" />
      <xsl:text>#,#</xsl:text>
      <xsl:value-of select="../../@RevisionId" />
      <xsl:text>#</xsl:text>
      <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>


extract-existing-bundle-revision-ids.xsl
Code: Select all
<?xml version="1.0"?>
<!-- Author: H. Buhrmester -->
<!-- Filename: extract-existing-bundle-revision-ids.xsl -->
<!-- This file extracts the following fields: -->
<!-- Field 1: Existing Bundle RevisionId -->
<!-- Note: This is one of the simplest XSLT files and may serve as a template for other files. -->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:__="http://schemas.microsoft.com/msus/2004/02/OfflineSync" version="1.0">
  <xsl:output omit-xml-declaration="yes" indent="no" method="text" />
  <xsl:template match="/">
    <xsl:for-each select="__:OfflineSyncPackage/__:Updates/__:Update[@IsBundle='true']">
      <xsl:text>#</xsl:text>
      <xsl:value-of select="@RevisionId" />
      <xsl:text>#</xsl:text>
      <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>


extract-update-revision-and-file-ids.xsl
Code: Select all
<?xml version="1.0"?>
<!-- Author: H. Buhrmester -->
<!-- Filename: extract-update-revision-and-file-ids.xsl -->
<!-- This file extracts the following fields: -->
<!-- Field 1: Bundle RevisionId -->
<!-- Field 2: Update RevisionId -->
<!-- Field 3: File Id of the PayloadFile -->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:__="http://schemas.microsoft.com/msus/2004/02/OfflineSync" version="1.0">
  <xsl:output omit-xml-declaration="yes" indent="no" method="text" />
  <xsl:template match="/">
    <xsl:for-each select="__:OfflineSyncPackage/__:Updates/__:Update/__:BundledBy/__:Revision">
      <xsl:text>#</xsl:text>
      <xsl:value-of select="@Id" />
      <xsl:text>#,#</xsl:text>
      <xsl:value-of select="../../@RevisionId" />
      <xsl:text>#,</xsl:text>
      <xsl:value-of select="../../__:PayloadFiles/__:File/@Id" />
      <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>


extract-update-cab-exe-ids-and-locations.xsl
Code: Select all
<?xml version="1.0"?>
<!-- Author: H. Buhrmester -->
<!-- Filename: extract-update-cab-exe-ids-and-locations.xsl -->
<!-- This file extracts the following fields: -->
<!-- Field 1: File Id -->
<!-- Field 2: File Url (Location) -->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:__="http://schemas.microsoft.com/msus/2004/02/OfflineSync" version="1.0">
  <xsl:output omit-xml-declaration="yes" indent="no" method="text" />
  <xsl:template match="/">
    <xsl:for-each select="__:OfflineSyncPackage/__:FileLocations/__:FileLocation">
      <xsl:if test="contains(@Url, 'http://') and contains(@Url, '/update/software/secu/') and not(contains(@Url, 'MUI') or contains(@Url, 'Mui') or contains(@Url, 'mui')) and (contains(@Url, '.cab') or contains(@Url, '.exe'))">
        <xsl:value-of select="@Id" />
        <xsl:text>,</xsl:text>
        <xsl:value-of select="@Url" />
        <xsl:text>&#10;</xsl:text>
      </xsl:if>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>


Damit vereinfacht sich die Beispielimplementierung zu:

Code: Select all
#!/bin/bash

# Sample implementation for the calculation of superseded updates.
export LC_ALL=C

xmlstarlet transform \
    extract-superseding-and-superseded-revision-ids.xsl \
    package.xml |
    sort --unique \
    > superseding-and-superseded-revision-ids.txt

xmlstarlet transform \
    extract-existing-bundle-revision-ids.xsl \
    package.xml |
    sort --unique \
    > existing-bundle-revision-ids.txt

join -t ',' -o 1.2 \
    superseding-and-superseded-revision-ids.txt \
    existing-bundle-revision-ids.txt |
    sort --unique \
    > ValidSupersededRevisionIds.txt

xmlstarlet transform \
    extract-update-revision-and-file-ids.xsl \
    package.xml |
    sort --unique \
    > BundledUpdateRevisionAndFileIds.txt

join -t ',' -o 2.3 \
    ValidSupersededRevisionIds.txt \
    BundledUpdateRevisionAndFileIds.txt |
    sort --unique \
    > SupersededFileIds.txt

xmlstarlet transform \
    extract-update-cab-exe-ids-and-locations.xsl \
    package.xml |
    sort --unique \
    > UpdateCabExeIdsAndLocations.txt

join -t ',' -o 2.2 \
    SupersededFileIds.txt \
    UpdateCabExeIdsAndLocations.txt \
    > ExcludeListLocations-superseded-all.txt
hbuhrmester
 
Posts: 525
Joined: 11.10.2013, 20:59

Unterschiede in den Ergebnissen (Teil 9)

Postby hbuhrmester » 08.08.2015, 10:22

Nach der Neuberechnung der superseded Updates gibt letztlich nur wenige Unterschiede in den Ergebnissen. Alle Unterschiede betreffen ältere Office-Updates.

Wenn man Office-Updates in den Sprachen Deutsch und Englisch auswählt, werden zehn Dateien zusätzlich heruntergeladen:

Code: Select all
client/ofc/deu:
works432_02d3c8fcac7fcb41f50be2ef48e692899cbc4fb8.cab

client/ofc/enu:
works432_14bcfcd89ea6731fcb5a7b4f64305b8708c1680a.cab

client/ofc/glb:
cdo10_61fbcbecc6f2f6802f05fd55cfc193e8dfb2b9cc.cab
excel_6b6c723f3a4be24058b0b8e73f671f5cbd1854bb.cab
mspub_b0c50f8d10570feb5ef5cab0bc28ea0a342741b9.cab
owc10_57d5689f99443813055bca3a58eca2df2ab5d048.cab
powerpnt_7912df405229fb025e8ca912ddf746abb20d30b6.cab
shared_9a730caaf3cd5a3187388bd94356e1f368b3bc5a.cab
vbe6_1b380133af898cf956d8b39992761eac3f86137f.cab
winword_bd3b0b18163e52e2b7edb499ebcfcca7414c5253.cab


Das wären dann geeignete Kandidaten für die Aufnahme in die Datei ExcludeList-superseded-exclude.txt. Bis jetzt hat aber niemand diese Dateien wirklich vermisst.

Drei Dateien werden nicht mehr heruntergeladen:

Code: Select all
client/ofc/glb:
mspub_7f0b88ad21cba0cba8f24f5f35145bf32a6206e0.cab
powerpnt_40d0f76fd35e602ad6a5811aecc492f02142d1be.cab
shared_069b42275e221c4305f58ff8ca67b6cdf84c161c.cab


Die Dateien

Code: Select all
client/ofc/UpdateTable-ofc-deu.csv
client/ofc/UpdateTable-ofc-enu.csv
client/ofc/UpdateTable-ofc-glb.csv


bleiben komischerweise unverändert.

Bei den Windows-Downloads gibt es keine Änderungen.


Wenn man die drei Dateien, die jetzt nicht mehr heruntergeladen werden, zurückverfolgt von den Dateinamen zu den Update-Records, und von den Update-Records zu den Bundle-Records, dann kann man ein Muster erkennen:
  • Die Bundle-Records sind alle als superseded gekennzeichnet, d.h. sie haben ein Element vom Typ "SupersededBy". Dann sollten die dazugehörigen Dateien auch nicht mehr heruntergeladen werden.
  • Gleichzeitig enthalten die Bundle-Records mehrere EulaFiles, die anscheinend verhindern, dass die Bundle-RevisionIds und die folgenden Update-RevisionIds richtig zugeordnet werden.

Details zu mspub_7f0b88ad21cba0cba8f24f5f35145bf32a6206e0.cab
Code: Select all
    <Update CreationDate="2008-02-12T18:00:00Z" DefaultLanguage="en" UpdateId="5bb91925-870c-4c8c-a908-142b9ba60aa0" RevisionNumber="101" RevisionId="4977392" IsLeaf="true" IsBundle="true">
      <EulaFiles>
        <File Id="Ay76ltL3uLYn9HARM3UnvyAJ41o=">
          <Language Name="sv"/>
        </File>
        <File Id="A34rJImU95We0Ndwz+QpumTcTco=">
          <Language Name="tr"/>
        </File>
        <File Id="BdB1kDyqV8bwpkBhosWWuMYBwxE=">
          <Language Name="fi"/>
        </File>
        <File Id="Bgwesd4/J+QCXI42S0HmhmtX6OA=">
          <Language Name="zh-tw"/>
        </File>
        <File Id="CHfuV4tjO1R63u44bgTFcOUNM9s=">
          <Language Name="es"/>
        </File>
        <File Id="GKlp5AmA5qHqFnSCV285nSilt28=">
          <Language Name="ru"/>
        </File>
        <File Id="I75VQzqYF4TUw9aYpJSTAvULOYo=">
          <Language Name="hu"/>
        </File>
        <File Id="M7DaaoCYhqnk0f0QoeBgvkgkUa8=">
          <Language Name="ja"/>
          <Language Name="ja-nec"/>
        </File>
        <File Id="SiKJ5P8NTyyedk8urSjMaVMzvDU=">
          <Language Name="he"/>
        </File>
        <File Id="XevBwNlTI277C4g96GuyYUf0xmw=">
          <Language Name="el"/>
        </File>
        <File Id="YDkx/jfu7qrZ100PZuoW5gZ5X20=">
          <Language Name="pt"/>
        </File>
        <File Id="ehJntJ4C7Uaoz7MrhH5OtdOk+po=">
          <Language Name="no"/>
        </File>
        <File Id="f3IKz2lJJLSw2JNmOrEHvEV0BOs=">
          <Language Name="cs"/>
        </File>
        <File Id="nOh+RhQp7nszwzRuwDkTLpwq22k=">
          <Language Name="pt-br"/>
        </File>
        <File Id="nemypMOpTallaJaw0tUFeuJQnh8=">
          <Language Name="de"/>
        </File>
        <File Id="rKUV9NrYBUeMDv3uQ8dOD0LqUX4=">
          <Language Name="en"/>
        </File>
        <File Id="wyBkQir7i9lorJ28yosEyioL0eQ=">
          <Language Name="nl"/>
        </File>
        <File Id="xsFntGJ8UY4BsONpwPfmNRipHrc=">
          <Language Name="pl"/>
        </File>
        <File Id="yuswM1wv9PLGKKhpT3zOElG359Q=">
          <Language Name="ko"/>
        </File>
        <File Id="0VNpr5uA+2UTBCtX+4KblYq3/aU=">
          <Language Name="it"/>
        </File>
        <File Id="0sikto9VRSMpuLJTkTe0IcJ2RIo=">
          <Language Name="da"/>
        </File>
        <File Id="36FCMnf02A2YII0PfEvVYo0OriE=">
          <Language Name="zh-cn"/>
        </File>
        <File Id="4jftCiFPp52gXSK33IOFAwJyP0Q=">
          <Language Name="ar"/>
        </File>
        <File Id="6uRTFlUoetrBcx/urQPksLWSXfY=">
          <Language Name="fr"/>
        </File>
      </EulaFiles>
      <Categories>
        <Category Type="Company" Id="56309036-4c77-4dd9-951a-99ee9c246a94"/>
        <Category Type="Product" Id="6248b8b1-ffeb-dbd9-887a-2acf53b09dfe"/>
        <Category Type="ProductFamily" Id="477b856e-65c4-4473-b621-a8b230bb70d9"/>
        <Category Type="UpdateClassification" Id="0fa1201d-4330-4fa8-8ae9-b877473b6441"/>
      </Categories>
      <Prerequisites>
        <UpdateId Id="0fa1201d-4330-4fa8-8ae9-b877473b6441"/>
        <UpdateId Id="6248b8b1-ffeb-dbd9-887a-2acf53b09dfe"/>
      </Prerequisites>
      <SupersededBy>
        <Revision Id="1270729"/>
        <Revision Id="3700197"/>
        <Revision Id="4080759"/>
        <Revision Id="4081016"/>
        <Revision Id="4081276"/>
        <Revision Id="4977499"/>
        <Revision Id="4981410"/>
        <Revision Id="4981836"/>
      </SupersededBy>
    </Update>

    <Update CreationDate="2012-04-05T21:22:42Z" DefaultLanguage="en" UpdateId="e78694a7-7ab1-4542-9c33-4abb9c878b51" RevisionNumber="101" RevisionId="4977391" DeploymentAction="Bundle" IsLeaf="true">
      <PayloadFiles>
        <File Id="fwuIrSHLoMuo8k9fNRRb8ypiBuA="/>
      </PayloadFiles>
      <Prerequisites>
        <UpdateId Id="6248b8b1-ffeb-dbd9-887a-2acf53b09dfe"/>
      </Prerequisites>
      <BundledBy>
        <Revision Id="4977392"/>
      </BundledBy>
    </Update>

    <FileLocation Id="fwuIrSHLoMuo8k9fNRRb8ypiBuA=" Url="http://www.download.windowsupdate.com/msdownload/update/software/secu/2008/02/mspub_7f0b88ad21cba0cba8f24f5f35145bf32a6206e0.cab"/>


Details zu powerpnt_40d0f76fd35e602ad6a5811aecc492f02142d1be.cab
Code: Select all
    <Update CreationDate="2010-02-09T18:00:00Z" DefaultLanguage="en" UpdateId="18ba006c-943e-4407-9b72-dd3685f5c9d9" RevisionNumber="101" RevisionId="4981308" IsLeaf="true" IsBundle="true">
      <EulaFiles>
        <File Id="Ay76ltL3uLYn9HARM3UnvyAJ41o=">
          <Language Name="sv"/>
        </File>
        <File Id="A34rJImU95We0Ndwz+QpumTcTco=">
          <Language Name="tr"/>
        </File>
        <File Id="BdB1kDyqV8bwpkBhosWWuMYBwxE=">
          <Language Name="fi"/>
        </File>
        <File Id="Bgwesd4/J+QCXI42S0HmhmtX6OA=">
          <Language Name="zh-tw"/>
        </File>
        <File Id="CHfuV4tjO1R63u44bgTFcOUNM9s=">
          <Language Name="es"/>
        </File>
        <File Id="GKlp5AmA5qHqFnSCV285nSilt28=">
          <Language Name="ru"/>
        </File>
        <File Id="I75VQzqYF4TUw9aYpJSTAvULOYo=">
          <Language Name="hu"/>
        </File>
        <File Id="M7DaaoCYhqnk0f0QoeBgvkgkUa8=">
          <Language Name="ja"/>
          <Language Name="ja-nec"/>
        </File>
        <File Id="SiKJ5P8NTyyedk8urSjMaVMzvDU=">
          <Language Name="he"/>
        </File>
        <File Id="XevBwNlTI277C4g96GuyYUf0xmw=">
          <Language Name="el"/>
        </File>
        <File Id="YDkx/jfu7qrZ100PZuoW5gZ5X20=">
          <Language Name="pt"/>
        </File>
        <File Id="ehJntJ4C7Uaoz7MrhH5OtdOk+po=">
          <Language Name="no"/>
        </File>
        <File Id="f3IKz2lJJLSw2JNmOrEHvEV0BOs=">
          <Language Name="cs"/>
        </File>
        <File Id="nOh+RhQp7nszwzRuwDkTLpwq22k=">
          <Language Name="pt-br"/>
        </File>
        <File Id="nemypMOpTallaJaw0tUFeuJQnh8=">
          <Language Name="de"/>
        </File>
        <File Id="rKUV9NrYBUeMDv3uQ8dOD0LqUX4=">
          <Language Name="en"/>
        </File>
        <File Id="wyBkQir7i9lorJ28yosEyioL0eQ=">
          <Language Name="nl"/>
        </File>
        <File Id="xsFntGJ8UY4BsONpwPfmNRipHrc=">
          <Language Name="pl"/>
        </File>
        <File Id="yuswM1wv9PLGKKhpT3zOElG359Q=">
          <Language Name="ko"/>
        </File>
        <File Id="0VNpr5uA+2UTBCtX+4KblYq3/aU=">
          <Language Name="it"/>
        </File>
        <File Id="0sikto9VRSMpuLJTkTe0IcJ2RIo=">
          <Language Name="da"/>
        </File>
        <File Id="36FCMnf02A2YII0PfEvVYo0OriE=">
          <Language Name="zh-cn"/>
        </File>
        <File Id="4jftCiFPp52gXSK33IOFAwJyP0Q=">
          <Language Name="ar"/>
        </File>
        <File Id="6uRTFlUoetrBcx/urQPksLWSXfY=">
          <Language Name="fr"/>
        </File>
      </EulaFiles>
      <Categories>
        <Category Type="Company" Id="56309036-4c77-4dd9-951a-99ee9c246a94"/>
        <Category Type="Product" Id="6248b8b1-ffeb-dbd9-887a-2acf53b09dfe"/>
        <Category Type="ProductFamily" Id="477b856e-65c4-4473-b621-a8b230bb70d9"/>
        <Category Type="UpdateClassification" Id="0fa1201d-4330-4fa8-8ae9-b877473b6441"/>
      </Categories>
      <Prerequisites>
        <UpdateId Id="0fa1201d-4330-4fa8-8ae9-b877473b6441"/>
        <UpdateId Id="6248b8b1-ffeb-dbd9-887a-2acf53b09dfe"/>
      </Prerequisites>
      <SupersededBy>
        <Revision Id="4046223"/>
        <Revision Id="4047407"/>
        <Revision Id="4047780"/>
        <Revision Id="4176430"/>
        <Revision Id="4214767"/>
        <Revision Id="4981737"/>
        <Revision Id="4981995"/>
        <Revision Id="4982011"/>
      </SupersededBy>
    </Update>

    <Update CreationDate="2012-04-05T22:49:38Z" DefaultLanguage="en" UpdateId="f32fbce9-5781-4db2-9c51-cf208532e252" RevisionNumber="101" RevisionId="4981307" DeploymentAction="Bundle" IsLeaf="true">
      <PayloadFiles>
        <File Id="QND3b9NeYCrWpYEa7MSS8CFC0b4="/>
      </PayloadFiles>
      <Prerequisites>
        <UpdateId Id="6248b8b1-ffeb-dbd9-887a-2acf53b09dfe"/>
      </Prerequisites>
      <BundledBy>
        <Revision Id="4981308"/>
      </BundledBy>
    </Update>

    <FileLocation Id="QND3b9NeYCrWpYEa7MSS8CFC0b4=" Url="http://download.windowsupdate.com/msdownload/update/software/secu/2010/01/powerpnt_40d0f76fd35e602ad6a5811aecc492f02142d1be.cab"/>


Details zu shared_069b42275e221c4305f58ff8ca67b6cdf84c161c.cab
Code: Select all
    <Update CreationDate="2010-02-09T18:00:00Z" DefaultLanguage="en" UpdateId="bae81b71-4aa7-483d-9062-83e1c2d7bf7e" RevisionNumber="101" RevisionId="4981310" IsLeaf="true" IsBundle="true">
      <EulaFiles>
        <File Id="Ay76ltL3uLYn9HARM3UnvyAJ41o=">
          <Language Name="sv"/>
        </File>
        <File Id="A34rJImU95We0Ndwz+QpumTcTco=">
          <Language Name="tr"/>
        </File>
        <File Id="BdB1kDyqV8bwpkBhosWWuMYBwxE=">
          <Language Name="fi"/>
        </File>
        <File Id="Bgwesd4/J+QCXI42S0HmhmtX6OA=">
          <Language Name="zh-tw"/>
        </File>
        <File Id="CHfuV4tjO1R63u44bgTFcOUNM9s=">
          <Language Name="es"/>
        </File>
        <File Id="GKlp5AmA5qHqFnSCV285nSilt28=">
          <Language Name="ru"/>
        </File>
        <File Id="I75VQzqYF4TUw9aYpJSTAvULOYo=">
          <Language Name="hu"/>
        </File>
        <File Id="M7DaaoCYhqnk0f0QoeBgvkgkUa8=">
          <Language Name="ja"/>
          <Language Name="ja-nec"/>
        </File>
        <File Id="SiKJ5P8NTyyedk8urSjMaVMzvDU=">
          <Language Name="he"/>
        </File>
        <File Id="XevBwNlTI277C4g96GuyYUf0xmw=">
          <Language Name="el"/>
        </File>
        <File Id="YDkx/jfu7qrZ100PZuoW5gZ5X20=">
          <Language Name="pt"/>
        </File>
        <File Id="ehJntJ4C7Uaoz7MrhH5OtdOk+po=">
          <Language Name="no"/>
        </File>
        <File Id="f3IKz2lJJLSw2JNmOrEHvEV0BOs=">
          <Language Name="cs"/>
        </File>
        <File Id="nOh+RhQp7nszwzRuwDkTLpwq22k=">
          <Language Name="pt-br"/>
        </File>
        <File Id="nemypMOpTallaJaw0tUFeuJQnh8=">
          <Language Name="de"/>
        </File>
        <File Id="rKUV9NrYBUeMDv3uQ8dOD0LqUX4=">
          <Language Name="en"/>
        </File>
        <File Id="wyBkQir7i9lorJ28yosEyioL0eQ=">
          <Language Name="nl"/>
        </File>
        <File Id="xsFntGJ8UY4BsONpwPfmNRipHrc=">
          <Language Name="pl"/>
        </File>
        <File Id="yuswM1wv9PLGKKhpT3zOElG359Q=">
          <Language Name="ko"/>
        </File>
        <File Id="0VNpr5uA+2UTBCtX+4KblYq3/aU=">
          <Language Name="it"/>
        </File>
        <File Id="0sikto9VRSMpuLJTkTe0IcJ2RIo=">
          <Language Name="da"/>
        </File>
        <File Id="36FCMnf02A2YII0PfEvVYo0OriE=">
          <Language Name="zh-cn"/>
        </File>
        <File Id="4jftCiFPp52gXSK33IOFAwJyP0Q=">
          <Language Name="ar"/>
        </File>
        <File Id="6uRTFlUoetrBcx/urQPksLWSXfY=">
          <Language Name="fr"/>
        </File>
      </EulaFiles>
      <Categories>
        <Category Type="Company" Id="56309036-4c77-4dd9-951a-99ee9c246a94"/>
        <Category Type="Product" Id="6248b8b1-ffeb-dbd9-887a-2acf53b09dfe"/>
        <Category Type="ProductFamily" Id="477b856e-65c4-4473-b621-a8b230bb70d9"/>
        <Category Type="UpdateClassification" Id="0fa1201d-4330-4fa8-8ae9-b877473b6441"/>
      </Categories>
      <Prerequisites>
        <UpdateId Id="0fa1201d-4330-4fa8-8ae9-b877473b6441"/>
        <UpdateId Id="6248b8b1-ffeb-dbd9-887a-2acf53b09dfe"/>
      </Prerequisites>
      <SupersededBy>
        <Revision Id="4046217"/>
        <Revision Id="4047389"/>
        <Revision Id="4047762"/>
        <Revision Id="4176418"/>
        <Revision Id="4981727"/>
        <Revision Id="4981989"/>
      </SupersededBy>
    </Update>

    <Update CreationDate="2012-04-05T22:49:42Z" DefaultLanguage="en" UpdateId="0eddd03f-530b-4299-9741-f170ba2936a1" RevisionNumber="101" RevisionId="4981309" DeploymentAction="Bundle" IsLeaf="true">
      <PayloadFiles>
        <File Id="BptCJ14iHEMF9Y/4yme2zfhMFhw="/>
      </PayloadFiles>
      <Prerequisites>
        <UpdateId Id="6248b8b1-ffeb-dbd9-887a-2acf53b09dfe"/>
      </Prerequisites>
      <BundledBy>
        <Revision Id="4981310"/>
      </BundledBy>
    </Update>

    <FileLocation Id="BptCJ14iHEMF9Y/4yme2zfhMFhw=" Url="http://download.windowsupdate.com/msdownload/update/software/secu/2010/01/shared_069b42275e221c4305f58ff8ca67b6cdf84c161c.cab"/>


Wenn man die Datei owc10_57d5689f99443813055bca3a58eca2df2ab5d048.cab zurückverfolgt zu den Bundle-Records, dann ist es bei dieser Datei genau anders herum:
  • Der Bundle-Record ist nicht superseded, die Dateien sind also noch gültig.
  • Wiederum verhindern die EulaFiles die richtige Zuordnung des Bundle-Records zu den nachfolgenden Update-Records.

Details zu owc10_57d5689f99443813055bca3a58eca2df2ab5d048.cab
Code: Select all
    <Update CreationDate="2009-08-11T17:00:00Z" DefaultLanguage="en" UpdateId="42c1601b-a2b5-4e98-8a6e-9d030998435d" RevisionNumber="106" RevisionId="4981153" IsLeaf="true" DownloadPriority="Low" IsBundle="true">
      <EulaFiles>
        <File Id="Ay76ltL3uLYn9HARM3UnvyAJ41o=">
          <Language Name="sv"/>
        </File>
        <File Id="A34rJImU95We0Ndwz+QpumTcTco=">
          <Language Name="tr"/>
        </File>
        <File Id="BdB1kDyqV8bwpkBhosWWuMYBwxE=">
          <Language Name="fi"/>
        </File>
        <File Id="Bgwesd4/J+QCXI42S0HmhmtX6OA=">
          <Language Name="zh-tw"/>
        </File>
        <File Id="CHfuV4tjO1R63u44bgTFcOUNM9s=">
          <Language Name="es"/>
        </File>
        <File Id="GKlp5AmA5qHqFnSCV285nSilt28=">
          <Language Name="ru"/>
        </File>
        <File Id="I75VQzqYF4TUw9aYpJSTAvULOYo=">
          <Language Name="hu"/>
        </File>
        <File Id="M7DaaoCYhqnk0f0QoeBgvkgkUa8=">
          <Language Name="ja"/>
          <Language Name="ja-nec"/>
        </File>
        <File Id="SiKJ5P8NTyyedk8urSjMaVMzvDU=">
          <Language Name="he"/>
        </File>
        <File Id="XevBwNlTI277C4g96GuyYUf0xmw=">
          <Language Name="el"/>
        </File>
        <File Id="YDkx/jfu7qrZ100PZuoW5gZ5X20=">
          <Language Name="pt"/>
        </File>
        <File Id="ehJntJ4C7Uaoz7MrhH5OtdOk+po=">
          <Language Name="no"/>
        </File>
        <File Id="f3IKz2lJJLSw2JNmOrEHvEV0BOs=">
          <Language Name="cs"/>
        </File>
        <File Id="nOh+RhQp7nszwzRuwDkTLpwq22k=">
          <Language Name="pt-br"/>
        </File>
        <File Id="nemypMOpTallaJaw0tUFeuJQnh8=">
          <Language Name="de"/>
        </File>
        <File Id="rKUV9NrYBUeMDv3uQ8dOD0LqUX4=">
          <Language Name="en"/>
        </File>
        <File Id="wyBkQir7i9lorJ28yosEyioL0eQ=">
          <Language Name="nl"/>
        </File>
        <File Id="xsFntGJ8UY4BsONpwPfmNRipHrc=">
          <Language Name="pl"/>
        </File>
        <File Id="yuswM1wv9PLGKKhpT3zOElG359Q=">
          <Language Name="ko"/>
        </File>
        <File Id="0VNpr5uA+2UTBCtX+4KblYq3/aU=">
          <Language Name="it"/>
        </File>
        <File Id="0sikto9VRSMpuLJTkTe0IcJ2RIo=">
          <Language Name="da"/>
        </File>
        <File Id="36FCMnf02A2YII0PfEvVYo0OriE=">
          <Language Name="zh-cn"/>
        </File>
        <File Id="4jftCiFPp52gXSK33IOFAwJyP0Q=">
          <Language Name="ar"/>
        </File>
        <File Id="6uRTFlUoetrBcx/urQPksLWSXfY=">
          <Language Name="fr"/>
        </File>
      </EulaFiles>
      <Categories>
        <Category Type="Company" Id="56309036-4c77-4dd9-951a-99ee9c246a94"/>
        <Category Type="Product" Id="6248b8b1-ffeb-dbd9-887a-2acf53b09dfe"/>
        <Category Type="ProductFamily" Id="477b856e-65c4-4473-b621-a8b230bb70d9"/>
        <Category Type="UpdateClassification" Id="0fa1201d-4330-4fa8-8ae9-b877473b6441"/>
      </Categories>
      <Prerequisites>
        <UpdateId Id="0fa1201d-4330-4fa8-8ae9-b877473b6441"/>
        <UpdateId Id="6248b8b1-ffeb-dbd9-887a-2acf53b09dfe"/>
      </Prerequisites>
    </Update>
   
    <Update CreationDate="2012-04-05T22:47:10Z" DefaultLanguage="en" UpdateId="23945ceb-ab9a-4647-9033-5ddb1d2c6cc5" RevisionNumber="106" RevisionId="4981152" DeploymentAction="Bundle" IsLeaf="true">
      <PayloadFiles>
        <File Id="V9Von5lEOBMFW8o6WOyi3yq10Eg="/>
      </PayloadFiles>
      <Prerequisites>
        <UpdateId Id="6248b8b1-ffeb-dbd9-887a-2acf53b09dfe"/>
      </Prerequisites>
      <BundledBy>
        <Revision Id="4981153"/>
      </BundledBy>
    </Update>
   
    <FileLocation Id="V9Von5lEOBMFW8o6WOyi3yq10Eg=" Url="http://download.windowsupdate.com/msdownload/update/software/secu/2009/08/owc10_57d5689f99443813055bca3a58eca2df2ab5d048.cab"/>

Vielleicht ist diese Datei noch am wichtigsten, da es in der Datei StaticDownloadLinks-ofc-glb.txt mehrere Einträge mit ähnlichen Pfaden gibt. Dann gehört owc10_57d5689f99443813055bca3a58eca2df2ab5d048.cab vielleicht mit dazu?


Fazit
Wenn ein Bundle-Record EulaFiles enthält, bekommen die nachfolgenden Update-Records eine falsche Bundle-RevisionId zugeordnet. Das kann sich anscheinend in beide Richtungen auswirken:
  • Gültige Dateien werden nicht mehr heruntergeladen.
  • Superseded Dateien werden heruntergeladen, obwohl sie nicht mehr benötigt werden.
hbuhrmester
 
Posts: 525
Joined: 11.10.2013, 20:59

Next

Return to Anregungen / Suggestions

Who is online

Users browsing this forum: No registered users and 73 guests