我试了调用了几次都出错。。       [StructLayout(LayoutKind.Sequential)]
        
        public struct QUERY_SERVICE_CONFIG
        {
            public int dwServiceType;
            public int dwStartType;
            public int dwErrorControl;
            public string lpBinaryPathName;
            public string lpLoadOrderGroup;
            public int dwTagId;
            public string lpDependencies;
            public string lpServiceStartName;
            public string lpDisplayName;        }        [StructLayout(LayoutKind.Sequential)]
        public struct SERVICE_DESCRIPTION
        {
            public string lpDescription;
        }        //连接服务控制管理器
        [DllImport("Advapi32.dll")]
        public extern static int OpenSCManager(string lpMachineName, string lpDatabaseName, int dwDesiredAccess);
        //打开服务
        [DllImport("Advapi32.dll")]
        public extern static int OpenService(int hSCManager, string lpServiceName, int dwDesiredAccess);
        //获取服务配置
        [DllImport("Advapi32.dll")]
         public extern static bool QueryServiceConfig(int hService, out QUERY_SERVICE_CONFIG QueryServiceConfig, int cbBufSize, out int pcbBytesNeeded);
        //获取服务描述
        [DllImport("Advapi32.dll")]
        public extern static bool QueryServiceConfig2(int hService, int dwInfoLevel, out SERVICE_DESCRIPTION ServiceDescription, int cbBufSize, out int pcbBytesNeeded);
        //获取错误代码
        [DllImport("Kernel32.dll")]
        public extern static int GetLastError();        public QUERY_SERVICE_CONFIG qsc = new QUERY_SERVICE_CONFIG();
        public SERVICE_DESCRIPTION sd = new SERVICE_DESCRIPTION();
        public void GetLocalServiceAttribute(String serviceName)
        {
            int hSCManager = OpenSCManager(null, null, 0xF003F);////SC_MANAGER_ALL_ACCESS (0xF003F)
            if (hSCManager != 0)
            {
                int hService = OpenService(hSCManager, serviceName, 0xF01FF);////SERVICE_ALL_ACCESS (0xF01FF)
                if (hService != 0)
                {
                    int dwError = 0, cbBufSize = 0, dwBytesNeeded = 0;                    if (!QueryServiceConfig(hService, out qsc, 0, out dwBytesNeeded))//
                    {
                        dwError = GetLastError();
                        if (dwError == 122)
                        {
                        cbBufSize = dwBytesNeeded;
                        }
                        else
                        {
                        //MessageBox.Show("Query Service: " + serviceName + "'s Config Failed!");
                        }
                    }
                    if (!QueryServiceConfig(hService, out qsc, cbBufSize, out dwBytesNeeded))//这里出错显示 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。 
                   {
                        // MessageBox.Show("Query Service: " + serviceName + "'s Config Failed!");
                    }                    if (!QueryServiceConfig2(hService, 1, out sd, 0, out dwBytesNeeded))
                    {
                        //第二个参数:dwInfoLevel:1==SERVICE_CONFIG_DESCRIPTION
                        dwError = GetLastError();
                        if (dwError == 122)
                        {
                            cbBufSize = dwBytesNeeded;
                            if (!QueryServiceConfig2(hService, 1, out sd, cbBufSize, out dwBytesNeeded))))//这里出错显示 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。                             {
                                //MessageBox.Show("Query Service: " + serviceName + "'s Description Failed!");
                            }
                        }
                        else
                        {
                            // MessageBox.Show("Query Service: " + serviceName + "'s Description Failed!");
                        }
                    }
                }
                else
                {
                    // MessageBox.Show("OpenService " + serviceName + " Failed!");
                }
            }
            else
            {
                // MessageBox.Show("OpenSCManager Failed!");
            }
        }

解决方案 »

  1.   

    解决了。。我认为是权限问题。。
    OpenSCManager(null, null, 0xF003F);////这里的对的。。
    OpenService(hSCManager, serviceName,0xF01FF);//这里改成0x00001还是不行。。于是我用c++写了个dll。调用成功获得服务的描述和服务文件的路径。
    CReadService.hstruct CServerRead
    {
     char * DisplayName;
     int ServiceType;
     char * ServicePath;
     char * ServiceMs;
    };
    typedef void(_stdcall *CallBackService)(CServerRead);
    void _stdcall OutService(char * ServiceName,CallBackService mae);CReadService.cppvoid _stdcall OutService(char * ServiceName,CallBackService callmae)
    {
    CServerRead   mae;
    SC_HANDLE scm; if((scm=::OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS))==NULL)  
    {
    //return false;
    }
    SC_HANDLE service=NULL;
    service=OpenService(scm,ServiceName,SERVICE_QUERY_CONFIG); LPQUERY_SERVICE_CONFIG ServicesInfo; 
    LPSERVICE_DESCRIPTION lpsd; DWORD nResumeHandle=0;
    DWORD cbBufSize, dwError; 
    //QueryServiceConfig( service, NULL, 0, &nResumeHandle); if( !QueryServiceConfigA( service, NULL, 0, &nResumeHandle)) //The QueryServiceConfig2 function retrieves the optional configuration parameters of the specified service
    {
    dwError = GetLastError();
    if( ERROR_INSUFFICIENT_BUFFER == dwError )
    {
    cbBufSize = nResumeHandle;
    ServicesInfo = (LPQUERY_SERVICE_CONFIG) LocalAlloc(LMEM_FIXED, cbBufSize);
    }
    else
    {
    //return false;
    }
    }
    //EnumDependentServices();
    //GetServiceDisplayName();
    //http://www.hackline.net/a/school/ymbc/C/2010/0729/5062.html
    if(!::QueryServiceConfigA(service,ServicesInfo,cbBufSize,&nResumeHandle))
    {
    //return false;
    } if( !QueryServiceConfig2A( service, SERVICE_CONFIG_DESCRIPTION,NULL, 0, &nResumeHandle)) //The QueryServiceConfig2 function retrieves the optional configuration parameters of the specified service
    {
    dwError = GetLastError();
    if( ERROR_INSUFFICIENT_BUFFER == dwError )
    {
    cbBufSize = nResumeHandle;
    lpsd = (LPSERVICE_DESCRIPTION) LocalAlloc(LMEM_FIXED, cbBufSize);
    }
    else
    {
    //return false;
    }
    }
    if (! QueryServiceConfig2A(service, SERVICE_CONFIG_DESCRIPTION,(LPBYTE) lpsd, cbBufSize, &nResumeHandle)) 
    {
    //return false;
    } mae.DisplayName=ServicesInfo->lpDisplayName;
    mae.ServicePath=ServicesInfo->lpBinaryPathName;
    mae.ServiceType=ServicesInfo->dwServiceType;
    mae.ServiceMs=lpsd->lpDescription; callmae(mae); LocalFree(ServicesInfo);
    LocalFree(lpsd); CloseServiceHandle(service);
    CloseServiceHandle(scm);
    //return true;
    }还是希望找到c#直接调用的方法。哪位高手请指点下。。
    1楼:错误是:其他信息: 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
      

  2.   

    看错误应该是函数的声明不对参考下面的声明,里面的例程也可以参考http://pinvoke.net/default.aspx/advapi32/OpenSCManager.html
    http://pinvoke.net/default.aspx/advapi32/OpenService.html
    http://pinvoke.net/default.aspx/advapi32/QueryServiceConfig.html
    http://pinvoke.net/default.aspx/advapi32/QueryServiceConfig2.html