2017-04-13 54 views
1

我有C#的Windows服务类:如何将IntPtr转换为SafeHandle?

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()”中使用它? 我的最终目标是授予管理员对服务的许可。

+0

我本来以为你根本不需要进入安全地带。您确定您需要的安全功能尚未存在于某些托管代码库中吗?例如https://msdn.microsoft.com/en-us/library/system.security.accesscontrol(v=vs.110).aspx – Neil

+2

ServiceBase.ServiceHandle是一个普通的IntPtr,而不是SafeHandle。没有任何意义使它成为一个安全的句柄,一个服务总是有一个句柄,它在服务终止之前一直有效。没有需要保护的清理工作,它只是眨眼而已。简单地修复您的pinvoke声明并将第一个参数设置为IntPtr。 –

+0

@尼尔:这些类是可用的,但需要一些努力。特别是,没有开箱即用的“ServiceSecurity”或“ServiceAccessRule”类。这些总共大约50行代码(主要是样板文件)。另一方面,这意味着您不必使用安全描述符或非托管调用。 –

回答

0

您是否尝试过使用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 
} 

虽然我没有的正确性测试这一点,所以我不知道这是否你的方式想要它。

+0

我没有从任何一个SafeHandle实例访问SetHandle()方法,如下所示:“SafeHandle sHandle; sHandle.SetHandle();”或直接使用“SafeHandle.SetHandle();” – Arnoj

+0

@Arnoj哦,我很抱歉,我刚刚看到它是一种“受保护的”方法,因此您无法使用它是正确的。我正在寻找替代品。 –

+0

@Arnoj编辑了我的答案,也许它现在适合你 –