用C#编写的读取客户端MAC地址的ActiveX控件,在IE中运行时出现权限错误,无从下手,求教
我用C#写了一个读取客户端MAC地址的控件,在WinForm下运行正常,搬到IE里就出现权限错误:请求“System.Security.Permissions.RegistryPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”类型的权限已失败。
窗体上只有一个文本框,用来显示MAC地址,源代码如下:
using System;
using System.Net;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using System.Management;
using System.Diagnostics;
using System.Text.RegularExpressions;
namespace WMActiveX
{
[Guid("D3722706-9591-4449-B8AA-F35EE65FB9B0")]
public partial class Hardware : UserControl
{
public Hardware()
{
InitializeComponent();
textBox1.Text = GetLocalMac();
}
public static string GetLocalMac()
{
List<string> netCardList = GetNetCardList();
List<string>.Enumerator enumNetCard = netCardList.GetEnumerator();
string macAddr = string.Empty;
while (enumNetCard.MoveNext())
{
macAddr = GetPhysicalAddr(enumNetCard.Current);
if (macAddr != string.Empty)
{
break;
}
}
return macAddr;
}
public static List<string> GetNetCardList()
{
List<string> cardList = new List<string>();
try
{
//请求“System.Security.Permissions.RegistryPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”类型的权限已失败。
RegistryKey regNetCards = Registry.LocalMachine.OpenSubKey(Win32Utils.REG_NET_CARDS_KEY);
if (regNetCards != null)
{
string[] names = regNetCards.GetSubKeyNames();
RegistryKey subKey = null;
foreach (string name in names)
{
subKey = regNetCards.OpenSubKey(name);
if (subKey != null)
{
object o = subKey.GetValue("ServiceName");
if (o != null)
{
cardList.Add(o.ToString());
}
}
}
}
}
catch (Exception ex)
{
}
return cardList;
}
private static string GetPhysicalAddr(string cardId)
{
string macAddress = string.Empty;
uint device = 0;
try
{
string driveName = "\\\\.\\" + cardId;
device = Win32Utils.CreateFile(driveName,
Win32Utils.GENERIC_READ | Win32Utils.GENERIC_WRITE,
Win32Utils.FILE_SHARE_READ | Win32Utils.FILE_SHARE_WRITE,
0, Win32Utils.OPEN_EXISTING, 0, 0);
if (device != Win32Utils.INVALID_HANDLE_VALUE)
{
byte[] outBuff = new byte[6];
uint bytRv = 0;
int intBuff = Win32Utils.PERMANENT_ADDRESS;
if (0 != Win32Utils.DeviceIoControl(device, Win32Utils.IOCTL_NDIS_QUERY_GLOBAL_STATS,
ref intBuff, 4, outBuff, 6, ref bytRv, 0))
{
string temp = string.Empty;
foreach (byte b in outBuff)
{
temp = Convert.ToString(b, 16).PadLeft(2, '0');
macAddress += temp;
temp = string.Empty;
}
}
}
}
finally
{
if (device != 0)
{
Win32Utils.CloseHandle(device);
}
}
return macAddress;
}
}
#region Win32Utils
public class Win32Utils
{
public const string REG_NET_CARDS_KEY = @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards";
public const uint GENERIC_READ = 0x80000000;
public const uint GENERIC_WRITE = 0x40000000;
public const uint FILE_SHARE_READ = 0x00000001;
public const uint FILE_SHARE_WRITE = 0x00000002;
public const uint OPEN_EXISTING = 3;
public const uint INVALID_HANDLE_VALUE = 0xffffffff;
public const uint IOCTL_NDIS_QUERY_GLOBAL_STATS = 0x00170002;
public const int PERMANENT_ADDRESS = 0x01010101;
[DllImport("kernel32.dll")]
public static extern int CloseHandle(uint hObject);
[DllImport("kernel32.dll")]
public static extern int DeviceIoControl(uint hDevice,
uint dwIoControlCode,
ref int lpInBuffer,
int nInBufferSize,
byte[] lpOutBuffer,
int nOutBufferSize,
ref uint lpbytesReturned,
int lpOverlapped);
[DllImport("kernel32.dll")]
public static extern uint CreateFile(string lpFileName,
uint dwDesiredAccess,
uint dwShareMode,
int lpSecurityAttributes,
uint dwCreationDisposition,
uint dwFlagsAndAttributes,
int hTemplateFile);
}
#endregion
}
--------------------编程问答-------------------- DLL文件与网页放在同一目录下的,网页HTML代码:
<html>
<head>
<title>Untitled Page</title>
</head>
<body>
<object id="HW" classid="WMActiveX.dll#WMActiveX.Hardware" width="400" height="300"></object>
</body>
</html>
--------------------编程问答-------------------- 用C#写ActiveX控件?太搞笑了吧...客户端要就是不装.NET Framework你能怎么办? --------------------编程问答-------------------- 只要实现功能就行了,客户端没有framework,装一个就行了 --------------------编程问答-------------------- 哈哈,如果是这样你还不入直接写net装配件了
net装配件也是可以直接再html页面里用<object>标签引入的
参考http://www.sifung.com/pages/879.shtm --------------------编程问答-------------------- 其实如果是编写控件取得mac地址,也用不着这么麻烦的手段
反正你的控件要在客户端运行,那么就直接启动cmd命令的ipconfig -all命令,程序接收回显的值就成
--------------------编程问答-------------------- 事实上我们总是讨论到别的方面上.而我问的只是个权限问题.
回vrhero(我是真小人/最烦伪君子...)
如果我们需要完全考虑所有人的客户端环境, 那还是写个C/S的,放在HTML上让别人下载,这样才能解决所有问题.现在各银行网站的ActiveX在FireFox下均表现不好.
回wanghui0380(放歌)
你的这个装配件,其实我在写这些代码之前就在用. 只不过最后我稍微改了一下,编译成ActiveX而已. 我认为他仍然存在权限问题, 当然这个可以测试一下.
而用cmd去取得MAC地址,我不知道你是否真的做过, 在WinForm下去跑后台cmd命令没有问题,并不一定在ActiveX里能跑吧, 当然这个也需要验证.
不得已,只好去挖了个VB6出来,写了几千行代码,从获取MAC,到CPUID和硬盘物理ID, 写得很不爽,但也算解决问题.
还是谢谢各位 --------------------编程问答-------------------- 不错啊!写得很好啊! --------------------编程问答-------------------- @LZ
只好去挖了个VB6出来,写了几千行代码,从获取MAC,到CPUID和硬盘物理ID, 写得很不爽,但也算解决问题.
请问一下LZ 试过没有MFC ActiveX 控件,不知怎么实现的~~
补充:.NET技术 , C#