INTEROP Probleme beim Einbinden von DLL's

andralin

Erfahrenes Mitglied
Hi Leute,

nach etlichem Suchen hab ich zum Thema Registrierung von COM (DLL's/OCX's) ein VB Beispiel gefunden mit dem ich die entsprechenden API's nutzen kann.

Leider ist das VB Projekt in meinem VS nicht lauffähig und der Umbau nach C# ein wenig schwerfällig gewesen.

Hier der komplette Code.

Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace MBS002
{
    class Program
    {
        //Private Declare Function LoadLibraryA Lib "kernel32" (ByVal lLibFileName As String) As Long
        [DllImport("kernel32.dll")]
        private static extern IntPtr LoadLibrary(string lLibFileName);

        //Private Declare Function CreateThread Lib "kernel32" (lThreadAttributes As Any, ByVal lStackSize As Long, ByVal lStartAddress As Long, ByVal larameter As Long, ByVal lCreationFlags As Long, lThreadID As Long) As Long
        [DllImport("kernel32.dll")]
        private static extern long CreateThread(object lThreadAttributes, long lStackSize, IntPtr lStartAddress, long larameter, long lCreationFlags, long lThreadID);
        
        //Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal lMilliseconds As Long) As Long
        [DllImport("kernel32.dll")]
        private static extern long WaitForSingleObject(long hHandle, long lMilliseconds);

        //Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lProcName As String) As Long
        [DllImport("kernel32.dll")]
        private static extern IntPtr GetProcAddress(IntPtr hModule, string lProcName);

        //TODO: wie wird alias umgesetzt?
        //Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
        [DllImport("user32.dll")]
        private static extern long CallWindowProc(long lpPrevWndFunc, long hwnd, long Msg, long wParam, long lParam);

        //Private Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long
        [DllImport("kernel32.dll")]
        private static extern long FreeLibrary(IntPtr hLibModule);

        //Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
        [DllImport("kernel32.dll")]
        private static extern long CloseHandle(long hObject);

        //Private Declare Function GetExitCodeThread Lib "kernel32" (ByVal hThread As Long, lExitCode As Long) As Long
        [DllImport("kernel32.dll")]
        private static extern long GetExitCodeThread(long hThread, long lExitCode);

        //Private Declare Sub ExitThread Lib "kernel32" (ByVal lExitCode As Long)
        [DllImport("kernel32.dll")]
        private static extern long ExitThread(long lExitCode);
                
        static void Main(string[] args)
        {
            if (RegisterComponent(@"C:\test.dll", true))
                Console.WriteLine("OK");
            else
                Console.WriteLine("FEHLER");

                Console.WriteLine("Programm-Ende! Taste drücken!");
            Console.ReadKey();
        }

        static private bool RegisterComponent(string sFilePath)
        {
             return RegisterComponent(sFilePath, true);
        }

        static private bool RegisterComponent(string sFilePath, bool bRegister)
        {
            bool RetVal = false;
            IntPtr lLibAddress;
            IntPtr lProcAddress;            
            //long lThreadID;
            long lSuccess;
            long lExitCode = 0;
            long lThread = 0;
            string sRegister;
            const long clMaxTimeWait = 20000;     //Wait 20 secs for register to complete

            try
            {
                if (sFilePath.Length > 0) // ACHTUNG in VB wurde hier noch sichergestellt das es ein Verzeichnis im sFilePath gibt!
                { //*** File exists!
                    string ext = sFilePath.Substring(sFilePath.Length - 3).ToUpper();
                    if (ext == "DLL" || ext == "OCX")
                    {
                        if (bRegister)
                            sRegister = "DllRegisterServer";
                        else
                            sRegister = "DllUnRegisterServer";

                        lLibAddress = LoadLibrary(sFilePath);
                        if (lLibAddress!=null)
                        {
                            lProcAddress = GetProcAddress(lLibAddress, sRegister);
                            if (lProcAddress!=null)
                            {
                                CreateThread(0, 0, lProcAddress, 0, 0, lThread);
                                if(lThread>0)
                                {   //Created thread and wait for it to terminate
                                    lSuccess = WaitForSingleObject(lThread, clMaxTimeWait);
                                    if(lSuccess==0)
                                    {//Failed to register, close thread
                                        GetExitCodeThread(lThread, lExitCode);
                                        ExitThread(lExitCode);
                                        RetVal = false;
                                    }
                                    else
                                    {   //Successfully registered component
                                        RetVal = true;
                                        CloseHandle(lThread);
                                    }
                                }
                                FreeLibrary(lLibAddress);
                            }
                            else
                            {
                                FreeLibrary(lLibAddress);
                            }
                        }
                        else
                        {
                            FreeLibrary(lLibAddress);
                        }
                    }
                }
                return RetVal;
            }
            catch(Exception ExErr)
            {
                Console.WriteLine(ExErr.Message);
                return false;
            }
            
        }
    }
}

Das y steigt mir immer bei
Code:
CreateThread(0, 0, lProcAddress, 0, 0, lThread);
aus.

Fehlermeldung:
Es wurde versucht i geschützten Speicher zu lesen oder zu schreiben. ...

Habs auch schon mit
Code:
CreateThread(null, 0, lProcAddress, 0, 0, lThread);
versucht, ...
aber dann hängt sich alles ohne behandelte Exception auf.

Vielleicht hat hier einer schon mal damit gekämpft und kann mir sagen wo der fehler her kommt.

LG Andralin
 
Ja, du machst es dir viel zu umständlich.
Ruf Regsvr32.exe mit Hilfe der Prozess-Klasse auf ;)

den aufruf der regSrv32 über Shell (Process) kenne ich aber die nützt mir nix. Ich muss nach der Registrierung ein true oder false bekommen. Aber bei RegServ habe ich keine Sicherheit. Habs getestet.

mit "xxx.dll" die eine umbenannte Textdatei war
mit "" also ohne Datei
in allen Fällen ist regSrv32 über process gelaufen und der ErrorOutput war leer.

Ich muss leider in dem Fall eine sichere Registrierung haben.
Deswegen die API. denn die gibt am Ende True/Falls oder anders Feedback
 
http://www.tutorials.de/forum/net-w...ocxs-und-tlbs-automatisiert-regsitrieren.html
Du hast die Frage doch selbst gestellt, wieso probierst du die Hilfe dann nicht auch aus?!
Ist im Link beschrieben!
das aus dem Link den Du geschickt hattest sieht stark nach $PHP aus.
Oder irre ich mich. Powershell ist für mich noch strange.
Alles was ich brauche ist ein weg wo ich registriere("irgendwas.dll") sage und die antwort lautet OK oder nicht OK,... denke der weg über die API ist der goldene. Nur kämpf ich noch mit den Parametern.
 

Neue Beiträge

Zurück