문제

면 activexobject 의에서 호스팅 Windows 데스크톱/가젯을 사이드 바,는 activexobject 의 종류의 캐시 및 DLL 파일에 대한 잠겨(의미로 이동할 수는 없습니다,삭제 또는 변경).이게 문제입니다;할 때에 가젯입 이후 폐쇄 DLL 은 여전히 잠겨있으로 윈도우 사이드 바 및 제거할 수 없습니다.이렇게 중요한 문제이 그것에 의하여 새로운 버전의 이 가젯을 설치할 수 없을 통해 최고의 이전 버전의 이 가젯,그것은 실패하면 프로세스 동안 그것을 삭제하지 않고 어떤 오류 메시지를 가지고 있습니다.

이것은 매우 사용자 친화적이,그래서 내가 찾는 방법을"서버에"유대 ActiveX 컨트롤게 중에 가젯을 언로드 이벤트입니다.I'm hoping 쉽게 확인할 수 있게 되었습니다 이것은 가능한 경우 그것은 나에게는 방법에 대한 몇 가지 아이디어를 적용하는 작업이 필요합니다.

FYI,윈도우 사이드 기기들은 실제로 인터넷 Explorer 서버 windows,그래서 그것을 가능하게 안전하다고 가정 즉시 동일한 동작이다.

편집: Unlocker 을 할 것 같다 꽤 많은 내가 무엇을해야하는,그래서 어떻게 수행할 수 있습니까 같은 일에서 프로그래밍 방식으로.NET?

도움이 되었습니까?

해결책

좋아요 이것은 오히려 복잡한 문제입니다.나는 이 행동하기 전에,나는 익숙하지 않 Windows 데스크톱/가젯을 사이드 바로 내가 그것을 사용하지 않는다.그러나 나는 관리하는 세 가지의 가능한 방법을 공격

1. 핸들 에서 TechNet

이지 내 생각, 또 다른 유래 실 는 방식을 권장합니다.그러나 저는 회의적이지 않을지,또 이 작동합니다.사이에는 차이가 있는 파일 잠금(이 유틸리티의 손잡이)그리고"로드 라이브러리"자물쇠는 가정은 문제가 있으로 ActiveX.

내가 코드를 수정하에서는 실 약간,거기에 그들이 사용하는 과정입니다.죽일()로 릴리스 잠금,나는 생각은 그것의 더 나은 사용 handle.exe 을 잠금을 해제하십시오.

public struct LockInfo
{
    public int PID;
    public string Handle;

    public LockInfo(int pid, string handle)
    {
        this.PID = pid;
        this.Handle = handle;
    }
}      

static List<LockInfo> getLockingInfo(string fileName)
{            
    List<LockInfo> lockingProcesses = new List<LockInfo>();

    Process tool = new Process();
    tool.StartInfo.FileName = "handle.exe";
    tool.StartInfo.Arguments = fileName;
    tool.StartInfo.UseShellExecute = false;
    tool.StartInfo.RedirectStandardOutput = true;
    tool.Start();
    tool.WaitForExit();
    string outputTool = tool.StandardOutput.ReadToEnd();

    // I;m not so hot with regex, so a bit of regex and a bit of manual splitting
    string matchPattern = @"(?<=\s+pid:\s+)\b(\d+)\b(\s+)\b(\S+:)";
    foreach (Match match in Regex.Matches(outputTool, matchPattern))
    {
        string[] temp = match.Value.Replace(":", "").Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
        if (temp.Length == 2)
        {
            lockingProcesses.Add(new LockInfo(int.Parse(temp[0].Trim()), temp[1].Trim()));
        }
    }
    return lockingProcesses.Count > 0 ? lockingProcesses : null;
}

static bool closeFileHandle(List<LockInfo> lockingInfo)
{
    if ((lockingInfo == null) || (lockingInfo.Count == 0))
    {
        throw new ArgumentException("lockingProcesses cannot be null or empty");
    }

    bool fileClosed = true;

    foreach (LockInfo lockInfo in lockingInfo)
    {
        Process tool = new Process();
        tool.StartInfo.FileName = "handle.exe";
        tool.StartInfo.Arguments = string.Format("-c {0} -y -p {1}", lockInfo.Handle, lockInfo.PID.ToString());
        tool.StartInfo.UseShellExecute = false;
        tool.StartInfo.RedirectStandardOutput = true;
        tool.Start();
        tool.WaitForExit();
        string outputTool = tool.StandardOutput.ReadToEnd();
        if (outputTool.IndexOf("Handle closed") == -1)
        {
            fileClosed = false;
        }
    }
    return fileClosed;
}

public static void Main()
{            
    //Path to locked file, make sure the full path is in quotes
    string fileName = "\"" + @"C:\Your_Path\To_The\ActiveX.ocx" + "\"";
    List<LockInfo> lockInfo = getLockingInfo(fileName);
    if ((lockInfo != null) && (lockInfo.Count > 0))
    {
        closeFileHandle(lockInfo);
    }                                 
}

...


2.Win32 스타일

이 없 많은 정보를 인터넷에서 이것에 대해,그것은이없는 것처럼 보인다는 일부 문서화하지 않는 api 를 호출하는 데 필요한이 부드럽습니다.

나는 이러한 c++예 도움이 될 수 있습니다.

불행하게도 나는 수 없이 원활하게 작동합니다.나는 이 테스트 방법을 사용하여 ActiveX 로드에서 MS Word.나는 다음의 잠금을 해제하려고 ActiveX,그것은 매우 안정적이며 자주 발생한 말씀해 충돌이 발생합니다.나 없이 필요한 c++전쟁의 상처를 해독을 위한 프로그램습니다.

이와 함께의 예 CreateRemoteThread C# 나이 함께.

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.사 Unlocker

이것은 내 가장 추천하고 있습니다에서 핸들 technet 처리할 수 없습니다드 dll/ocx 자물쇠(아래에 테스트).Win32 이 지저분하고 문서화되지 않습니다.

Unlocker 제공하는 명령 라인에 액세스할 수 있습니다 그것은 정확히 동일한 방식으로 handle.exe.그냥 wack a/?후에 unlocker.exe 명령 프롬프트에서 볼 스위치가 있습니다.

휴대용 버전을 사용할 수 있 Unlocker 그래서 묶을 수 있으로 배포하지 않고 최종 사용자가 응용 프로그램을 설치합니다.

모든 사람이 실패하는 경우 연결할 수 있 저자의 언어를 확인하이에서 자신의 readme.

라이선싱

에 관심이 있는 경우 재배포 언어 중 하나에 원본 또는 수정된 형태로,또는 사용 Unlocker 소스 코드에서는,제품 전자 메일을 보내 주시기 바랍니하는 ccollomb@yahoo.com 가 포함되어 있습니다.

...


4.용 프로세스 해커는 공유 라이브러리

나는 단지 이 화려한 도구: 프로세스 해커 는 서면에서 100%C#의 코드(그것을 많이 사용하 WinAPI 을 통해 기능 P/Invoke 후드에서).

최고의 일이다:그것은 오픈 소스(를 가짂 것)과 제공하는 두 개의 라이브러리를 개발하고 있습니다 참조에서 자신의 솔루션:ProcessHacker.일반적인 ProcessHacker.Native.

소스를 다운로드하고 그 말씀의 경고 그것은 꽤 큰 솔루션할 수있는 약간의 시간을 정확히 파악/는 방법을 사용합니다.

그것은 사용하는 언급되지 않음 API 함수(ntdll 에서.dl)말씀에 대한 옵션에서 2 고 모든 것을 할 수 있습니다 Unlocker 수 있고 훨씬 더 많은.

다른 팁

가 확실하지 않으면 이동 ActiveX 개체 하지만 그것은 결정적으로 않습니다.NET 어셈블리입니다.나는 그것을 사용에 대한 UnitTesting 는 Dll 을 덮어 부드럽습니다.이 메커니즘을 사용하는 그림자를 복사.

핸들을 닫는 외부로부터 응용 프로그램지 않는 것이 정말로 매우 안전하고 있습니다.

그것은 해결책이 아니 어쩌면에는 아이디어이나 방향으로...

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top