dll调用

主  题:  dll调用
作  者:  lornwolf80 (孤独的狼)
等  级:  ^
信 誉 值:  100
所属论坛:  .NET技术 C#
问题点数:  100
回复次数:  18
发表时间:  2003-9-24 19:25:35

调用AdvAPI32.Dll中的EnumServicesStatus函数

[DllImport("AdvAPI32.Dll",CharSet=CharSet.Auto)]
public static extern bool EnumServicesStatus(
    IntPtr handle,
    ServiceType type,
    ServiceActiveStatus activestatus,
    [In,Out]EnumServiceStatus[] servicestatus,
    int bufsize,
    ref int byteneeded,
    ref int servicesreturn,
    ref int resumehandle
);

所需结构如下:

[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Auto)]
public struct ServiceStatus
{
    public ServiceType Type;
    public ServiceCurrentType CurrentType;
    public SerivceControlAccepted ControlAccepted;
    public int Win32ExitCode;
    public int ServiceSpecificExitCode;
    public int CheckPoint;
    public int WaitHint;
}

[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Auto)]
public struct EnumServiceStatus
{
    [MarshalAs(UnmanagedType.LPTStr)]
    public String ServiceName;
    [MarshalAs(UnmanagedType.LPTStr)]
    public String DisplayName;
    public ServiceStatus status;
}

请问这样对否?
运行时出现“未将对象引用设置到对象的实例”错误?
调用如下:

IntPtr handle=EcService.OpenSCManager(null,null,ServicesAccess.AllAccess);
try
{
    EnumServiceStatus[] ess;
    ess=new EnumServiceStatus[100];
    int bufsize=Marshal.SizeOf(ess[0])*ess.Length;
    int sreturn,rhandle,bneeded;
    sreturn=rhandle=bneeded=0;
    EcService.EnumServicesStatus(handle,
            ServiceType.ServiceWin32,
            ServiceActiveStatus.StateAll,
        ess,bufsize,ref bneeded,ref sreturn,ref rhandle);
}
finally
{
    EcService.CloseServiceHandle(handle);
}


回复人: changezhong(小刀) ( 二级(初级)) 信誉:100 2003-9-24 19:33:40 得分:10

gz

回复人: xswh418(大衰哥) ( 四级(中级)) 信誉:100 2003-9-24 19:39:57 得分:10

楼主什么意思?

回复人: lornwolf80(孤独的狼) ( 一级(初级)) 信誉:100 2003-9-24 19:42:37 得分:0

我现在使用这个函数时,出现错误提示“未将对象引用设置到对象的实例”
不知道是什么地方错了?

回复人: Lorenes(晓帆) ( 二级(初级)) 信誉:99 2003-9-24 19:44:18 得分:0

调用方法基本正确,

WINDOWS中有很多怪问题出现null Exception的.

try{
...
}catch(Exception){

}

容错就好.

回复人: cnhgj(戏子.Com?俺真TMD够菜) ( 两星(中级)) 信誉:100 2003-9-24 19:44:28 得分:10

调用API函数不用new实例

回复人: Lorenes(晓帆) ( 二级(初级)) 信誉:99 2003-9-24 19:45:17 得分:10

对了,静态的API调是static 的.

回复人: lornwolf80(孤独的狼) ( 一级(初级)) 信誉:100 2003-9-24 19:48:42 得分:0

我使用new 是开辟数组空间,函数原型如下

BOOL EnumServicesStatus(
  SC_HANDLE hSCManager,
  DWORD dwServiceType,
  DWORD dwServiceState,
  LPENUM_SERVICE_STATUS lpServices,
  DWORD cbBufSize,
  LPDWORD pcbBytesNeeded,
  LPDWORD lpServicesReturned,
  LPDWORD lpResumeHandle
);

回复人: yaoyaonet(绿洲) ( 四级(中级)) 信誉:100 2003-9-24 19:49:18 得分:10

ess=new EnumServiceStatus[100]; --》ess=EnumServiceStatus[100]; 试试。。。

回复人: lornwolf80(孤独的狼) ( 一级(初级)) 信誉:100 2003-9-24 19:52:53 得分:0

yaoyaonet(绿洲)
编译都不通过:(
还有这个函数是用来枚举windows2000的服务,
我试了,如果调用函数时出错,将不能完全枚举服务

回复人: kuangren(今天逃课~) ( 三级(初级)) 信誉:100 2003-9-24 19:54:53 得分:10

恩,up

回复人: zhouzhouzhou(人生程序) ( 四级(中级)) 信誉:100 2003-9-24 19:55:50 得分:10

支持

回复人: easydone(水泥) ( 一级(初级)) 信誉:100 2003-9-24 19:58:31 得分:10

在C#中使用API首先要使用引入名字空间:
using System.Runtime.InteropServices;
然后
[DllImport("AdvAPI32")]
+函数说明

回复人: lornwolf80(孤独的狼) ( 一级(初级)) 信誉:100 2003-9-24 20:01:37 得分:0

using System.Runtime.InteropServices;名称空间已经引用
编译都通过了,是在运行时出现的错误提示,用try...catch...finally
捕捉异常,将不能得到一个我所需要的东西.

回复人: xz_king(西杀魄工人) ( 五级(中级)) 信誉:100 2003-9-24 20:09:56 得分:10

帮你up

回复人: Gao2003(Gao) ( 四级(中级)) 信誉:100 2003-9-24 20:18:14 得分:10

把API和结构的C原形贴出来

回复人: lornwolf80(孤独的狼) ( 一级(初级)) 信誉:100 2003-9-24 20:24:58 得分:0

函数原型:

BOOL EnumServicesStatus(
  SC_HANDLE hSCManager,
  DWORD dwServiceType,
  DWORD dwServiceState,
  LPENUM_SERVICE_STATUS lpServices,
  DWORD cbBufSize,
  LPDWORD pcbBytesNeeded,
  LPDWORD lpServicesReturned,
  LPDWORD lpResumeHandle
);

C#结构

[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Auto)]
public struct ServiceStatus
{
    public ServiceType Type;
    public ServiceCurrentType CurrentType;
    public SerivceControlAccepted ControlAccepted;
    public int Win32ExitCode;
    public int ServiceSpecificExitCode;
    public int CheckPoint;
    public int WaitHint;
}
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Auto)]
public struct EnumServiceStatus
{
    [MarshalAs(UnmanagedType.LPTStr)]
    public String ServiceName;
    [MarshalAs(UnmanagedType.LPTStr)]
    public String DisplayName;
    public ServiceStatus status;
}

使用的枚举类型

public enum ServiceCurrentType
{
    Stopped         =0x00000001,
    StartPending    =0x00000002,
    StopPending     =0x00000003,
    Running         =0x00000004,
    ContinuePending =0x00000005,
    PausePending    =0x00000006,
    Paused          =0x00000007
}
public enum ServiceType
{
    KernelDriver        =0x00000001,
    FileSystemDriver    =0x00000002,
    Adapter             =0x00000004,
    RecognizerDriver    =0x00000008,
    ServiceDriver       =(KernelDriver|FileSystemDriver|RecognizerDriver),
    Win32_OwnProcess    =0x00000010,
    Win32_ShareProcess  =0x00000020,
    ServiceWin32        =(Win32_OwnProcess|Win32_ShareProcess),
    InterActiveProcess  =0x00000100,
    TypeAll             =(Adapter|ServiceDriver|ServiceWin32|InterActiveProcess)
}
public enum SerivceControlAccepted
{
    Stop                =0x00000001,
    PauseContinue       =0x00000002,
    Shutdown            =0x00000004,
    ParamChange         =0x00000008,
    NetBindChange       =0x00000010,
    HardwareProfileChange   =0x00000020,
    PowerEvent              =0x00000040,
    SessionChange           =0x00000080
}
public enum ServiceActiveStatus
{
    Active      =0x00000001,
    InActive    =0x00000002,
    StateAll    =(Active|InActive)
}

详细的API说明在
ms-help://MS.MSDNQTR.2003FEB.2052/dllproc/base/enumservicesstatus.htm中

该问题已经结贴 ,得分记录: changezhong (10)、 xswh418 (10)、 cnhgj (10)、 Lorenes (10)、 yaoyaonet (10)、 kuangren (10)、 zhouzhouzhou (10)、 easydone (10)、 xz_king (10)、 Gao2003 (10)、

Contributors: FHL