Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/62.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# 从.NET调用非托管代码_C#_Dll_Unmanaged - Fatal编程技术网

C# 从.NET调用非托管代码

C# 从.NET调用非托管代码,c#,dll,unmanaged,C#,Dll,Unmanaged,我试图在我的c程序中使用dll,但我似乎无法让它工作。我制作了一个测试应用程序,如下所示。返回值为0,但它实际上并不执行它应该执行的操作 鉴于以下命令不起作用: rundll32 cmproxy.dll,SetProxy /source_filename proxy-1.txt /backup_filename roxy.bak /DialRasEntry NULL /TunnelRasEntry DSLVPN /Profile "C:\Documents and ettings\Adminis

我试图在我的c程序中使用dll,但我似乎无法让它工作。我制作了一个测试应用程序,如下所示。返回值为0,但它实际上并不执行它应该执行的操作

鉴于以下命令不起作用:

rundll32 cmproxy.dll,SetProxy /source_filename proxy-1.txt /backup_filename roxy.bak /DialRasEntry NULL /TunnelRasEntry DSLVPN /Profile "C:\Documents and ettings\Administrator\Application Data\Microsoft\Network\Connections\Cm\dslvpn.cmp"
代码:

以下是dumpbin/exports命令的内容

File Type: DLL

  Section contains the following exports for cmproxy.dll

    00000000 characteristics
    3E7FEF8C time date stamp Tue Mar 25 05:56:28 2003
        0.00 version
           1 ordinal base
           1 number of functions
           1 number of names

    ordinal hint RVA      name

          1    0 00001B68 SetProxy

  Summary

        1000 .data
        1000 .reloc
        1000 .rsrc
        2000 .text
当这起作用时,它将为VPN连接设置代理服务器

编辑:

我希望避免从system.process运行rundll32

我还可以提供指向dll和我的测试应用程序的链接。虽然上面粘贴的代码是它包含的全部内容,而且dll可以从服务器资源工具包中获得,但我认为

更新:

我在C++中编写了一个测试DLL,它简单地回响了它给出的ARG。它正在运行,但它说

句柄无效


只是一些值得思考的东西。这可能是一个可行的解决办法

也许您可以使用System.Diagnostics.Process类从代码中运行命令,如下所示:

  System.Diagnostics.Process p = new System.Diagnostics.Process();
  p.StartInfo.Arguments = @"cmproxy.dll,SetProxy /source_filename proxy-1.txt /backup_filename roxy.bak /DialRasEntry NULL /TunnelRasEntry DSLVPN /Profile ""C:\Documents and ettings\Administrator\Application Data\Microsoft\Network\Connections\Cm\dslvpn.cmp\""";
  p.StartInfo.FileName = "rundll32";
  p.Start();
如果需要在运行时替换某些参数,则可以使用String.Format格式化这些参数并替换所需的任何内容

编辑1:


它似乎没有正确地突出显示此处的代码。我没有cmproxy.dll,因此无法测试此场景。

只是一些值得思考的问题。这可能是一个可行的解决办法

也许您可以使用System.Diagnostics.Process类从代码中运行命令,如下所示:

  System.Diagnostics.Process p = new System.Diagnostics.Process();
  p.StartInfo.Arguments = @"cmproxy.dll,SetProxy /source_filename proxy-1.txt /backup_filename roxy.bak /DialRasEntry NULL /TunnelRasEntry DSLVPN /Profile ""C:\Documents and ettings\Administrator\Application Data\Microsoft\Network\Connections\Cm\dslvpn.cmp\""";
  p.StartInfo.FileName = "rundll32";
  p.Start();
如果需要在运行时替换某些参数,则可以使用String.Format格式化这些参数并替换所需的任何内容

编辑1:

它似乎没有正确地突出显示此处的代码。我没有cmproxy.dll,因此无法测试此方案。

可能有帮助吗?特别是,本节似乎很有用:

将参数添加到Rundll条目 要点如下:

hwnd - window handle that should be used as the owner window for any windows your DLL creates hinst - your DLL's instance handle lpszCmdLine - ASCIIZ command line your DLL should parse nCmdShow - describes how your DLL's windows should be displayed 然后像这样称呼它:

const int SW_SHOWNORMAL = 1;
IntPtr hWnd = (this as Form).Handle;
IntPtr hInstance = Marshal.GetHINSTANCE(this.GetType().Module);
SetProxy(hWnd, hInstance, cmdLine, SW_SHOWNORMAL);
我用shell32.dll中的控件_RunDLL入口点测试了相同的代码,我可以确认它对我来说工作正常。诀窍是让正确的HWND和HINSTANCE指针作为前两个参数传入。另外,我之前在nCmdShow中传递了0,但是SW_SHOWNORMAL的值为1,这可能是您想要的值。

可能会有帮助吗?特别是,本节似乎很有用:

将参数添加到Rundll条目 要点如下:

hwnd - window handle that should be used as the owner window for any windows your DLL creates hinst - your DLL's instance handle lpszCmdLine - ASCIIZ command line your DLL should parse nCmdShow - describes how your DLL's windows should be displayed 然后像这样称呼它:

const int SW_SHOWNORMAL = 1;
IntPtr hWnd = (this as Form).Handle;
IntPtr hInstance = Marshal.GetHINSTANCE(this.GetType().Module);
SetProxy(hWnd, hInstance, cmdLine, SW_SHOWNORMAL);

我用shell32.dll中的控件_RunDLL入口点测试了相同的代码,我可以确认它对我来说工作正常。诀窍是让正确的HWND和HINSTANCE指针作为前两个参数传入。另外,我之前在nCmdShow中传递了0,但是SW_SHOWNORMAL的值为1,这可能是您想要的。

答案是CharSet=CharSet.Unicode应该是CharSet=CharSet.Ansi

答案是CharSet=CharSet.Unicode应该是CharSet=CharSet.Ansi

cmproxy.dll的.h看起来像什么?我同意Per,查看SetProxy的函数签名会很有帮助。我没有编写dll,它是由Microsoft提供的。有没有办法在没有源的情况下获取.h文件?请尝试在Visual Studio中使用对象浏览器打开DLL。如果它起作用,您将能够看到DLL公开了什么,然后查看函数签名。可能SetProxy函数签名与您在代码中定义它的方式不同。它表示无法浏览dll。有趣的是,它返回0,因此可以假设它工作了,并且命令行有问题。但是命令行是使用rundll32工作的,所以我想知道我是否还没有形成正确的命令行,或者它需要一个不同的类型或者其他什么。cmproxy.dll的.h是什么样子的?我同意Per的说法,看到SetProxy的函数签名会很有帮助。我没有编写dll,它是由Microsoft提供的。有没有办法在没有源的情况下获取.h文件?请尝试在Visual Studio中使用对象浏览器打开DLL。如果它起作用,您将能够看到DLL公开了什么,然后查看函数签名。可能SetProxy函数签名与您在代码中定义它的方式不同。它表示无法浏览dll。有趣的是,它返回0,因此可以假设它工作了,并且命令行有问题。但是命令行使用rundll32工作,所以我想知道我是否没有正确地形成命令行,或者它需要不同的类型或其他东西抱歉,我应该在OP中提到这一点,我还没有尝试过,但我假设它确实工作,但是我试图避免使用此方法。抱歉,我应该在OP中提到这一点,我还没有试过,但我认为它确实有效,但我正在努力避免使用这种方法。我已经读过这篇文章,不幸的是它没有给我任何启示。我想知道我是否需要更改命令的类型
“在线辩论?”查尔斯·加金特:我刚刚编辑了我的答案。P/Invoke代码示例有帮助吗?我们显然是在同一时间键入:我已经尝试了您的编辑,但仍然没有更改。我还通过设置EntryPoint=SetProxy进行了尝试。还是没有区别。也许微软的人会看到这一点,并给我们答案@查尔斯·加金特:好吧,看来这是hWnd和hInstance争论的问题。我之前只是为这些函数传递NULL,但对于某些DLL,这似乎不起作用,所以我添加了代码来演示如何获取有效的窗口和实例句柄。有了这个更改,我可以让它调用shell32.dll中的RunDll入口点,所以我很有信心这对您现在应该是可行的。我担心这不会有任何区别。我已经读过这篇文章,不幸的是它没有给我任何启示。我想知道是否需要更改命令行参数的类型?@Charles Gargent:我刚刚编辑了我的答案。P/Invoke代码示例有帮助吗?我们显然是在同一时间键入:我已经尝试了您的编辑,但仍然没有更改。我还通过设置EntryPoint=SetProxy进行了尝试。还是没有区别。也许微软的人会看到这一点,并给我们答案@查尔斯·加金特:好吧,看来这是hWnd和hInstance争论的问题。我之前只是为这些函数传递NULL,但对于某些DLL,这似乎不起作用,所以我添加了代码来演示如何获取有效的窗口和实例句柄。有了这个更改,我可以让它在shell32.dll中调用RunDll入口点,所以我很有信心这对您现在应该是可行的。恐怕这没有什么区别。您能告诉我们吗?你怎么知道的?你能告诉我们吗?你怎么知道的?
const int SW_SHOWNORMAL = 1;
IntPtr hWnd = (this as Form).Handle;
IntPtr hInstance = Marshal.GetHINSTANCE(this.GetType().Module);
SetProxy(hWnd, hInstance, cmdLine, SW_SHOWNORMAL);