Eigene EXE findet DLL nicht, nur wenn es im Verzeichnis der EXE ist

  • VB.NET

Es gibt 32 Antworten in diesem Thema. Der letzte Beitrag () ist von Splamy.

    Eigene EXE findet DLL nicht, nur wenn es im Verzeichnis der EXE ist

    Hallo Zusammen,

    ich habe jetzt schon seit Stunden gesucht. Ich krieg den Horror.

    Meine erstellte EXE funktioniert nur dann, wenn ich die DLL
    (System.Data.SQLite.DLL ist nur ein Beispiel) im gleichen Verzeichnis habe.
    Ich hab schon unter DLL dynamisch einbinden gesucht, usw.
    Ich krieg es einfach nicht hin.
    Mein Versuch ist die EXE egal in welchem Verzeichnis auch immer
    startend, zum laufen zu kriegen.
    Die EXE soll die DLL aus einem Verzeichnis (C:\DLLs) nutzen.

    Wo wird den generell nach der DLL gesucht wenn sie nicht im
    Startverzeichnis ist.

    Wäre toll, wenn mir jemand bei diesem Problem helfen könnte.
    Verzweifle.

    Evtl., wenn es nicht zuviel Mühe macht wäre ein Code Snippet super.

    Schon mal vielen Dank für Eure Hilfe.

    Viele Grüße

    Edit by der_Kurt:
    - gehört nicht zu den Grundlagen
    --> Beitrag verschoben

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „der_Kurt“ ()

    singu schrieb:

    Die DLLs müssen sich immer im gleichen Verzeichnis wie die EXE befinden. Such mal hier im Forum da hat jemand ein ähnliches Problem gehabt

    das stimmt nicht ganz, man kann auf den projektmappen explorer auf den projektnamen rechts raufklicken und da auf neuer ordner, dann rechtsklick auf den neuen ordner(im projektmappen explorer) und da hinzufügen -> vorhandenes element -> auf Ausführbare dateien umstellen und die dll auswählen.

    lg Gugi
    Hallo Zusammen,

    vielen Dank für Eure schnelle Hilfe.

    Leider funktioniert weder das Hinzufügen, das Gugi, noch das Programm
    AssemblyCompressor, das Samus Aran, vorgeschlagen hat.

    Sobald ich die o. g. DLL jedoch in das Verzeichnis packe, wo die
    EXE sich befindet, läuft es.

    Ich habe auch die DLL als Managed Only mit AssemblyCompressor verucht.
    Verstehe es einfach nicht.

    Aber trotzdem erstmal vielen Dank.
    Vielleicht weis ja noch jemand eine Möglichkeit ?

    TheSaint schrieb:

    Hallo Zusammen,

    vielen Dank für Eure schnelle Hilfe.

    Leider funktioniert weder das Hinzufügen, das Gugi, noch das Programm
    AssemblyCompressor, das Samus Aran, vorgeschlagen hat.

    Sobald ich die o. g. DLL jedoch in das Verzeichnis packe, wo die
    EXE sich befindet, läuft es.

    Ich habe auch die DLL als Managed Only mit AssemblyCompressor verucht.
    Verstehe es einfach nicht.

    Aber trotzdem erstmal vielen Dank.
    Vielleicht weis ja noch jemand eine Möglichkeit ?


    du musst du wohl die dll im selben ordner lassen ;)
    ist es denn so schlimm wenn man eine DLL im programm hat/eine andere dll verwendet?

    lg Gugi
    Hallo jvbsl,

    ich habe mir den Link angesehen. Vielen Dank.

    Es kommt folgende Fehlermeldung:

    Fehler beim Erstellen des Formulars. Weitere Informationen finden Sie in Exception.InnerException. Fehler: Die Datei oder Assembly "System.Data.SQLite, Version=1.0.66.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" oder eine Abhängigkeit davon wurde nicht gefunden. Das System kann die angegebene Datei nicht finden..

    Ich habe folgenden Code eingefügt:

    VB.NET-Quellcode

    1. Dim loadedAssembly As Assembly = Assembly.LoadFile("U:\Daten\Datenbank\System.Data.SQLite.DLL")
    2. If loadedAssembly IsNot Nothing Then
    3. MsgBox("DLL ist geladen")
    4. End If

    Anschließend habe ich beim Verweis: Lokale Kopie auf False gesetzt.

    Trotzdem kommt die o. g. Fehlermeldung??

    Wäre für Deine / Eure Hilfe sehr dankbar.
    das wurde bereits gepostet...

    @TE:
    dürfte ich mal den gesamten Code sehen? Und wo definierst du AddHandler? Wann wird die dll zum ersten mal verwendet?
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---

    jvbsl schrieb:


    das wurde bereits gepostet...

    @TE:
    dürfte ich mal den gesamten Code sehen? Und wo definierst du AddHandler? Wann wird die dll zum ersten mal verwendet?


    Na klar ;)

    Also ich hoffe ich habe Dich richtig verstanden: Beim Starten der EXE wird Form1 gestartet und folgender Code folgt:

    VB.NET-Quellcode

    1. Imports System.Data.SQLite
    2. Imports System.IO
    3. Imports System.Reflection
    4. Public Class Form1
    5. Dim SQLcommand As SQLiteCommand
    6. Dim SQLcommand1 As SQLiteCommand
    7. Dim SQLcommand2 As SQLiteCommand
    8. Dim SQLcommand3 As SQLiteCommand
    9. Dim SQLcommand4 As SQLiteCommand
    10. Dim SQLcommand5 As SQLiteCommand
    11. Dim SQLconnect As New SQLite.SQLiteConnection()
    12. Public Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    13. Me.CenterToScreen()
    14. Dim loadedAssembly As Assembly = Assembly.LoadFile("U:\Daten\Datenbank\System.Data.SQLite.DLL")
    15. If loadedAssembly IsNot Nothing Then
    16. MsgBox("DLL ist geladen")
    17. End If
    18. Me.Show()
    19. Me.TextBox1.Visible = True
    20. Me.DataGridView1.Visible = False
    21. ... ab hier wird zum erstenmal auf die DLL zugegriffen...
    22. SQLconnect.ConnectionString = "Data Source=" + UrDB + ";"
    23. SQLconnect.Open()
    24. SQLcommand = SQLconnect.CreateCommand
    25. SQLcommand.CommandText = "delete from StTab"
    26. SQLcommand.ExecuteNonQuery()
    27. SQLcommand.CommandText = "Begin Transaction"
    28. SQLcommand.ExecuteNonQuery()
    29. ... usw... hier folgt einfach nur noch der Aufruf von verschiedenen Datenbankabfragen bzw. Updates
    30. SQLcommand.CommandText = "Commit"
    31. SQLcommand.ExecuteNonQuery()
    32. SQLcommand.Dispose()
    33. SQLconnect.Close()
    34. End Sub
    35. End Class


    Vielen Dank das Du mir hilfst.

    Viele Grüße
    Ich bin ja normalerweise ein grosser Fan davon benötigte DLL's als embedded Ressource im Hauptprogramm einzubinden, d.h. natürlich nur wenn sich die Anzahl der DLL's in Grenzen hält. In Deinem Fall würde ich auf die AppDomain Klasse zurückgreifen.

    Mit AppendPath kannst Du einen zusätzlichen Suchpfad für Deine AppDomain.CurrrentDomain einrichten.
    hallo jvbs,

    sorry, dass ich noch mal nachfrage, meinst du dies hier???

    VB.NET-Quellcode

    1. # Fügen Sie einen Ereignishandler hinzu AssemblyResolve Ereignis in das Ereignis Form1_Load wie folgt:
    2. Visual Basic .NET oder Visual Basic 2005-code
    3. AddHandler AppDomain.CurrentDomain.AssemblyResolve, AddressOf MyResolveEventHandler
    4. Visual c# .NET oder Visual c# 2005-code
    5. AppDomain currentDomain = AppDomain.CurrentDomain;
    6. currentDomain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler);
    7. # Definieren Sie die MyResolveEventHandler -Funktion wie folgt:
    8. Visual Basic .NET oder Visual Basic 2005-code
    9. Function MyResolveEventHandler(ByVal sender As Object, _
    10. ByVal args As ResolveEventArgs) As [Assembly]
    11. 'This handler is called only when the common language runtime tries to bind to the assembly and fails.
    12. 'Retrieve the list of referenced assemblies in an array of AssemblyName.
    13. Dim objExecutingAssemblies As [Assembly]
    14. objExecutingAssemblies = [Assembly].GetExecutingAssembly()
    15. Dim arrReferencedAssmbNames() As AssemblyName
    16. arrReferencedAssmbNames = objExecutingAssemblies.GetReferencedAssemblies()
    17. 'Loop through the array of referenced assembly names.
    18. Dim strAssmbName As AssemblyName
    19. For Each strAssmbName In arrReferencedAssmbNames
    20. 'Look for the assembly names that have raised the "AssemblyResolve" event.
    21. If (strAssmbName.FullName.Substring(0, strAssmbName.FullName.IndexOf(",")) = args.Name.Substring(0, args.Name.IndexOf(","))) Then
    22. 'Build the path of the assembly from where it has to be loaded.
    23. Dim strTempAssmbPath As String
    24. strTempAssmbPath = "C:\assemblies\" & args.Name.Substring(0, args.Name.IndexOf(",")) & ".dll"
    25. Dim MyAssembly as [Assembly]
    26. 'Load the assembly from the specified path.
    27. MyAssembly = [Assembly].LoadFrom(strTempAssmbPath)
    28. 'Return the loaded assembly.
    29. Return MyAssembly
    30. End If
    31. Next
    32. End Function


    Hab da einfach nicht durchgeblickt...

    Ich versuche nochmal zu schauen ob ich es hinkriege.

    Wäre toll, wenn du mal so ein Beispiel machen könntest, wenn
    es dich nicht zu sehr stört.

    Dank!
    Hallo Zusammen,

    bin seit gestern dabei das Problem zu lösen.
    Trotz Eurer Ratschläge und Hilfen, krieg ich es einfach nicht mit dem Beispiel hin.
    Wäre sehr Dankbar über eine Hilfestellung.

    Ich nutze folgenden Code:

    VB.NET-Quellcode

    1. Imports System.Collections.Generic
    2. Imports System.ComponentModel
    3. Imports System.Data
    4. Imports System.Drawing
    5. Imports System.Text
    6. Imports System.Windows.Forms
    7. Imports System.Reflection
    8. Imports System.Data.SQLite
    9. Imports System.IO
    10. Public Class Form1
    11. Public Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    12. AddHandler AppDomain.CurrentDomain.AssemblyResolve, AddressOf MyResolveEventHandler
    13. Me.CenterToScreen()
    14. Me.TextBox1.Visible = True
    15. Me.DataGridView1.Visible = False
    16. SQLconnect.ConnectionString = "Data Source=" + UrDB + ";"
    17. SQLconnect.Open()
    18. SQLcommand = SQLconnect.CreateCommand
    19. '***** Hier folgen verschiedene SQL Codes *****
    20. SQLconnect.Close()
    21. End Sub
    22. Function MyResolveEventHandler(ByVal sender As Object, _
    23. ByVal args As ResolveEventArgs) As [Assembly]
    24. 'This handler is called only when the common language runtime tries to bind to the assembly and fails.
    25. 'Retrieve the list of referenced assemblies in an array of AssemblyName.
    26. Dim objExecutingAssemblies As [Assembly]
    27. objExecutingAssemblies = [Assembly].GetExecutingAssembly()
    28. Dim arrReferencedAssmbNames() As AssemblyName
    29. arrReferencedAssmbNames = objExecutingAssemblies.GetReferencedAssemblies()
    30. 'Loop through the array of referenced assembly names.
    31. Dim strAssmbName As AssemblyName
    32. For Each strAssmbName In arrReferencedAssmbNames
    33. 'Look for the assembly names that have raised the "AssemblyResolve" event.
    34. If (strAssmbName.FullName.Substring(0, strAssmbName.FullName.IndexOf(",")) = args.Name.Substring(0, args.Name.IndexOf(","))) Then
    35. 'Build the path of the assembly from where it has to be loaded.
    36. Dim strTempAssmbPath As String
    37. strTempAssmbPath = "U:\Daten\Datenbank\" & args.Name.Substring(0, args.Name.IndexOf(",")) & ".dll"
    38. Dim MyAssembly As [Assembly]
    39. 'Load the assembly from the specified path.
    40. MyAssembly = [Assembly].LoadFrom(strTempAssmbPath)
    41. 'Return the loaded assembly.
    42. Return MyAssembly
    43. End If
    44. Next
    45. End Function
    46. End Class


    Was mache ich den falsch? Was habe ich den da vergessen?

    Es kommt immer die Fehlermeldung, dass er die System.Data.SQLite.dll nicht findet.

    Schon mal vielen Dank vorab für Eure Hilfe.

    Viele Grüße