Tag: pinvoke

.NET:如何PInvoke UpdateProcThreadAttribute

我试图在Windows 7上PInvoke UpdateProcThreadAttribute()但我的尝试只是返回FALSE与最后Win32错误50。 Function declaration (from MSDN) BOOL WINAPI UpdateProcThreadAttribute( __inout LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList, __in DWORD dwFlags, __in DWORD_PTR Attribute, __in PVOID lpValue, __in SIZE_T cbSize, __out_opt PVOID lpPreviousValue, __in_opt PSIZE_T lpReturnSize ); 这是我对PInvoke签名的尝试: [DllImport(“kernel32.dll”, CallingConvention = CallingConvention.Winapi, SetLastError = true)] public static extern bool UpdateProcThreadAttribute ( IntPtr lpAttributeList, UInt32 dwFlags, ref UInt32 Attribute, ref IntPtr […]

如何将指针从C#传递到DLL中的本机函数?

这是我在DLL中的函数的签名: int __stdcall myFun( void * const context, const char * const pszFileName, const unsigned int buffSize, void * const pWaveFormatex ); 所有参数均为[in]。 用户应该通过最后一个参数将指针传递给WAVEFORMATEX结构。 返回后,它将被填补。 所有这些在C ++中都很有效。 现在,我正在尝试使用C#中的相同DLL,但它根本不起作用。 问题出在最后一个参数中。 由于我根本不了解C#,我想问一下这是否可行。 如果是,我会很感激一个例子。 我最后一次尝试是这样的: [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct WAVEFORMATEX { public ushort wFormatTag; public ushort nChannels; public uint nSamplesPerSec; public uint nAvgBytesPerSec; public ushort nBlockAlign; […]

DllImport – ANSI与Uni​​code

我对下面的测试问题的可能答案有一些疑问: 问题:您编写以下代码段以使用平台调用从Win32应用程序编程接口(API)调用函数。 string personName = “N?el”; string msg = “Welcome” + personName + “to club”!”; bool rc = User32API.MessageBox(0, msg, personName, 0); 您需要定义一个最能编组字符串数据的方法原型。 你应该使用哪个代码段? // A. [DllImport(“user32”, CharSet = CharSet.Ansi)] public static extern bool MessageBox(int hWnd, string text, string caption, uint type); } // B. [DllImport(“user32”, EntryPoint = “MessageBoxA”, CharSet = CharSet.Ansi)] public static extern […]

PInvoke:用C ++分配内存并在C#中释放它

我们正在使用PInvoke在C#和C ++之间进行交互。 我有一个如下的互操作结构,另一边有相同的布局C ++结构。 [StructLayout(LayoutKind.Sequential)] public struct MeshDataStruct : IDisposable { public MeshDataStruct(double[] vertices, int[] triangles , int[] surfaces) { _vertex_count = vertices.Length / 3; _vertices = Marshal.AllocHGlobal(_vertex_count*3*sizeof (double)); Marshal.Copy(vertices, 0, _vertices, _vertex_count); } // .. extract data methods to double[] etc. private IntPtr _vertices; private int _vertex_count; public void Dispose() { if (_vertices != […]

平台pinvoke教程msdn

以下是msdn的教程。 _flushall的输出在教程中是“Test”,但是通过使用console.write()显示输出我得到了“2”。 有人可以解释一下吗? using System; using System.Runtime.InteropServices; class PlatformInvokeTest { [DllImport(“msvcrt.dll”)] public static extern int puts(string c); [DllImport(“msvcrt.dll”)] internal static extern int _flushall(); public static void Main() { puts(“Test”); _flushall(); } }

统一处理非托管API中的错误代码

我正在编写一个包含相当大的非托管API的包装器。 几乎每个导入的方法在失败时都会返回一个常见的错误代码。 现在,我这样做: ErrorCode result = Api.Method(); if (result != ErrorCode.SUCCESS) { throw Helper.ErrorToException(result); } 这很好用。 问题是,我有很多非托管方法调用,这会非常令人沮丧和重复。 所以,我尝试切换到这个: public static void ApiCall(Func apiMethod) { ErrorCode result = apiMethod(); if (result != ErrorCode.SUCCESS) { throw Helper.ErrorToException(result); } } 这允许我将所有这些调用减少到一行: Helper.ApiCall(() => Api.Method()); 然而,这有两个直接的问题。 首先,如果我的非托管方法使用out参数,我必须首先初始化局部变量,因为方法调用实际上是在委托中。 我希望能够简单地声明一个目的地而不初始化它。 其次,如果抛出exception,我真的不知道它来自何处。 调试器跳转到ApiCall方法,堆栈跟踪仅显示包含对ApiCall的调用而不是委托本身的方法。 由于我可以在单个方法中进行许多API调用,这使调试变得困难。 然后我考虑使用PostSharp来包装所有非托管调用以及错误代码检查,但我不确定如何使用extern方法。 如果最终只是为每个人创建一个包装器方法,那么我会ApiCall与ApiCall方法相同的exception问题,对吧? 另外,如果调试器只存在于已编译的程序集中,那么调试器如何知道如何在我的代码中向我显示抛出exception的站点? 接下来,我尝试实现一个自定义封送器,它将拦截API调用的返回值并检查那里的错误代码。 遗憾的是,您无法应用自定义封送程序来返回值。 但我认为如果有效的话,那将是一个非常干净的解决方案。 [return: MarshalAs(UnmanagedType.CustomMarshaler, […]

从文件句柄中获取文件名?

我将ntdll.dll的NtCreateFile()函数挂钩以允许/拒绝某些文件的访问。 与kernel32.dll的CreateFile()不同,它很容易为您提供相关文件的完整路径,ntdll.dll的NtCreateFile()函数只为您提供文件的句柄。 我需要从文件句柄获取文件的完整路径,从而允许/拒绝访问。 我一直在搜索,似乎没有一个有效的C#解决方案。 此解决方案使用C ++编写,并在Microsoft中进行了记录。 我试图将它移植到C#并没有太大的成功。 这是我尝试C#等效的C ++版本“从文件句柄获取文件名”: public string GetFileNameFromHandle(IntPtr FileHandle) { string fileName = String.Empty; IntPtr fileMap = IntPtr.Zero, fileSizeHi = IntPtr.Zero; UInt32 fileSizeLo = 0; fileSizeLo = GetFileSize(FileHandle, fileSizeHi); if (fileSizeLo == 0 && fileSizeHi == IntPtr.Zero) { // cannot map an 0 byte file return String.Empty; } fileMap = CreateFileMapping(FileHandle, […]

如何从服务访问当前登录用户的HKCU注册表?

在Windows服务中,我想检查存储在每个用户的HKCU注册表区域中的一些用户首选项。 我怎样才能做到这一点? 我看到HKEY_USERS有每个用户登录到机器的子键(或类似的东西?),其中包括每个用户的HKCU区域。 但是,这些子键是用户的SID,所以不知怎的,我需要计算出当前登录用户的SID。 然后,我将查询HKEY_USERS\\whichever\key\i\need代替查询HKEY_CURRENT_USER\whichever\key\i\need 。 从这个问题我可以获得DOMAIN \ USER格式的机器上当前用户的列表。 有没有办法从他们的Windows登录获取用户的SID? 或者是否有更直接的方法来获取当前登录用户的HKCU注册表路径?

如何从GetTokenInformation()安全地为32位和64位拼接可变长度的结构数组? C#

我正在遵循这里提供的pinvoke代码,但稍微有点害怕可变长度数组的编组为size = 1,然后通过计算偏移量而不是索引到数组中来踩过它。 有没有更好的方法? 如果没有,我该怎么做才能使它对32位和64位安全? [StructLayout(LayoutKind.Sequential)] public struct SID_AND_ATTRIBUTES { public IntPtr Sid; public uint Attributes; } [StructLayout(LayoutKind.Sequential)] public struct TOKEN_GROUPS { public int GroupCount; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] public SID_AND_ATTRIBUTES[] Groups; }; public void SomeMethod() { IntPtr tokenInformation; // … string retVal = string.Empty; TOKEN_GROUPS groups = (TOKEN_GROUPS)Marshal.PtrToStructure(tokenInformation, typeof(TOKEN_GROUPS)); int sidAndAttrSize = Marshal.SizeOf(new SID_AND_ATTRIBUTES()); […]

pInvoke readFile():重叠的I / O操作正在进行中

我正在尝试开发一种与电子卡通信的function。 我需要使用readFile()函数: [DllImport(“kernel32.dll”, SetLastError = true)] static extern bool ReadFile(IntPtr hFile, ref byte lpBuffer, uint nNumberOfBytesToRead, out uint lpNumberOfBytesRead, Overlapped lpOverlapped); 我的function是: EventObject = CreateEvent(IntPtr.Zero,true,true,””); lastError = Marshal.GetLastWin32Error(); HIDOverlapped = new System.Threading.Overlapped(); HIDOverlapped.OffsetLow = 0; HIDOverlapped.OffsetHigh = 0; HIDOverlapped.EventHandleIntPtr = EventObject; readHandle = CreateFile(MyDeviceInterfaceDetailData.DevicePath, (GENERIC_READ | GENERIC_WRITE), (FILE_SHARE_READ | FILE_SHARE_WRITE), IntPtr.Zero, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, IntPtr.Zero); uint […]