【问题标题】:How to convert IntPtr to SafeHandle?如何将 IntPtr 转换为 SafeHandle?
【发布时间】:2017-09-09 09:04:19
【问题描述】:

我有 C# Windows 服务类:

class MyService : ServiceBase
{
    private void InitializeComponent() {
       //some other code ...
       SafeHandle sHandle = this.ServiceHandle; // I want to do this but this fails.
       SetServiceObjectSecurity(sHandle, secInfo, binaryDescriptor);
       //some more code ...
    }
}

如何将 IntPtr(如 this.ServiceHandle)转换为“System.Runtime.InteropServices.SafeHandle”?以便我可以在函数调用“SetServiceObjectSecurity()”中使用它? 我的最终目标是授予该服务的管理员权限。

【问题讨论】:

  • 我原以为你根本不需要进入 pinvoke-land。您确定您需要的安全功能不在某些托管代码库中吗?例如msdn.microsoft.com/en-us/library/…
  • ServiceBase.ServiceHandle 是一个普通的 IntPtr,而不是 SafeHandle。让它成为一个安全句柄没有任何意义,服务总是有一个句柄,并且在服务终止之前它一直有效。并且没有需要安全的清理,它只是眨眼就消失了。只需修复您的 pinvoke 声明并将第一个参数也设为 IntPtr。
  • @Neil:这些类是可用的,但确实需要一些努力。特别是,没有开箱即用的 ServiceSecurityServiceAccessRule 类。这些总共大约有 50 行代码(大部分是样板代码)。从好的方面来说,这意味着您不必乱用安全描述符或非托管调用。

标签: c# interop interopservices


【解决方案1】:

您是否尝试过按照此处https://msdn.microsoft.com/de-de/library/system.runtime.interopservices.safehandle.sethandle(v=vs.110).aspx 的说明使用SafeHandle.SetHandle(IntPtr handle),看看是否适合您?

编辑: 由于SafeHandle.SetHandle(IntPtr handle) 是受保护的方法,您可以像这样创建派生类:

public class SafeHandleExtended : SafeHandle
{
    public void SetHandleExtended(IntPtr handle)
    {
        this.SetHandle(handle);
    }

    // .. SafeHandle's abstract methods etc. that you need to implement
}

虽然我还没有测试过它的正确性,所以我不知道这是否能如你所愿。

【讨论】:

  • 我无法从任何一个 SafeHandle 实例访问 SetHandle() 方法,如下所示:“SafeHandle sHandle; sHandle.SetHandle();”或直接使用“SafeHandle.SetHandle();”
  • @Arnoj 哦,对不起,我刚刚看到这是一个protected 方法,所以你不能使用它是正确的。我现在正在寻找替代品。
  • @Arnoj 感谢您将其作为公认的答案。我很高兴能帮上忙,而且现在可以了。祝你好运
猜你喜欢
  • 1970-01-01
  • 2013-08-12
  • 2010-09-07
  • 2016-12-07
  • 1970-01-01
  • 2010-10-06
  • 2010-10-20
  • 2010-10-23
  • 1970-01-01
相关资源
最近更新 更多