【问题标题】:How to release a handle through C#?如何通过 C# 释放句柄?
【发布时间】:2009-08-04 06:33:26
【问题描述】:

我有一个应用程序会隐式打开 dll/文件的句柄。在应用程序的某个时刻,我想释放这个句柄。我该怎么做?我的应用程序是 C#。

【问题讨论】:

  • 有问题的文件是什么?它是资源还是引用的程序集?您似乎肯定知道它为什么打开,这是对它的用途和何时关闭的最大暗示。介意让我们进去吗?
  • 280Z28 所说的一切......加上“影子副本”;-p
  • 好的。我的应用程序正在使用 GUI 自动化工具对安装程序进行一些测试。我启动安装程序,(xyx.exe)使用自动化工具生成的代码来执行使用安装程序更新软件的 GUI 操作。在此期间,“xyz.exe”上打开了一个不会关闭的句柄。这是我要关闭的句柄。生成的代码包含所有静态成员,因此我无法调用 Dispose 或 Close 方法。我也没有加载程序集,因此我无法创建另一个应用程序域,然后在使用后将其卸载。

标签: c# handle filehandle


【解决方案1】:

如果您有要关闭的处理程序,请使用 PInvoke

[System.Runtime.InteropServices.DllImport("Kernel32")]
private extern static Boolean CloseHandle(IntPtr handle);

【讨论】:

  • 但是我如何找出我必须关闭的句柄。我只知道文件名。我的进程在该文件上打开的句柄未知。
  • 你使用Process类来启动exe吗?
【解决方案2】:

你到底想做什么?如果你想加载一个程序集来做一些事情,然后完全卸载它,你需要依赖创建一个新的应用程序域。

public static void Main(string[] args)
{
AppDomain appDomain = AppDomain.CreateDomain("NewAppDomain");
appDomain.DoCallBack(new CrossAppDomainDelegate(AsmLoad));

// At this point, your assembly is locked, you can't delete

AppDomain.Unload(appDomain);
Console.WriteLine("AppDomain unloaded");

//You've completely unloaded your assembly. Now if you want, you can delete the same

}

public static void AsmLoad()
{
Assembly assembly = Assembly.LoadFrom(@"c:\Yourassembly.dll");

//Loaded to the new app domain. You can do some stuff here
Console.WriteLine("Assembly loaded in {0}",AppDomain.CurrentDomain.FriendlyName);
}

请查看此帖子了解更多信息,http://blogs.msdn.com/suzcook/archive/2003/07/08/57211.aspx

或者,如果您只是担心 保持文件锁定,您可以使用 影子复制。这将制作一个副本 磁盘上的文件并从 新位置。原始文件 不会被该负载锁定。到 这样做,设置 AppDomainSetup.ShadowCopyFiles 到 创建 AppDomain 时为“true”或 将 AppDomain.ShadowCopyFiles 设置为 true 在它已经创建之后。

【讨论】:

    【解决方案3】:

    只需使用打开句柄的类的 Dispose 或 Close 方法即可。

    【讨论】:

      【解决方案4】:

      我不知道一个简单的方法。过度隐式文件锁定是我一直不喜欢 Windows 的地方。

      如果您需要替换文件,MoveFileEx 可以在下次启动时完成。您将使用它来重命名或删除原始文件,然后将其他内容重命名到它的位置。 http://msdn.microsoft.com/en-us/library/aa365240(VS.85).aspx http://www.pinvoke.net/default.aspx/kernel32/MoveFileEx.html

      如果您不想直接使用 API,那么 SysInternals 套件中的 MoveFile 也可以做到这一点:http://technet.microsoft.com/en-us/sysinternals/bb897556.aspx

      或者您可以让其他程序在您的程序未运行时访问该文件。

      如果您真的想尝试关闭句柄,有一些方法可以获取每个进程的句柄列表,如果 .NET 再次尝试访问它,这很可能会使您的程序崩溃。它不漂亮,示例是 C++: http://www.codeguru.com/forum/showthread.php?t=176997

      【讨论】:

        猜你喜欢
        • 2011-02-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-29
        • 2012-12-02
        • 2011-02-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多