从 .NET 调用非托管代码
我正在尝试在我的 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"
代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.Runtime.InteropServices;
using System.Net;
using WUApiLib;
namespace nac
{
class Program
{
[DllImport("cmproxy.dll", CharSet = CharSet.Unicode)]
static extern int SetProxy(string cmdLine);
static void Main(string[] args)
{
string cmdLine = @"/source_filename proxy-1.txt /backup_filename proxy.bak /DialRasEntry NULL /TunnelRasEntry DSLVPN /Profile ""C:\Documents and Settings\Administrator\Application Data\Microsoft\Network\Connections\Cm\dslvpn.cmp""";
Console.WriteLine(SetProxy(cmdLine));
}
}
}
这是 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,它只是回显给定的参数。它正在运行,但它说
句柄无效
I am trying to use a dll in my c# program but I just cant seem to get it to work. I have made a test app shown below. The return value is 0, however it does not actually do what it is supposed to do.
Whereas the following command does work:
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"
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.Runtime.InteropServices;
using System.Net;
using WUApiLib;
namespace nac
{
class Program
{
[DllImport("cmproxy.dll", CharSet = CharSet.Unicode)]
static extern int SetProxy(string cmdLine);
static void Main(string[] args)
{
string cmdLine = @"/source_filename proxy-1.txt /backup_filename proxy.bak /DialRasEntry NULL /TunnelRasEntry DSLVPN /Profile ""C:\Documents and Settings\Administrator\Application Data\Microsoft\Network\Connections\Cm\dslvpn.cmp""";
Console.WriteLine(SetProxy(cmdLine));
}
}
}
Here is the contents of the dumpbin /exports command
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
When this works it sets the proxy server for a VPN connection.
EDIT:
I wish to avoid running rundll32 from system.process
I can also provide a link to both the dll and my test app. Although the code pasted above is all it contains and the dll is available from the Server resource kit I think.
UPDATE:
I have written a test DLL in c++ that simply echos the args it is given. It is running but it says
The handle is invalid
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
只是一些值得深思的东西。这可能是一个可能的解决方法。
也许您可以使用 System.Diagnostics.Process 类从代码中运行命令,如下所示:
如果您需要在运行时替换某些参数,那么您可以使用 String.Format 来格式化参数并替换您需要的任何内容。
编辑1:
这里似乎没有正确突出显示代码。我没有 cmproxy.dll,因此无法测试此场景。
Just some food for thought. This may be a possible work around.
Perhaps you could use the System.Diagnostics.Process class to run the command from your code like this:
If you need to substitute some of the arguments at runtime then you could use String.Format to format the arguments and substitute whatever you need.
Edit 1:
It doesn't seem to be correctly highlighting the code here. I don't have cmproxy.dll so I cannot test this scenario.
也许 有关 RUNDLL32.EXE 的 Microsoft 文档 会有所帮助?特别是,本节似乎很有用:
更新 2:
这应该适合您:
然后像这样调用它:
我使用 shell32.dll 中的 Control_RunDLL 入口点测试了相同的代码,我可以确认它对我来说工作正常。诀窍是获取正确的 HWND 和 HINSTANCE 指针作为前两个参数传递。另外,我之前为 nCmdShow 传递了 0,但是 根据 pinvoke.net< /a>,SW_SHOWNORMAL 的值为 1,这可能就是您想要的。
Perhaps the Microsoft documentation on RUNDLL32.EXE would be helpful? In particular, this section seems useful:
Update 2:
This should work for you:
and then call it like:
I tested the same code with the Control_RunDLL entrypoint in shell32.dll and I can confirm that it works fine for me. The trick is getting the correct HWND and HINSTANCE pointers to pass in as the first two arguments. Also, I was previously passing 0 for the nCmdShow, but according to pinvoke.net, SW_SHOWNORMAL has value 1, which is probably what you want.
答案是 CharSet = CharSet.Unicode 应该是 CharSet = CharSet.Ansi
The answer is CharSet = CharSet.Unicode should be CharSet = CharSet.Ansi