问题标签 [safehandle]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
86 浏览

c# - Marshal.Release() 是否有隐含的 ReliabilityContract?

我正在编写一个 .NET 应用程序,我必须使用 API 调用(真的)。我的应用程序通过调用 Win API 的函数来获取 COM 接口CoCreateInstance()

当然,我必须在完成这些接口后释放它们。我认为这样做的适当方法是Marshal.Release()(至少,我没有想到其他合理的方法)。

现在,我想让每个相应的接口指针成为一个安全句柄。为此,我必须从中派生我自己的安全句柄类,SafeHandle并且必须在派生类中重写ReleaseHandle()。相应的文档指出:

[...] 特别是,将 ReliabilityContractAttribute 属性应用于您从 ReleaseHandle 调用的任何方法。在大多数情况下,此代码应为: ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success) [...]

这是我的问题:我不知道Marshal.ReleaseHandle()默认情况下是否已经有了这个合同,如果没有,我该如何添加它。我想我在这里缺乏一些基础知识。有人可以在那里阐明一下吗?

0 投票
0 回答
269 浏览

interop - 互操作、重叠 I/O、句柄:使用 SafeHandle 还是 pin?

当您将非托管句柄(存储在托管端的 IntPtr 或 SafeHandle 中)从托管代码传递到非托管代码以执行重叠 I/O 时,正确的方法是什么?

  • 使用 SafeHandle 将 (IntPtr) 操作系统句柄包装在其中,
  • 或使用 GCHandle.Alloc(IntPtrHandle, GCHandleType.Pinned) 固定它?

我目前正在将 SafeHandle 与 NativeOverlapped 结构结合使用,但我开始越来越怀疑 GC 在内存中移动一个或两个,而不受管理的重叠 IO 正在进行。

我会更好地回到使用 IntPtr 而不是 SafeHandle,并使用 GCHandle 结构来固定它吗?

或者正确的方法是所有的组合,即在你的 NativeOverlapped 中,使用 IntPtr 的固定版本,而 IntPtr 又来自 SafeHandle?

- 编辑

午饭时回想起来,我觉得我很愚蠢。它必须是需要固定的重叠结构,而不是其中的手柄。这是正确的(最佳)答案吗?

0 投票
1 回答
290 浏览

c# - 哪些“IntPtr”风格是“SafeHandle”的候选者

我得到一个 CA2006 (" Review usage of ... (a 'IntPtr' instance) to determine whether it should be replaced with a SafeHandle or CriticalHandle") 用于IntPtr返回ConvertStringSecurityDescriptorToSecurityDescriptor一个我知道的安全描述符,可以使用FreeLocal. 我只是简单地使用它,可能不会泄漏所涉及的内存。据我所知,没有关联内核句柄。

有很多SafeHandle子类,它们似乎都没有FreeLocal在包装对象的生命结束时调用。但是,我找不到任何关于哪些IntPtr实例(例如,由 Win32 API 返回)由 a 有效管理SafeHandle而哪些不是的确切信息。

我应该只取消 CA 警告吗?

更重要的是,如何确定IntPtr我将遇到的下一个用法相同?

(将SafeHandle子类映射到最终将释放句柄的函数的表会很棒。)

0 投票
1 回答
2963 浏览

c# - 安全手柄已关闭 - 修复的众多选项

我有一个私有函数,它创建一个新的串行端口并打开它。有时,我会收到“安全句柄已关闭”异常,这会终止应用程序。现在,我一直在阅读一些可选的修复程序,并想从您的经验中了解,我的代码中真正的问题可能是什么。1)需要在_serialPort这个私有函数的范围之外定义变量。2) 串口的 readTimeout 属性不应该是无限的。3) 上面的 using 语句处理我的portName变量。

谢谢!

0 投票
1 回答
248 浏览

c# - 无法将 ReleaseHandle 中的 SafeHandle 实例传递给本机方法

我最近才了解到SafeHandle,为了测试,我为 SDL2 库实现了它,创建和销毁一个窗口:

这很好用,然后我了解到使用的另一个优点SafeHandle:可以直接使用 p/invoke 签名中的类,如下所示:

这当然比泛型IntPtr参数/返回要好得多,因为我有类型安全Window向/从这些方法传递/检索实际(句柄)。

虽然这适用于SDL_CreateWindow,它现在正确返回一个Window实例,但它不适用于SDL_DestroyWindow,它由我在内部调用,Window.ReleaseHandle如下所示:

当试图传递this给时SDL_DestroyWindow,我得到一个ObjectDisposedException安全句柄已关闭。确实,该IsClosed物业是true,我没想到此时会出现。显然它在内部尝试增加引用计数,但注意IsClosedtrue. 根据文档,它已设置为true因为“调用了 Dispose 方法或 Close 方法,并且在其他线程上没有对 SafeHandle 对象的引用。”,所以我猜Dispose之前在调用堆栈中隐式调用了我的ReleaseHandle.

ReleaseHandle如果我想在 p/invoke 签名中使用类参数,显然不是清理的正确位置,所以我想知道是否有任何方法可以在不破坏SafeHandle内部结构的情况下进行清理?

0 投票
2 回答
86 浏览

c# - 如何防止相同的非托管指针被封装在两个不同的 SafeHandles 中?

我正在为用 C 编写的游戏引擎编写一个托管包装器来挑战自己。我已经开始将非托管指针包装在SafeHandle派生类中,但我认为调用可能返回相同指针的非托管函数可能会创建新的 SafeHandles,如果其中一个被释放,其余的将变得无效。

我怎样才能有效地防止这种情况发生?我怀疑编组器会自动跟踪重复项...

0 投票
0 回答
291 浏览

c# - 使用 SafeHandle 作为参考参数的 P/Invoke

我在非托管 Dll 中有一个函数,它需要一个指向句柄的指针,如该示例:

如何在不使用 DangerousGetHandle 的情况下从 C# 调用它?

这不起作用(抛出 .ctor 的 MissingMethodException ):

0 投票
0 回答
582 浏览

c# - 用什么代替 SafeHandle.DangerousGetHandle?

I was looking at my SonarQube static code analysis and came across a report that says using a SafeTokenHandle DangerousGetHandle method call.

I start by declaring a SafeTokenHandle:

检查它对我的登录方法的返回值。

Use a basic "using" which I log the value of the SafeTokenValue:

然后我有另一个 using 使用“DangerousGetHandle”方法设置一个新的 WindowsItentity:

有没有办法在不使用“DangerousGetHandle”方法的情况下继续获取该信息,还是我只需要接受这方面的风险?

微软表示:“DangerousGetHandle 方法可能带来安全风险”主要是因为引用变得陈旧,这可能导致它访问敏感信息。

看起来使用DangerousAddRefDangerousRelease是微软的建议,但这些似乎也有风险。任何方向都会有所帮助。

0 投票
0 回答
1042 浏览

c# - WinAPI 中的 SafeHandle 与 IntPtr 和 C# 中的 CloseHandle

我阅读了很多关于SafeHandleIDiposable我仍然不明白是否应该在 C# 中使用 SafeHandle 和 CloseHandle。

MSDN SafeHandle 示例

IntPtr、SafeHandle 和 HandleRef - 解释

https://blog.benoitblanchon.fr/safehandle/

第一个来源类似于我的问题,但它没有回答我的问题。

假设我有以下 3 个从 Internet 获得的不同示例:

这些示例是 Windows API,因此它们是非托管的。我不明白的是:

1)所有 3 个示例是否应该使用 SafeHandle 而不是 IntPtr,因为它们是非托管的,如果其中一个不应该,为什么?

2) 我发现 CloseHandle 在 C/C++ 中是一个很好的做法,但在 C# 中我不知道垃圾收集器最终是否会自动关闭句柄?在上面的例子中应该使用 CloseHandle 吗?为什么?

3) 第一个示例使用非托管byte*在堆上分配内存。这个过程可以通过不使用非托管指针来完成吗?下面的代码是我的猜测,你怎么看?

编辑: 发布我编辑的代码:

你认为我做的一切都好吗?应该SafeHandle在每个 Windows API 上使用,比如GetModuleHandle, GetProcAddressMapViewOfFile还有一些我现在不记得了。他们中的一些人正在返回LPVOID

0 投票
2 回答
3438 浏览

vb.net - 通过 USB 将原始文本发送到打印机

我正在尝试将 ZPL 命令发送到 Zebra ZT230 打印机。打印机和驱动程序已安装,打印机端口为“USB003”。PC 通过 Zebra Printer Setup Utilities 或 ZebraDesign 与打印机完美通信。我尝试了以下代码:

我在这一行收到错误: Dim printer As System.Runtime.InteropServices.SafeHandle = CreateFile("USB003:", FileAccess.ReadWrite, 0, IntPtr.Zero, FileMode.Open, 0, IntPtr.Zero)

错误消息和堆栈跟踪是:

无法编组“返回值”:返回的 SafeHandles 不能是抽象的。

在 PerfectPotatoInventory.vb.PotatoGlobals.CreateFile(String& lpFileName, FileAccess dwDesiredAccess, UInt32 dwShareMode, IntPtr lpSecurityAttributes, FileMode dwCreationDisposition, UInt32 dwFlagsAndAttributes, IntPtr hTemplateFile) 在 PerfectPotatoInventory.vb.PotatoGlobals.PrintLabelsTest() 在 C:\Potatoes\PerfectPotato.b PerfectPotatoInventory.vb\PotatoGlobals.vb:798 行

我正在使用带有目标 x86 和 .Net 3.5 的 VS2008 在 VB.net 中工作。

请告知我做错了什么。