如何将IntPtr转换为SafeHandle?

3

我有一个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()”中使用它了。我的最终目标是给服务提供管理员权限。

我本以为你根本不需要涉及到P/Invoke。你确定你所需的安全功能不已经存在于某个托管代码库中吗?例如:https://msdn.microsoft.com/zh-cn/library/system.security.accesscontrol(v=vs.110).aspx - Neil
2
ServiceBase.ServiceHandle是一个普通的IntPtr,而不是SafeHandle。没有必要将其设置为安全句柄,因为服务始终具有句柄,并且在服务终止之前保持有效。而且没有需要进行安全清理的操作,它只是消失了。只需修复您的pinvoke声明,并将第一个参数也设置为IntPtr即可。 - Hans Passant
@Neil:这些类是可用的,但需要一些努力。特别是,开箱即用没有ServiceSecurityServiceAccessRule类。总共大约有50行代码(主要是样板代码)。好的一面是,这意味着您不必在安全描述符或非托管调用上瞎折腾。 - Jeroen Mostert
1个回答

1

你尝试过使用 SafeHandle.SetHandle(IntPtr handle) 方法吗?在这里有解释 https://msdn.microsoft.com/de-de/library/system.runtime.interopservices.safehandle.sethandle(v=vs.110).aspx,你可以试试看是否有效果。

编辑: 由于 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
@Arnoj 哦,对不起,我刚刚看到这是一个protected方法,所以你不能使用它是正确的。我正在寻找替代方案。 - Thomas Flinkow
@Arnoj 感谢您将此回答设为最佳答案。我很高兴能够帮到您,现在它已经起作用了。祝您进一步好运。 - Thomas Flinkow

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接