Frage

Wenn ein ActiveXObject in einem Windows-Desktop / Sidebar Gadget gehostet wird, dass ActiveXObject ist eine Art zwischengespeichert und die DLL-Datei für sie gesperrt ist (dh, es kann nicht verschoben werden, gelöscht oder umbenannt). Das Problem ist, diese; wenn das Gerät anschließend geschlossen wird, wird die DLL immer noch von Windows Sidebar gesperrt und kann nicht entfernt werden. Dies verursacht ein signifikantes Problem, wodurch eine neue Version des Gadgets nicht über den oberen Teil einer früheren Version des Gadgets installiert werden kann, ist es während des Prozesses scheitert es ohne Fehlermeldungen zu löschen.

Das ist nicht sehr benutzerfreundlich, so dass ich mich für eine Art und Weise zu „trennen“ Verbindungen zu dem ActiveX-Steuerelement irgendwie während der Gadgets Entlade-Ereignisses suchen. Ich hoffe, jemand kann mir sagen, ob dies möglich ist, und wenn es gibt, ist mir ein paar Ideen, wie sie umzusetzen.

FYI, Windows Sidebar Gadgets sind eigentlich nur Server Internet Explorer-Fenster, so ist es wahrscheinlich sicher davon ausgehen, dh das gleiche Verhalten zeigt.

EDIT: Unlocker scheint ziemlich viel zu tun, was ich brauche zu tun, so wie kann ich die gleiche Sache programmatisch in .NET erreichen?

War es hilfreich?

Lösung

Okay, das ist ein ziemlich komplexes Problem. Ich habe dieses Verhalten gesehen, ich bin nicht vertraut mit dem Windows-Desktop / Sidebar Gadget, wie ich es nicht verwenden. Allerdings habe ich zu kommen mit drei möglichen Angriffsmethoden verwaltet

1. Griff von TechNet

Das war nicht meine Idee, Untersuchen Informationen auf Windows NT System Level Primitives

  • Löschen Gesperrte Dateien
  • eine DLL in einem anderen Prozess der Adressraum Injizieren
  • Leider konnte ich das nicht bekommen nahtlos zu arbeiten. Ich habe diese Methode getestet, ein ActiveX geladen in MS Word. Ich habe dann versucht das ActiveX zu entsperren, es ist nicht sehr stabil und häufig verursacht Wort zum Absturz bringen. Ich glaube, ich nicht über die erforderlichen c ++ Kriegsverletzungen haben richtig die oben genannten Programme zu entschlüsseln.

    Neben diesem Beispiel Create in C # ich diesen Code gelegt hat zusammen.

    public struct ProcessInfo
    {
        public Process Process;
        public ProcessModule Module;
    
        public ProcessInfo(Process process, ProcessModule module)
        {
            this.Process = process;
            this.Module = module;
        }
    }
    
    private static List<ProcessInfo> getProcessInfo(string fileName, bool partialMatch)
    {
        List<ProcessInfo> myProcesses = new List<ProcessInfo>();
    
        Process[] runningProcesses = Process.GetProcesses();
        int i = 0;
        for (i = 0; i < runningProcesses.Length; i++)
        {
            Process currentProcess = runningProcesses[i];
            try
            {
                if (!currentProcess.HasExited)
                {
                    try
                    {
                        ProcessModuleCollection modules = currentProcess.Modules;
                        int j = 0;
                        for (j = 0; j < modules.Count; j++)
                        {
                            if (partialMatch)
                            {
                                if ((modules[j].FileName.ToLower().IndexOf(fileName.ToLower()) != -1))
                                {
                                    myProcesses.Add(new ProcessInfo(currentProcess, modules[j]));
                                    break;
                                }
                            }
                            else
                            {
                                if ((modules[j].FileName.ToLower().CompareTo(fileName.ToLower()) == 0))
                                {
                                    myProcesses.Add(new ProcessInfo(currentProcess, modules[j]));
                                    break;
                                }
                            }
                        }
                    }
                    catch (NotSupportedException)
                    {
                        // You are attempting to access the Modules property for a process that is running on a remote computer. 
                        // This property is available only for processes that are running on the local computer. 
                    }
                    catch (InvalidOperationException)
                    {
                        // The process Id is not available.
                    }
                    catch (Win32Exception)
                    {
                        // You are attempting to access the Modules property for either the system process or the idle process. 
                        // These processes do not have modules.
                    }
                }
            }
            catch (InvalidOperationException)
            {
                // There is no process associated with the object. 
            }
            catch (Win32Exception)
            {
                // The exit code for the process could not be retrieved. 
            }
            catch (NotSupportedException)
            {
                // You are trying to access the HasExited property for a process that is running on a remote computer.
                // This property is available only for processes that are running on the local computer.
    
            }
        }
        return myProcesses.Count > 0 ? myProcesses : null;
    }
    
    private static void forceRemoteCloseHandle(ProcessInfo processInfo)
    {
        // Open remote process for write
        IntPtr hProcess = NativeMethods.OpenProcess(NativeMethods.PROCESS_CREATE_THREAD | NativeMethods.PROCESS_VM_OPERATION |
                NativeMethods.PROCESS_VM_WRITE | NativeMethods.PROCESS_VM_READ, false, processInfo.Process.Id);
    
        // Get the handle to CloseHandle in kernel32.dll
        IntPtr hKernel32 = NativeMethods.LoadLibrary("kernel32.dll");
        IntPtr hCloseHandle = NativeMethods.GetProcAddress(hKernel32, "CloseHandle");
        uint temp = 0;
    
        // Create the remote thread and point it to CloseHandle
        IntPtr hCreateRemoteThread = NativeMethods.CreateRemoteThread((IntPtr)hProcess, (IntPtr)0, 0, hCloseHandle, (IntPtr)processInfo.Module.BaseAddress, 0, out temp);
    
        // Wait for thread to end
        NativeMethods.WaitForSingleObject(hCreateRemoteThread, 2000);
    
        //Closes the remote thread handle
        NativeMethods.CloseHandle(hCreateRemoteThread);
    
        //Free up the kernel32.dll
        if (hKernel32 != null)
            NativeMethods.FreeLibrary(hKernel32);
    
        //Close the process handle
        NativeMethods.CloseHandle(hProcess);
    }
    
    private static void forceRemoteFreeLibrary(ProcessInfo processInfo)
    {
        // Open remote process for write
        IntPtr hProcess = NativeMethods.OpenProcess(NativeMethods.PROCESS_CREATE_THREAD | NativeMethods.PROCESS_VM_OPERATION |
                NativeMethods.PROCESS_VM_WRITE | NativeMethods.PROCESS_VM_READ, false, processInfo.Process.Id);
    
        // Get the handle to FreeLibrary in kernel32.dll
        IntPtr hKernel32 = NativeMethods.LoadLibrary("kernel32.dll");
        IntPtr hFreeHandle = NativeMethods.GetProcAddress(hKernel32, "FreeLibrary");
    
        // Create the remote thread and point it to FreeLibrary
        uint temp = 0;
        IntPtr hCreateRemoteThread = NativeMethods.CreateRemoteThread((IntPtr)hProcess, (IntPtr)0, 0, hFreeHandle, (IntPtr)processInfo.Module.BaseAddress, 0, out temp);
    
        // Wait for thread to end
        NativeMethods.WaitForSingleObject(hCreateRemoteThread, 2000);
    
        //Closes the remote thread handle
        NativeMethods.CloseHandle(hCreateRemoteThread);
    
        //Free up the kernel32.dll
        if (hKernel32 != null)
            NativeMethods.FreeLibrary(hKernel32);
    
        // Close the process handle
        NativeMethods.CloseHandle(hProcess);        
    }
    
    public static void Main()
    {
        string strFile = @"C:\Program Files\Microsoft Office\OFFICE11\MSCAL.OCX";
        List<ProcessInfo> lockingProcesses = getProcessInfo(strFile, false);
    
        foreach (ProcessInfo processInfo in lockingProcesses)
        {
            forceRemoteCloseHandle(processInfo);
            // OR
            forceRemoteFreeLibrary(processInfo);
        }
    
        // OR
        foreach (ProcessInfo procInfo in lockingProcesses)
        {
            procInfo.Process.Kill();
        }
    
    }
    
    internal static class NativeMethods
    {
        internal const int PROCESS_TERMINATE = 0x0001;
        internal const int PROCESS_CREATE_THREAD = 0x0002;
        internal const int PROCESS_VM_OPERATION = 0x0008;
        internal const int PROCESS_VM_READ = 0x0010;
        internal const int PROCESS_VM_WRITE = 0x0020;
    
        internal const int PROCESS_QUERY_INFORMATION = 0x0400;
    
        [DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
        internal static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
    
        [DllImport("kernel32.dll", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
        internal static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
    
        [DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
        internal static extern int WaitForSingleObject(IntPtr hHandle, int dwMilliseconds);
    
        [DllImport("kernel32", SetLastError = true)]
        internal static extern IntPtr LoadLibrary(string lpFileName);
    
    
        [DllImport("kernel32.dll", SetLastError = true)]
        internal static extern bool FreeLibrary(IntPtr hModule);
    
        [DllImport("kernel32")]
        public static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, out uint lpThreadId);
    
        [DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
        internal static extern int CloseHandle(IntPtr hPass);
    }
    

    ...


    3. Verwenden Sie einfach Unlocker

    Das ist meine beste Empfehlung. Griff aus technet nicht verarbeiten kann geladenen DLL / ocx Schlösser (unter meinen Tests). Win32 ist chaotisch und ohne Papiere.

    Unlocker bietet Befehlszeile Zugang, so dass Sie es auf genau die gleiche Art und Weise wie handle.exe aufrufen können. Wack nur ein /? nach unlocker.exe in einer Eingabeaufforderung die Schalter zu sehen.

    Es gibt auch eine portable Version von Unlocker verfügbar , so dass Sie es in Ihre Bereitstellung, ohne dass der Endanwender die App installieren bündeln können.

    Wenn alle Stricke reißen Sie den Autor von Unlocker kontaktieren könnte, lesen Sie in dieser von seinem readme.

      

    Lizenzierung

         

    Wenn Sie daran interessiert sind,   Umverteilen Unlocker, entweder in   Original oder modifizierter Form oder Wunsch   verwenden Unlocker Quellcode in einem Produkt,   Bitte senden Sie eine E-Mail an   ccollomb@yahoo.com mit Details.

    ...


    4. Verwenden Sie Process Hacker Shared Libraries

    Ich habe gerade dieses geniale Tool entdeckt: Process Hacker , die in 100% C # -Code geschrieben (obwohl es eine Menge WinAPI Funktionen über P Nutzt / Invoke unter der Haube).

    Das Beste daran: es ist Open Source (LGPL'd) und bietet zwei Bibliotheken, die Entwickler in ihre Lösungen verweisen können: ProcessHacker.Common ProzessHacker.Native.

    heruntergeladen ich die Quelle und nur ein Wort der Warnung es eine ziemlich große Lösung ist so ein wenig Zeit in Anspruch nehmen kann, genau herauszufinden, was / wie es zu benutzen.

    Es verwendet die nicht dokumentierte API-Funktionen (ntdll.dl) I etwa 2 in Option gesprochen und alles Unlocker kann tun können, und eine ganze Menge mehr.

    Andere Tipps

    Nicht sicher, ob dies für ActiveX-Objekte funktioniert, aber es funktioniert definitiv für .NET-Assemblies. Ich benutze es für Unittesting, wo der DLLs problemlos überschrieben werden. Der Mechanismus verwendet wird, Schatten Kopieren .

    Closing Griffe von außen eine Anwendung nicht wirklich eine sehr sichere Option zu sein scheint.

    Es ist nicht die Lösung vielleicht eine Idee oder Richtung ...

    Lizenziert unter: CC-BY-SA mit Zuschreibung
    Nicht verbunden mit StackOverflow
    scroll top