Announcement

Collapse
No announcement yet.

Assembly wurde nicht gefunden

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Assembly wurde nicht gefunden

    Hallo,
    nach einer Änderung in einer DLL (Delphi 2005 mit NET-FCL) klappt die Verknüpfung zwischen EXE und DLL nicht mehr, gleichgültig ob ich die DLL im GAC installiere oder lokal im Verzeichnis \Bin aufrufe.
    <b>Exception.Message</b> lautet:
    <i>"Datei- oder Assemblyname 'VS_Klassen' oder eine Abhängigkeit davon wurde nicht gefunden."</i>
    Als <b>Details der Exception</b> werden gemeldet:
    "=== Pre-bind state information ===
    LOG: DisplayName = VS_Klassen, Version=5.0.2320.19655, Culture=de-DE, PublicKeyToken=a81d510c00000000 (Fully-specified)
    LOG: Appbase = F:\VS_NET\bin\
    LOG: Initial PrivatePath = NULL
    Calling assembly : VS_Polis, Version=5.0.2320.19660, Culture=de-DE, PublicKeyToken=1b720cbd2c7186f9.
    ===
    LOG: Private path hint found in configuration file: Bin.
    LOG: Publisher policy file is not found.
    LOG: Host configuration file not found.
    LOG: Using machine configuration file f
    <b>VS_Polis.exe.config</b> enthält folgende Angaben:
    <configuration>
    <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <publisherPolicy apply="yes" />
    <probing privatePath="Bin" />
    <dependentAssembly>
    <assemblyIdentity name="VS_Klassen"
    publicKeyToken="1b720cbd2c7186f9"
    culture="de-DE" />
    </dependentAssembly>
    </assemblyBinding>
    </runtime>
    </configuration>
    Grundsätzlich ist mir bewusst, dass beim Aufruf der DLL alle Angaben - Version, Culture, Key - übereinstimmen müssen. Aber auch wenn ich in der config-Datei unter assemblyIdentity die Angaben ändere, bleibt das Problem bestehen.
    Deshalb habe ich - neben dem Hauptproblem, was eigentlich passiert ist und wie ich dies regeln kann - folgende zusätzliche Fragen:
    ** Ist beim Vergleich der Versionsnummer auch der letzte Bestandteil relevant? Muss ggf. die DLL nach jedem Rebuild neu in den GAC kopiert werden?
    ** Ist es deshalb beim Entwickler sinnvoller, auf den GAC für eigene Entwicklungen zu verzichten?
    ** Delphi bietet an, die Versionsnummer verkürzt "5.0.*" vorzugeben. Ist dies etwa ungünstig?
    ** Wieso zeigt die Fehlermeldung für die DLL einen anderen PublicKeyToken an als der Explorer? Für DLL und EXE habe ich die gleiche Schlüsseldatei .snk verwendet. Also müssten die Schlüssel doch gleich sein?
    ** Sucht NET bei dieser config-Datei vorrangig im GAC oder in \Bin?
    ** Worauf bezieht sich die Fehlermeldung "Publisher policy file"? Ist dabei der entsprechende Abschnitt der config-Datei gemeint oder was sonst?
    ** Welche config-Datei ist bei "Host configuration file" gemeint?
    ** Bei eigenen Entwicklungen kann ich natürlich auf den GAC verzichten. Ist dieser (also auch der <i>strong name</i>) aber nicht Voraussetzung für Registrierung als Managed Code?
    Leider haben mir die NET-Hilfe, Kosch's Crashkurs, das Forum und viele Versuche nicht geholfen. Wie komme ich weiter? Danke!
    Jürgen

  • #2
    Hallo,
    eine .NET-Assembly hat einen Namen, der aus gleich 4 Bestandteilen besteht: <br>
    1. Friendly Name (Dateiname ohne Erweiterung)
    2. Version Number (durch Punkt abgestrennte vierteilige Versionnummer)
    3. Culture Setting (Zeichenkette mit der Landeskodierung oder neutral für universellen Einsatz)
    4. Public Key (128 Byte mit dem öffentlichen Schlüsselteil) und ein 8-Byte Public Key Token.
    <br>
    Das Laden einer Assembly lässt sich in verschiedene Arbeitsschritte unterteilen. Zuerst sucht die CLR nach einer anwendungsspezifischen Konfigurations-Datei mit der Dateiendung <i>.config</i>. Wird diese gefunden, sucht die CLR dort nach Einträgen, die den Ladevorgang beeinflussen – wie zum Beispiel <i>CodeBaseHint</i>. Außerdem wird die Assembly auch im <i>AppBase</i>-Verzeichnis (also dem Installationsverzeichnis der aufrufenden Anwendung) gesucht. Nur dann, wenn die angeforderte DLL einen Strong Name besitzt, sucht die CLR auch im Global Assembly Cache. Ist auch dort keine passende Assembly aufzutreiben, berücksichtigt die CLR die vorgefundenen Versionsnummern-Policies, so dass ein „Umbiegen“ auf andere Versionsnummern unterstützt wird. Der Administrator des Rechnern hat über eine Versionsnummern-Policy (u.a. Publisher policy file, eine mit einem Strong Name versehene config-Datei im DLL-Format) die Möglichkeit, eine alternative Versionsnummer vorzuschreiben, die statt dessen genutzt werden soll. Hilft auch das nichts, so wirft die CLR in der Probing-Phase das Handtuch, was sich im Erscheinen eines Exception-Hinweisfensters äußert. <br>
    Das .NET Framework stellt das <i>Assembly Binding Log Viewer Utility</i> (FUSLOGVW.EXE) zur Verfügung, um das Fehlerprotokoll in der ausführlichen Art anzuzeigen.
    <br>
    Wenn eine Assembly die Versionsnummer (egal, an welcher Stelle ändert), muss auch der Client seinen Verweis im Manifest aktualisieren (Fall A) oder die Versionsnummer über einen der unterstützten Weg umgebogen (Fall B) werden. Die IDE von Visual Studio 2005 ist so clever, den Fall A automatisch hinter den Kulissen auszuführen, wenn der Client neu kompiliert wird. Der Fall B könnte so aussehen - der <b>bindingRedirect</b>-Eintrag leitet die Versionsnummer um:
    <pre>
    <div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border-top: windowtext 1pt solid; padding-top: 0pt; border-left: windowtext 1pt solid; padding-left: 0pt; border-right: windowtext 1pt solid; padding-right: 0pt; border-bottom: windowtext 1pt solid; padding-bottom: 0pt;"><p style="margin: 0px;"><span style="color: blue;">&lt;?</span><span style="color: maroon;">xml</span><span style="color: blue;"> </span><span style="color: red;">version</span><span style="color: blue;">=</span>"<span style="color: blue;">1.0</span>"<span style="color: blue;">?&gt;</span></p><p style="margin: 0px;"><span style="color: blue;">&lt;</span><span style="color: maroon;">configuration</span><span style="color: blue;">&gt;</span></p><p style="margin: 0px;"><span style="color: blue;">&nbsp; &lt;</span><span style="color: maroon;">runtime</span><span style="color: blue;">&gt;</span></p><p style="margin: 0px;"><span style="color: blue;">&nbsp; &nbsp; &lt;</span><span style="color: maroon;">assemblyBinding</span><span style="color: blue;"> </span><span style="color: red;">xmlns</span><span style="color: blue;">=</span>"<span style="color: blue;">urn:schemas-microsoft-com:asm.v1</span>"<span style="color: blue;">&gt;</span></p><p style="margin: 0px;"><span style="color: blue;">&nbsp; &nbsp; &nbsp; &lt;</span><span style="color: maroon;">probing</span><span style="color: blue;"> </span><span style="color: red;">privatePath</span><span style="color: blue;">=</span>"<span style="color: blue;">Bin</span>"<span style="color: blue;"> /&gt;</span></p><p style="margin: 0px;"><span style="color: blue;">&nbsp; &nbsp; &nbsp; &lt;</span><span style="color: maroon;">dependentAssembly</span><span style="color: blue;">&gt;</span></p><p style="margin: 0px;"><span style="color: blue;">&nbsp; &nbsp; &nbsp; &nbsp; &lt;</span><span style="color: maroon;">assemblyIdentity</span><span style="color: blue;"> </span><span style="color: red;">name</span><span style="color: blue;">=</span>"<span style="color: blue;">OSProbingDemoLib</span>"<span style="color: blue;"> </span><span style="color: red;">publicKeyToken</span><span style="color: blue;">=</span>"<span style="color: blue;">d0ac782f480cdd54</span>"<span style="color: blue;"> </span><span style="color: red;">culture</span><span style="color: blue;">=</span>"<span style="color: blue;">de-DE</span>"<span style="color: blue;">/&gt;</span></p><p style="margin: 0px;"><span style="color: blue;">&nbsp; &nbsp; &nbsp; &nbsp; &lt;</span><span style="color: maroon;">publisherPolicy</span><span style="color: blue;"> </span><span style="color: red;">apply</span><span style="color: blue;">=</span>"<span style="color: blue;">no</span>"<span style="color: blue;"> /&gt;</span></p><p style="margin: 0px;"><span style="color: blue;">&nbsp; &nbsp; &nbsp; &nbsp; &lt;</span><span style="color: maroon;">bindingRedirect</span><span style="color: blue;"> </span><span style="color: red;">oldVersion</span><span style="color: blue;">=</span>"<span style="color: blue;">1.2.0.0</span>"<span style="color: blue;"> </span><span style="color: red;">newVersion</span><span style="color: blue;">=</span>"<span style="color: blue;">1.3.0.0</span>"<span style="color: blue;"> /&gt;</span></p><p style="margin: 0px;"><span style="color: blue;">&nbsp; &nbsp; &nbsp; &lt;/</span><span style="color: maroon;">dependentAssembly</span><span style="color: blue;">&gt;</span></p><p style="margin: 0px;"><span style="color: blue;">&nbsp; &nbsp; &lt;/</span><span style="color: maroon;">assemblyBinding</span><span style="color: blue;">&gt;</span></p><p style="margin: 0px;"><span style="color: blue;">&nbsp; &lt;/</span><span style="color: maroon;">runtime</span><span style="color: blue;">&gt;</span></p><p style="margin: 0px;"><span style="color: blue;">&lt;/</span><span style="color: maroon;">configuration</span><span style="color: blue;">&gt;</span></p></div>
    </pre&gt

    Comment


    • #3
      Danke, Herr Kosch,
      Ihre Erläuterungen - über den "Crashkurs" und andere Hinweise hier im Forum hinaus - haben mir etwas weitergeholfen.
      Auf den <u>GAC</u> verzichtet man in einer "normalen" Anwendung wohl lieber.
      Die automatische <u>Versionsnummerierung</u> von Delphi wird aus praktischen Gründen ebenfalls besser abgeschaltet.
      Die <u>Details der Exception</u> waren doch nicht ausreichend (wie ich mir eingebildet hatte); Ihr Hinweis auf <u>Fusion Log View</u> war insofern wichtig, als die DLL im Verzeichnis \Bin\de-DE gesucht wurde. Daraus ziehe ich den Schluss, dass die <u>CultureInfo</u> nur dann gesetzt werden sollte, wenn tatsächlich verschiedene Versionen vorgesehen sind.
      Ihre Erläuterung <i>Der Administrator des Rechnern hat über eine Versionsnummern-Policy ...</i> hat mir klar gemacht, dass und warum zumindest in meiner Situation <u>publisherPolicy apply="no" </u> gesetzt werden sollte.
      Damit habe ich wieder Zugriff auf meine DLL.
      Mit <b>Public Key</b> komme ich aber nicht weiter:
      ** Wenn ich zuerst die DLL und dann die EXE kompiliere, kennt die EXE den erwarteten PublicKeyToken der DLL. Diesen kann ich (siehe Crashkurs) durch ILDASM auslesen. Aber wenn ich den dort aufgeführten Wert in die config-Datei schreibe, gibt es die Fehlermeldung "mismatch public key token".
      ** Ist ein anderer Weg vorgesehen, den PublicKeyToken festzustellen, der in der config-Datei unter <dependentAssembly / <assemblyIdentity> einzutragen ist?
      ** Ergänzende Frage: Ist der PublicKeyToken der EXE an irgendeiner Stelle von Bedeutung? Wie kann dieser festgestellt werden?
      Danke für weitere Hilfe!
      Jürgen Thoma

      Comment


      • #4
        Hallo,

        &gt;..gibt es die Fehlermeldung "mismatch public key token".

        hier würde ich zuerst prüfen, ob das der "alte" Bug »Delphi.NET legt einen falschen PUBLIC KEY TOKEN im Manifest ab« ist (siehe <i><a href="/webx?50@@.4a871f46/11">Andreas Kosch "Der Delphi 2005-Streichelzoo" 08.02.2005 16:13</a></i>).
        &#10

        Comment


        • #5
          Ach je, sollte ich diesen Bug immer noch haben?
          Update 3 wurde im Sommer 2005 installiert; bds.exe hat Version 9.0.1882.30496.
          Kann ich den PublicKeyToken z.B. mit einem Hex-Viewer direkt ablesen? Ist es sinnvoll, stattdessen Borland-C# zu verwenden (zum jetzigen Zeitpunkt wäre mir dies noch möglich, auch wenn die andere Schreibweise von C# natürlich Umstellungsprobleme verursacht)?
          Danke!
          Jürgen Thoma

          Comment


          • #6
            Guten Tag,

            ich bin auf diesen Threat gestossen und habe das selbe Problem. Ich suche seit Stunden und weiß nicht mehr ein und aus. Ich hatte eine Projektmappe erstellt mit mehreren Projekten. Jetzt habe ich die einzelnen Projekte aufgeteilt.

            "Die Assembly \"ClientApplicationDocumentBase, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null\" kann nicht gefunden werden."

            Jetzt kommt diese Fehlermeldung.

            Ich habe folgende Dateien:

            bin32.dll Darin sind mein Methoden für Serializierung/Deserialisierung
            base32.dll darin sind meine ganzen Variablen für ein Objekt was ich brauche
            control32.dll Darin sind meine benutzerlemente (bin32, base32 werden hier eingebunden)

            und dann noch mein clientapplication / Hauptprogramm (hier werden all oben aufgeführten dll eingebunden.)

            wenn ich jetzt eine methode von bin32 ausführe wird eine Exception geworfen die die Fehlermeldung oben enthält! Base32 hieß früher mal ClientapplicationDokumentBase aber die bin32.dll war nie abhängig von dieser base32.dll. Daher weiß ich nicht warum er die Assembly sucht. Ich habe alle Dateien nachgeschaut, ich weiß nicht was ich noch machen kann!

            Habt ihr vielleicht eine Idee!

            mfg Daniel

            Comment


            • #7
              okay ich habe es nach langem suchen gefunden. Die Datei die ich an der Stelle geladen habe enthielt ja ein Objekt und darin war ein Verweiß noch auf die Dokumentbase nach dem ich die config neu angelegt habe mit dem neuen objekt hat wieder alles funktioniert! darauf muss man erst mal kommen!

              Comment

              Working...
              X