[vb.NET] System.Data.SQLite into .exe

07/03/2014 15:38 TeamFAiTh#1
Moin,

ich sitze jetzt schon seit wahrscheinlich 4 Stunden da und versuche vergeblich die System.Data.SQLite.dll (v1.0.93.0 32bit Framework 2.0 SP2) in meine .exe einzubinden.


Was ich schon probiert habe:

AssemblyCompressor v2
ILMerge mit /zeroPekind Modus (Normaler Modus geht überhaupt nicht)
In Visual Basic 2010 die DLL einzubinden (Via Ressources)


Nichts davon hat funktioniert, kann es jemand bei sich versuchen und dann eine Schritt-zu-Schritt Anleitung für Doofies posten?


Und ja es ist wichtig das die DLL in der .exe ist.



Gruß
TeamFAiTh
07/03/2014 15:52 tolio#2
Quote:
Originally Posted by TeamFAiTh View Post
kann es jemand bei sich versuchen und dann eine Schritt-zu-Schritt Anleitung für Doofies posten?
klar doch:
1. webbrowser öffnen
2. google.de eingegen, enter drücken
3. ".Net dll resource" eingeben, enter drücken
4. einige der "About 2,870,000 results" durchlesen
5. ???
6. Profit
07/03/2014 17:04 Black Tiger ツ#3
[Only registered and activated users can see links. Click Here To Register...]

das hat bei mir immer geklappt.
07/03/2014 18:07 TeamFAiTh#4
Leider auch nicht.
Hab's zumal auch mit netz.exe (Und da mit allen Methoden) probiert > Kein Erfolg.


Ich denke ich muss die DLL in die Ressourcen kopieren und dann beim ersten Start in eine Datei schreiben > Diese DLL registriere ich dann mit:

Code:
 System.Diagnostics.Process.Start("regsvr32.exe", "PfadZurDLL\System.Data.SQLite.DLL")

Hier sind zwei Codes mit denen ich versucht habe die eingebundene DLL zu forcen:

Code:
Option Strict On
Imports System.Reflection

Namespace My

    Partial Friend Class MyApplication

        Private Sub Form1_Startup(ByVal sender As Object, ByVal e As Microsoft.VisualBasic.ApplicationServices.StartupEventArgs) Handles Me.Startup
            AddHandler AppDomain.CurrentDomain.AssemblyResolve, AddressOf DLLDateiAusResourcesLaden
        End Sub

        Private Function DLLDateiAusResourcesLaden(ByVal sender As Object, ByVal args As System.ResolveEventArgs) As System.Reflection.Assembly

            If args.Name.Contains("System.Data.SQLite") Then
                Return System.Reflection.Assembly.Load(My.Resources.System_Data_SQLite)
            Else
                Return Nothing
            End If

        End Function

        'Private Function LoadDLLFromStream(ByVal sender As Object, ByVal args As System.ResolveEventArgs) As System.Reflection.Assembly

        '    Using stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("System.Data.SQLite.dll")

        '        Dim assemblyData(CInt(stream.Length - 1)) As Byte

        '        stream.Read(assemblyData, 0, assemblyData.Length)

        '        Return System.Reflection.Assembly.Load(assemblyData)

        '    End Using

        'End Function

    End Class

End Namespace
07/04/2014 17:14 Mostey#5
Quote:
Originally Posted by TeamFAiTh View Post
Und ja es ist wichtig das die DLL in der .exe ist.
Dynamic Link Library. Wie zur Hölle möchtest du das bitte statisch in einer .exe einbinden? Das geht nicht einfach so, du meinst eher eine statische Library (.lib), wobei ich da nicht genau weiß wie das bei .NET gehandhabt wird.

Allerdings wird eine DLL immer zur Laufzeit (vom Programm) geladen. Dementsprechend muss das Programm auch für gewöhnlich im selben Ordner sein, wie die benötigten Ressourcen (= DLL), da standardmäßig im Working Directory gesucht wird.

Du solltest das nochmal überdenken.

Quote:
Originally Posted by Jon Skeet
The closest you can come is ILMerge - but do you really need this? Unless you have an application which you can deploy as a single executable, it doesn't much matter whether you have one DLL or ten. I would suggest that for most cases, you should just keep them as normal class libraries.

Note that ILMerge isn't quite the same as "static linking" - it still does the job of bundling all the code into a single file, but the linking process in .NET is fundamentally somewhat different to the one for native code.
[Only registered and activated users can see links. Click Here To Register...]
07/04/2014 20:55 TeamFAiTh#6
Quote:
Originally Posted by Mostey View Post
[B]Allerdings wird eine DLL immer zur Laufzeit (vom Programm) geladen. Dementsprechend muss das Programm auch für gewöhnlich im selben Ordner sein, wie die benötigten Ressourcen (= DLL), da standardmäßig im Working Directory gesucht wird.


Das kann man verhindern, indem man die DLL zu den Resourcen hinzufügt und dann diese dann in den Memory schreibt (In ApplicationsEvents.vb). Dies geht aber nur mit manchen DLLs.
07/05/2014 17:11 Requi#7
Was ich für mein Programm mal genutzt habe:

Code:
public class AssemblyLoader
    {
        private static Dictionary<string, Assembly> dic;

        static AssemblyLoader()
        {
            AssemblyLoader.dic = null;
        }

        public AssemblyLoader()
        {
        }

        public static Assembly Get(string assemblyFullName)
        {
            Assembly item;
            if (!(AssemblyLoader.dic == null ? false : AssemblyLoader.dic.Count != 0))
            {
                item = null;
            }
            else if (!AssemblyLoader.dic.ContainsKey(assemblyFullName))
            {
                item = null;
            }
            else
            {
                item = AssemblyLoader.dic[assemblyFullName];
            }
            return item;
        }

        public static void Load(string embeddedResource, string fileName)
        {
            if (AssemblyLoader.dic == null)
            {
                AssemblyLoader.dic = new Dictionary<string, Assembly>();
            }
            byte[] numArray = null;
            Assembly assembly = null;
            Stream manifestResourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(embeddedResource);
            try
            {
                if (manifestResourceStream == null)
                {
                    throw new Exception(string.Concat(embeddedResource, " is not found in Embedded Resources."));
                }
                numArray = new byte[(int)manifestResourceStream.Length];
                manifestResourceStream.Read(numArray, 0, (int)manifestResourceStream.Length);
                try
                {
                    assembly = Assembly.Load(numArray);
                    AssemblyLoader.dic.Add(assembly.FullName, assembly);
                    return;
                }
                catch
                {
                }
            }
            finally
            {
                if (manifestResourceStream != null)
                {
                    ((IDisposable)manifestResourceStream).Dispose();
                }
            }
            bool flag = false;
            string str = "";
            SHA1CryptoServiceProvider sHA1CryptoServiceProvider = new SHA1CryptoServiceProvider();
            try
            {
                string str1 = BitConverter.ToString(sHA1CryptoServiceProvider.ComputeHash(numArray)).Replace("-", string.Empty);
                str = string.Concat(Path.GetTempPath(), fileName);
                if (!File.Exists(str))
                {
                    flag = false;
                }
                else
                {
                    flag = (str1 != BitConverter.ToString(sHA1CryptoServiceProvider.ComputeHash(File.ReadAllBytes(str))).Replace("-", string.Empty) ? false : true);
                }
            }
            finally
            {
                if (sHA1CryptoServiceProvider != null)
                {
                    ((IDisposable)sHA1CryptoServiceProvider).Dispose();
                }
            }
            if (!flag)
            {
                File.WriteAllBytes(str, numArray);
            }
            assembly = Assembly.LoadFile(str);
            AssemblyLoader.dic.Add(assembly.FullName, assembly);
        }
    }
In der Program.cs steht das:
Code:
        private static Assembly CurrentDomainAssemblyResolve(object sender, ResolveEventArgs args)
        {
            return AssemblyLoader.Get(args.Name);
        }

        [STAThread]
        private static void Main()
        {
            string str = "NAMESPACE.LIBRARY.dll";
            AssemblyLoader.Load(str, str);
            AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(Program.CurrentDomainAssemblyResolve);
            /*Standard Code*/
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new frmMain());
        }