Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 封送Win32结构(进程信息)时的安全句柄_C#_Winapi_Pinvoke_Safehandle - Fatal编程技术网

C# 封送Win32结构(进程信息)时的安全句柄

C# 封送Win32结构(进程信息)时的安全句柄,c#,winapi,pinvoke,safehandle,C#,Winapi,Pinvoke,Safehandle,我正在将Win32 p/invoke代码转换为使用SafeHandle类,而不是典型的IntPtr句柄 虽然在DllImport方法签名中一切都很好,但在封送Win32结构(即PROCESS\u INFORMATION)时,我无法让它们工作 ProcessSafeHandle和ThreadSafeHandle类与ReadProcessMemory或WriteProcessMemory等方法配合使用效果很好,但我无法在上述Win32结构中使用它们 我是否缺少某种注释魔力?据我所知*,互操作封送拆收

我正在将Win32 p/invoke代码转换为使用
SafeHandle
类,而不是典型的
IntPtr
句柄

虽然在
DllImport
方法签名中一切都很好,但在封送Win32结构(即
PROCESS\u INFORMATION
)时,我无法让它们工作

ProcessSafeHandle
ThreadSafeHandle
类与
ReadProcessMemory
WriteProcessMemory
等方法配合使用效果很好,但我无法在上述Win32结构中使用它们

我是否缺少某种注释魔力?

据我所知*,互操作封送拆收器不支持在类/结构中使用安全句柄

因此,在p/Invoke函数声明中用
SafeHandle
替换
IntPtr
效果很好,但在结构中替换它不起作用。
PROCESS\u INFORMATION
结构中的句柄必须由不了解托管
SafeHandle
类的非托管代码初始化,因此CLR需要具备如何执行所需
[out]
封送的专业知识

但不用担心。按原样声明结构没有问题:

[StructLayout(LayoutKind.Sequential)]
internal struct Win32ProcessInformation
{
    public IntPtr ProcessHandle { get; set; }
    public IntPtr ThreadHandle { get; set; }
    public int ProcessId { get; set; }
    public int ThreadId { get; set; }
}
如果需要,调用填充
Win32ProcessInformation
结构的函数后,可以为存储在intptr中的每个句柄值创建
SafeHandle
对象。这将确保在对象被垃圾回收时关闭句柄(如果您之前忘记调用
Dispose()

对于进程句柄(如本例中所示),将是一个不错的选择,因为所有进程句柄都是可等待的。这使您不必做任何额外的工作,因为
SafeWaitHandle
已经作为SafeHandle的公共专门化提供。(说到做额外的工作,我假设您已经检查了
流程
类是否已经包装了调用流程API的原因?)


*这可能在某些最新版本的CLR上发生了变化;我的知识有些过时。

我对.net一无所知,但只要看看
SafeHandle
类,它的构造函数就有两个参数(一个
IntPtr
和一个
bool
表示所有权)。我不知道封送员怎么知道
bool
应该是真的还是假的。说得好。我已经尝试让我的
SafeHandle
子类中的构造函数只接受
IntPtr
(假设布尔始终为
true
)。不幸的是,仍然没有骰子。只是不要试图把所有的骰子都敲进一个洞里。使用两个声明,一个声明仅用于互操作调用,另一个声明(通常为类)用于存储安全句柄。与方法相比,请注意结尾处对SetProcessHandle的调用。@JonathanPotter,封送拆收器使用默认构造函数,并具有安全句柄的特殊知识,允许它设置句柄。SafeHandle的特定子类应提供一个默认构造函数,该构造函数传入一个合适的bool。@Erik_at_Digit,您是否用表示无效句柄的实例预先填充句柄字段?我发现我需要预先填充用于ref参数的SafeHandle变量,结构可能有相同的要求。谢谢,完全忘记了
SafeWaitHandle
。使我不用编写子类。不幸的是,内置的
Process
类没有公开任何访问进程内存的方法(
ReadProcessMemory
WriteProcessMemory
)。我已经创建了一个流子类来包装这些方法。此外,内置的
Process
类不允许创建带有标志(如suspended)的进程。因此,我必须使用
CreateProcess
Win32 API来实现这一点。
[StructLayout(LayoutKind.Sequential)]
internal struct Win32ProcessInformation
{
    public IntPtr ProcessHandle { get; set; }
    public IntPtr ThreadHandle { get; set; }
    public int ProcessId { get; set; }
    public int ThreadId { get; set; }
}