标签: pinvoke

在C#中以编程方式锁定Windows工作站

我遇到了锁定Windows工作站的示例:

using System.Runtime.InteropServices;
...
[DllImport("user32.dll", SetLastError = true)]
static extern bool LockWorkStation();

...
if (!LockWorkStation())
    throw new Win32Exception(Marshal.GetLastWin32Error()); // or any other thing
Run Code Online (Sandbox Code Playgroud)

这个片段有一个纯粹的托管替代方案吗?即,没有P-Invoke.

c# windows pinvoke pure-managed

16
推荐指数
1
解决办法
7452
查看次数

C#没有捕获来自非托管C++ DLL的未处理异常

我有一个从C#应用程序调用的非托管C++ DLL,我试图让C#应用程序捕获所有异常,以便在由于非托管异常导致dll失败的情况下,用户将得到一个半合适的错误消息(C#app是一个实现它自己的http处理程序的Web服务).

我遇到的问题是并非所有类型都被捕获.因此,如果我创建以下内容并执行C#应用程序,则dll会抛出错误并终止整个应用程序.有任何想法吗?

这是在VS2005中使用.Net framework v2创建的

C++ - Test.h

#ifndef INC_TEST_H
#define INC_TEST_H

extern "C" __declspec(dllexport) void ProcessBadCall();

#endif
Run Code Online (Sandbox Code Playgroud)

C++ - Test.cpp

#include <iostream>
#include <vector>

using namespace std;

void ProcessBadCall()
{
  vector<int> myValues;
  int a = myValues[1];
  cout << a << endl;
}
Run Code Online (Sandbox Code Playgroud)

C# - Program.cs

class Program
{
  [DllImport("Test.dll", EntryPoint="ProcessBadCall")]
  static extern void ProcessBadCall();

  static void Main(string[] args)
  {
    try
    {
      ProcessBadCall();
    }
    catch (SEHException ex)
    {
      Console.WriteLine("SEH Exception: {0}", ex.Message);
    }
    catch (Exception ex)
    {
      Console.WriteLine("Exception: {0}", …
Run Code Online (Sandbox Code Playgroud)

c# c++ dll pinvoke exception-handling

16
推荐指数
1
解决办法
1万
查看次数

在WPF窗口中挂钩进入Windows消息循环,在内部添加白色边框

我正在尝试创建一个WPF窗口WindowStyle="None"(用于自定义按钮,没有标题),无法调整大小.设置ResizeModeNoResize删除我想要保留的空气边界.

我可以设置最小/最大尺寸属性并完成它,除了:

  1. 调整大小的游标仍然可见,并且
  2. 显示窗口以响应用户操作并适合其内容.它显示图像,因此大小会发生变化.

所以,我有一个简单的方案,让我99%的方式:

public class BorderedWindowNoResize : Window
{
    [DllImport( "DwmApi.dll" )]
    public static extern int DwmExtendFrameIntoClientArea(
        IntPtr hwnd,
        ref MARGINS pMarInset );

    [DllImport( "user32.dll", CharSet = CharSet.Auto )]
    public static extern IntPtr DefWindowProc(
        IntPtr hWnd,
        int msg,
        IntPtr wParam,
        IntPtr lParam );

    public BorderedWindowNoResize()
    {           
        Loaded += BorderedWindowNoResize_Loaded;
    }

    private void BorderedWindowNoResize_Loaded( object sender, RoutedEventArgs e )
    {           
        IntPtr mainWindowPtr = new WindowInteropHelper( this ).Handle;
        HwndSource mainWindowSrc = HwndSource.FromHwnd( mainWindowPtr ); …
Run Code Online (Sandbox Code Playgroud)

c# wpf pinvoke

16
推荐指数
1
解决办法
1万
查看次数

在.NET中,如何在NTFS中创建连接,而不是Symlink?

我正在尝试创建一个NTFS Junction.从cmd行我可以使用sysinternals中junction.exe工具执行此操作.结点的DIR cmd输出如下所示:

 Volume in drive C has no label.
 Volume Serial Number is C8BC-2EBD

 Directory of c:\users\cheeso\Documents

03/22/2009  09:45 PM    <JUNCTION>     My Music [\??\c:\users\cheeso\Music]
05/11/2007  05:42 PM    <DIR>          My Received Files
03/22/2009  09:46 PM    <JUNCTION>     my videos [\??\c:\users\cheeso\Videos]
Run Code Online (Sandbox Code Playgroud)

我在某地读过Junctions是Symbolic Links的子集.

所以我尝试使用CreateSymbolicLink创建一个Junction.当我这样做时,我实际上得到了一个符号链接,而不是一个连接点.

09/09/2009  11:50 AM    <SYMLINKD>     newLink [.\]
Run Code Online (Sandbox Code Playgroud)

还有CreateHardLink.那里的文档说交汇点(又名"重新分析点")是硬链接的子集.但我似乎无法接受这项工作.它完成但没有创建硬链接或联结.

我正在使用.NET/C#,导入如下所示:

    [Interop.DllImport("kernel32.dll", EntryPoint="CreateSymbolicLinkW", CharSet=Interop.CharSet.Unicode)]
    public static extern int CreateSymbolicLink(string lpSymlinkFileName, string lpTargetFileName, int dwFlags);

    [Interop.DllImport("kernel32.dll", EntryPoint="CreateHardLinkW", CharSet=Interop.CharSet.Unicode)]
    public static extern bool CreateHardLink(string lpFileName, …
Run Code Online (Sandbox Code Playgroud)

.net pinvoke winapi ntfs deviceiocontrol

15
推荐指数
1
解决办法
8130
查看次数

C#P/Invoke:包含函数指针的编组结构

对不起,下面是详细的介绍.我需要知道P/Invoke内部人员的洞察力比我更好.

这是我如何编组包含从C到C#的函数指针的结构.我想知道这是否是最干净和/或最有效的方式.

我正在使用C编码的本机DLL连接,它提供以下入口点:

void* getInterface(int id);
Run Code Online (Sandbox Code Playgroud)

您必须传递getInterface(int)以下枚举值之一:

enum INTERFACES
{
  FOO,
  BAR
};
Run Code Online (Sandbox Code Playgroud)

它返回一个指向包含函数指针的结构的指针,如:

typedef struct IFOO
{
  void (*method1)(void* self, int a, float b);
  void (*method2)(void* self, int a, float b, int c);
} IFoo;
Run Code Online (Sandbox Code Playgroud)

以下是您在C中使用它的方式:

IFoo* interface = (IFoo*)getInterface(FOO);
interface->method1(obj, 0, 1.0f); // where obj is an instance of an object
                                  // implementing the IFoo interface.
Run Code Online (Sandbox Code Playgroud)

在C#中,我有一个使用P/Invoke Library映射getInterface(int)入口点的类.

class Library
{
  [DllImport("MyDLL"), EntryPoint="getInterface", CallingConvention=CallingConvention.Cdecl)]
  public static extern IntPtr GetInterface(int id);
};
Run Code Online (Sandbox Code Playgroud)

然后我定义了:

struct …
Run Code Online (Sandbox Code Playgroud)

c# pinvoke structure function-pointers marshalling

15
推荐指数
2
解决办法
9790
查看次数

使用进程间同步对象同步2个进程 - Mutex或AutoResetEvent

请考虑以下场景:我正在运行我的应用程序,在执行期间,必须运行另一个进程,并且只有在第二个进程完成内部特定初始化之后,我的第一个进程才能继续.例如:

...
// Process1 code does various initializations here
Process.Start("Process2.exe");
// Wait until Process2 finishes its initialization and only then continue (Process2 doesn't exit)
...
Run Code Online (Sandbox Code Playgroud)

我看到几个选项:

  1. Mutex - Mutex在考虑进程间通信时会自动浮现,但是,我看不到让Process1等待他自己生成的互斥锁的方法.我可以使Process2创建一个互斥锁并等待Process1,直到创建Mutex(使用轮询和Mutex.OpenExisting函数)
  2. AutoResetEvent - 那些对于任务来说是完美的,但是,似乎在.NET下这些不能用于进程间通信.
  3. CreateEvent - 我可以使用P/Invoke并使用Win32 CreateEvent函数.从理论上讲,它可以为我提供我需要的一切.但是,如果可能的话,我宁愿不使用本机函数.
  4. 使用外部文件 - 最简单的方法就是使用一些操作系统外部对象(文件,注册表等).然而,这似乎相当hacky.

我很高兴听到你对这个案子的意见.

谢谢!

.net c# pinvoke synchronization mutex

15
推荐指数
2
解决办法
2万
查看次数

了解使用fixed {},Marshal.AllocHGlobal()和GCHandle.Alloc()之间的区别

首先让我说看看我在整个论坛和网络上的许多链接中找到了固定{},Marshal.AllocHGlobal()和GCHandle.Alloc()的使用说明.但是,我还没有找到关于何时使用Marshal类与GCHandle类(使用和不使用fixed {})的简明解释.

我正在使用第三方.NET库,它在"Buffer"类中有一个名为Readline()的方法.该手册显示了以下函数原型:

bool ReadLine(int x1,int y1,int x2,int y2,System.IntPtr bufData,out int numRead);

描述bufData,说明:...内存区域的字节数必须大于或等于行长度乘以BytesPerPixel属性返回的值.

现在,后来在他们的用户手册,给访问该缓冲区(我已经调整了我的具体的例子一点点)的例子:

// Create an array large enough to hold one line from buffer
int size = 640; 
byte[] dataLine = new byte[size * 2];   // 2 bytes per pixel

// Pin the array to avoid Garbage collector moving it  
GCHandle dataLineHandle = GCHandle.Alloc(dataLine, GCHandleType.Pinned); 
IntPtr dataLineAddress = dataLineHandle.AddrOfPinnedObject(); 
Run Code Online (Sandbox Code Playgroud)

我可以按照上面的"示例"代码:

// Read one line of buffer data 
success = buffer.ReadLine(0, 0, 639, 0, …
Run Code Online (Sandbox Code Playgroud)

c# pinvoke marshalling

15
推荐指数
1
解决办法
7230
查看次数

如何从C#调用C++ API

我有一个用C++实现的非常大的系统,我需要与之交互.该系统有一个非常大的API,许多C++ DLL.这些DLL导出C++类,而不是一个漂亮的C风格API.我需要从一个新的C#项目中使用它们.

据我所知,.NET有三种与本机软件交互的方式:

  1. P/Invoke - 仅适用于C API
  2. COM对象
  3. C++/CLI

所以我理解它的方式,我有三种方法:

  1. 在C中编写包装器并使用P/Invoke调用它.这看起来太过分了.
  2. 用COM编写包装器.我不知道怎么做,除非它非常简单,我不愿意学习我认为的东西 - 一种垂死的技术.
  3. 在C++/CLI中编写包装器.这似乎是最不起作用的,尽管仍然很多.

我的问题:

  1. 首先,我想知道为什么.NET不允许我"按原样"使用C++类?我假设这是一个内存管理问题.如果是的话,我更愿意编写终结器,并实现IDisposable.据我所知,C++类只是非常奇特的结构,并且由于P/Invoke支持结构,以及将结构作为第一个参数的函数,为什么不支持类呢?

  2. 其次,假设我真的很懒,而且它很无聊,乏味,工作,使用这些DLL的最佳方法是什么?直接从C#调用它们的可能性是最好的.如果没有,那么我会喜欢自动工具来制作包装纸.此外,DLL可能会稍微改变,但仍然,id而不是强制手动重写包装器.

对于一个非常好的答案,特别是在第一部分,或一个很好的自动工具,我会奖励赏金......

谢谢

c# c++ dll pinvoke interop

15
推荐指数
1
解决办法
6328
查看次数

C# - 将不安全的字节*转换为byte []

我有一个unsafe byte*指向已知长度的本机字节数组.我该怎么把它转换成byte[]

unsafe sbyte*到零结尾的本地字符串指针可以被转换成一个C#string容易,因为有一个转换构造函数用于此目的,但我不能找到一个简单的方法来转换byte*byte[].

c# pinvoke

15
推荐指数
1
解决办法
2万
查看次数

当你有句柄时,int vs IntPtr?

首先是一个背景问题:

一般来说,int和之间有什么区别IntPtr?我的猜测是它是一个实际的对象,而不是像int或是一个值byte.假设是真的:

所以他们不一样.然而,我看到手柄代表两者.

  1. IntPtr的: Control.Handle
  2. int(或uint):PInvoke可以设置为返回一个int并且它可以正常工作:

    [DllImport("coredll.dll", SetLastError = true)]
    public static extern int GetForegroundWindow();
    private string GetActiveWindow()
    {
        const int nChars = 256;
        int handle = 0;
        StringBuilder Buff = new StringBuilder(nChars);
    
        handle = CoreDLL.GetForegroundWindow();
    
        if (CoreDLL.GetWindowText(handle, Buff, nChars) > 0)
        {
            return Buff.ToString();
        }
    
        return "";
    }
    
    Run Code Online (Sandbox Code Playgroud)

那么,intvs IntPtr?手柄有问题吗?你能用吗?

c# pinvoke

14
推荐指数
1
解决办法
7783
查看次数