每做一个操作都提示操作不会花费很长时间,每个操作都花费很长时间。点一下确定,半天没有响应。Wasai~
吃力不讨好的SP,将Web前端服务器加入到SP服务器场之后,在管理中心执行创建web应用程序,则会在所有web前端上自动创建好IIS站点,整体来说,SP还是节省了一些人工操作,只是提示太弱智了~如果提醒能反应出SP将在N台服务器上执行xxx操作,至少使用的人会感受到SP在干些NB的事情,默默地点赞。目前这种情况是,SP欺骗了用户,虽然在干活,使用的人在抓狂,痛骂。 若是能将每个服务器的执行状态使用可视化的呈现,那就更好了。
博客
-
吐槽 Sharepoint 2013
-
C#通过webbrowser控件与javascript交互 (转)
C#通过webbrowser控件与javascript交互
1.C#里调用控件里面网页的js函数
// 调用JavaScript的messageBox方法,并传入参数
object[] objects = new object[1];
objects[0] = “C#访问JavaScript脚本”;this.webBrowser1.Document.InvokeScript(“messageBox”, objects);
//object就是传入的参数,而messageBox则是网页中预定义好的js函数。
通过这种方式C#里面就可以执行Javascript函数,可以把上面的代码放到一个button的click事件里面。
2.C#windows窗体应用webbrowser控件里网页js调用C#窗体的函数
首先需要在代码里面加上
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
public partial class Form1 : Form{
…..//
}
这样使得C#的com对象是对网页里的javascript可见的。
然后在嵌入网页里面通过“window.external.MyMessageBox(‘javascript访问C#代码’)” ,即通过window.external捕获调用c#定义好的函数。
具体Form.cs代码如下(通过vs2008创建的c#window窗体应用,拖拽上一个webbrowser控件和button控件。):
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
System.IO.FileInfo file = new System.IO.FileInfo(“test.html”);
// WebBrowser控件显示的网页路径
this.webBrowser1.Url = new Uri(file.FullName);
// 将当前类设置为可由脚本访问
this.webBrowser1.ObjectForScripting =this;}
private void button1_Click(object sender, EventArgs e)
{}
// 提供给JavaScript调用的方法
public void MyMessageBox(string message)
{
MessageBox.Show(message);
}private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{}
private void button1_Click_1(object sender, EventArgs e)
{
// 调用JavaScript的messageBox方法,并传入参数
object[] objects = new object[1];
objects[0] = “C#访问JavaScript脚本”;
this.webBrowser1.Document.InvokeScript(“messageBox”, objects);
}
}test.html内容比较简单:
<html>
<head>
<meta http-equiv=”Content-Language” content=”zh-cn”>
<script language=”javascript” type=”text/javascript”>
<!– 提供给C#程序调用的方法 –>
function messageBox(message)
{
alert(message);
}
</script>
</head>
<body>
<!– 调用C#方法 –>
<button onclick=”window.external.MyMessageBox(‘javascript访问C#代码’)” >
javascript访问C#代码</button>
</body>
</html>配置运行成功的话,可以看到相互调用的效果,希望对需要的童鞋有用!
补充一个js调用C#函数的方法:
1,设置脚本对象:
wb.ObjectForScripting = this; // wb为Webbrowser对象
2,公开方法
public void Alert()
{
MessageBox.Show(“dkkfdkf”);
}
3,然后页面上用javascript可以调用这个方法
external.Alert();看了高人的博客,再补充几个,哈:
Winform WebBrowser控件对访问页面执行、改写、添加Javascript代码
大家有兴趣可以加我QQ群交流:14792063 广州软件开发团队
使用Winform WebBrowser控件对访问页面执行、改写、添加Javascript代码,可以解决许多问题,实现你想要的效果。
可以通过引用Microsoft.mshtml,实现对Javascript的操作,代码如下:
代码 mshtml.IHTMLDocument2 doc = webBrowser1.Document.DomDocument as mshtml.IHTMLDocument2;
mshtml.IHTMLWindow2 win = doc.parentWindow as mshtml.IHTMLWindow2;
win.execScript(@”alert(‘hello webbrowser’)”, “javascript”);其实还有一种更好的、无需引用Microsoft.mshtml的实现方式:
代码 HtmlElement ele = webBrowser1.Document.CreateElement(“script”);
ele.SetAttribute(“type”, “text/javascript”);
ele.SetAttribute(“text”, “alert(‘hello webbrowser’)”);
webBrowser1.Document.Body.AppendChild(ele);这种使用.Net框架本身所提供的对象,相比引用框架外的COM,好处是显而易见的,这将更方便于安装部署至客户机上。
执行上述两段代码的效果是一样的,都将弹出网页对话框“hello webbrowser”。如果仅是执行Javascript方法,那么,有更简单的且可获得方法返回值的方式,首先假如页面上有如下Javascript方法:
function sayHello(to) {
alert(‘hello ‘ + to);
return ‘hi, i am javascript’;
}在Winform中执行以下代码,首先会弹出网页对话框“hello webbrowser”,然后是Winform的MessageBox对话框“hi, i am javascript”
MessageBox.Show(webBrowser1.Document.InvokeScript(“sayHello”,new object[]{“webbrowser”}).ToString());
Winform WebBrowser控件是一个好东西,它不但可以导航网页,还可以使用它获取一些在客户端浏览器HTML源代码中无法获取的数据。如使用了AJAX获取数据的页面,通过客户端浏览器查看源代码的方式,将无法获取到这部分的数据;又如使用了Javascript对内容进行加密以防止采集的页面,即使让你获得HTML源代码,也难以解密得到你想要的结果。但WebBrowser使得这一切变得简单!有兴趣的朋友欢迎继续阅读本博的另一篇文章《》,讲述如何通过WebBrowser访问加密页面,改写其中的Javascirpt方法获取加密的结果。
原始地址:http://blog.csdn.net/luxiaoyu_sdc/article/details/6896451
-
手机支付体验
体验场景:下班后,在西二旗地铁站自助售货机购买饮料。结果如图所示:
在这场体验比赛中,显然是支付宝胜出。地铁站人流量大,手机网络不稳定的情况下,微信支付基本处于不可用的状态,支付宝却巧妙的避开了,为支付宝的实现思路点赞!
正如图示展示的那样,微信支付依赖于手机网络,用户扫描完二维码之后,数据是通过手机网络来回倒腾。而支付宝当面付则完全不需要手机网络,此时支付宝当面付仅通过声波将数据传给售货机,售货机本身有“神秘的网络”,数据在畅通的网络下来往,这才是可用的手机支付啊。支付宝当面付相当于把自身变成了一张虚拟的支付卡,脱离网络下存在。点赞!
-
厚积薄发,丰富的公用类库积累,助你高效进行系统开发(8)—-非对称加密、BASE64加密、MD5等常用加密处理
厚积薄发,丰富的公用类库积累,助你高效进行系统开发(8)—-非对称加密、BASE64加密、MD5等常用加密处理 (转)
俗话说,一个好汉十个帮,众人拾柴火焰高等都说明一个道理,有更多的资源,更丰富的积累,都是助你走向成功,走向顶峰的推动力。
本篇继续继续整理优化已有的共用类库,并继续发表随笔介绍公用类库的接口方法以及详细使用操作,力求给自己继续优化,积攒更丰富的公用类库资源,加深了解的同时,也给大家展现公用类库好的方面。
本篇的公用类库的介绍主题是加密解密的部分,加解密算法包括DES加解密、Base64加解密、
AES RijndaelManaged加解密、MD5加密、以及RSA非对称加密等操作。如果你对前面的类库介绍文章有兴趣,可以参考下面的连接了解。
厚积薄发,丰富的公用类库积累,助你高效进行系统开发(7)
厚积薄发,丰富的公用类库积累,助你高效进行系统开发(6)
1、非对称加密、解密、验证辅助类 RSASecurityHelper
本人开发过很多共享软件,在共享软件注册方面积累了一些自己的经验,其中采用非对称加密方式实现注册码验证的操作,就是其中一个比较重要的步骤,由于其逻辑不可逆的特点,采用非对称加密方式,较一般的对称加密方式,能够隐藏授权的逻辑,因此具有更好的效果。 这个非对称的解密解密、验证操作,是我所有共享软件里面用到的授权操作,很早很多朋友就这个问题问过我很多次,现在奉献给大家注册码实现的思路及操作接口,希望大家能够在享受代码带来的便利外,也可以提高自己对知识产权的保护。
一般来说,非对称加密方式,结合代码混淆和强名称验证,是比较好的实现注册授权机制的功能。
实现效果
1)本辅助类主要是用来方便实现非对称加密、解密、验证等相关操作。
2)非对称加密有RSA、椭圆曲线等,最流行的是RSA。所谓的非对称,是因为它有两个密钥,一个称为公钥,一个称为私钥。公钥是可以对外发布的,而私钥是自己保存的。用公钥加密,必须用私钥解密,反之,用私钥加密必须用公钥解密。所以,我们可以在软件中保存公钥的内容,这个是可以公开的;私钥我们可以自己留着。别人拿不到私钥,根本计算不出注册码来。
3)使用辅助类RSASecurityHelper实现注册机制如下:
a. 注册码产生过程:
注册信息(包括用户名等信息)—> RSA私钥加密 —> 注册码。
b. 软件验证注册码过程:
注册码 —> RSA公钥验证 —> 验证成功或失败。


实现代码
1)辅助类提供的方法接口如下所示:
/// <summary>
/// 非对称加密生成的私钥和公钥
/// </summary>
/// <param name=”privateKey”>私钥</param>
/// <param name=”publicKey”>公钥</param>
public static void GenerateRSAKey(out string privateKey, out string publicKey)
#region 非对称数据加密(公钥加密)
/// <summary>
/// 非对称加密字符串数据,返回加密后的数据
/// </summary>
/// <param name=”publicKey”>公钥</param>
/// <param name=”originalString”>待加密的字符串</param>
/// <returns>加密后的数据</returns>
public static string RSAEncrypt(string publicKey, string originalString)
/// <summary>
/// 非对称加密字节数组,返回加密后的数据
/// </summary>
/// <param name=”publicKey”>公钥</param>
/// <param name=”originalBytes”>待加密的字节数组</param>
/// <returns>返回加密后的数据</returns>
public static string RSAEncrypt(string publicKey, byte[] originalBytes)
#endregion
#region 非对称解密(私钥解密)
/// <summary>
/// 非对称解密字符串,返回解密后的数据
/// </summary>
/// <param name=”privateKey”>私钥</param>
/// <param name=”encryptedString”>待解密数据</param>
/// <returns>返回解密后的数据</returns>
public static string RSADecrypt(string privateKey, string encryptedString)
/// <summary>
/// 非对称解密字节数组,返回解密后的数据
/// </summary>
/// <param name=”privateKey”>私钥</param>
/// <param name=”encryptedBytes”>待解密数据</param>
/// <returns></returns>
public static string RSADecrypt(string privateKey, byte[] encryptedBytes)
#endregion
#region 非对称加密签名、验证
/// <summary>
/// 使用非对称加密签名数据
/// </summary>
/// <param name=”privateKey”>私钥</param>
/// <param name=”originalString”>待加密的字符串</param>
/// <returns>加密后的数据</returns>
public static string RSAEncrypSignature(string privateKey, string originalString)
/// <summary>
/// 对私钥加密签名的字符串,使用公钥对其进行验证
/// </summary>
/// <param name=”originalString”>未加密的文本,如机器码</param>
/// <param name=”encrytedString”>加密后的文本,如注册序列号</param>
/// <returns>如果验证成功返回True,否则为False</returns>
public static bool Validate(string originalString, string encrytedString)
/// <summary>
/// 对私钥加密的字符串,使用公钥对其进行验证
/// </summary>
/// <param name=”originalString”>未加密的文本,如机器码</param>
/// <param name=”encrytedString”>加密后的文本,如注册序列号</param>
/// <param name=”publicKey”>非对称加密的公钥</param>
/// <returns>如果验证成功返回True,否则为False</returns>
public static bool Validate(string originalString, string encrytedString, string publicKey)#endregion
2) 辅助类RSASecurityHelper的使用例子代码如下所示
//生成加解密私钥、公钥
string publicKey = “”;
string privateKey = “”;
RSASecurityHelper.GenerateRSAKey(out privateKey, out publicKey);
string originalString = “testdata”;
string encryptedString = RSASecurityHelper.RSAEncrypt(publicKey, originalString);
string originalString2 = RSASecurityHelper.RSADecrypt(privateKey, encryptedString);
if (originalString == originalString2)
{
MessageUtil.ShowTips(“解密完全正确”);
}
else
{
MessageUtil.ShowWarning(“解密失败”);
}
string regcode = RSASecurityHelper.RSAEncrypSignature(privateKey, originalString);
bool validated = RSASecurityHelper.Validate(originalString, regcode, publicKey);MessageUtil.ShowTips( validated ? “验证成功” : “验证失败”);
3)实际项目使用的注册验证代码如下所示。
/// <summary>
/// 每次程序运行时候,检查用户是否注册
/// </summary>
/// <returns>如果用户已经注册, 那么返回True, 否则为False</returns>
public bool CheckRegister()
{
// 先获取用户的注册码进行比较
string serialNumber = string.Empty; //注册码
RegistryKey reg = Registry.CurrentUser.OpenSubKey(UIConstants.SoftwareRegistryKey, true);
if (null != reg)
{
serialNumber = (string)reg.GetValue(“SerialNumber”);
Portal.gc.bRegisted = Portal.gc.Register(serialNumber);
}
return Portal.gc.bRegisted;
}
/// <summary>
/// 调用非对称加密方式对序列号进行验证
/// </summary>
/// <param name=”serialNumber”>正确的序列号</param>
/// <returns>如果成功返回True,否则为False</returns>
public bool Register(String serialNumber)
{
string hardNumber = HardwareInfoHelper.GetCPUId();
return RSASecurityHelper.Validate(hardNumber, serialNumber);
}
public string GetHardNumber()
{
return HardwareInfoHelper.GetCPUId();}
2、 DES对称加解密、AES RijndaelManaged加解密、Base64加密解密、MD5加密等操作辅助类 EncodeHelper
实现效果
1)本辅助类主要是用来方便实现DES对称加解密、AES RijndaelManaged加解密、Base64加密解密、MD5加密等操作。
2)本辅助类实现多种加解密处理,可以实现字符串、文件、文件流等加密处理。该加密辅助类汇集各种加密处理逻辑,是一个非常常用、方便应对各种加密处理的辅助类。
实现代码
1)辅助类提供的方法接口如下所示:
/// <summary>
/// 使用默认加密
/// </summary>
/// <param name=”strText”></param>
/// <returns></returns>
public static string DesEncrypt(string strText)
/// <summary>
/// 使用默认解密
/// </summary>
/// <param name=”strText”>解密字符串</param>
/// <returns></returns>
public static string DesDecrypt(string strText)
/// <summary>
/// 加密字符串,注意strEncrKey的长度为8位
/// </summary>
/// <param name=”strText”>待加密字符串</param>
/// <param name=”strEncrKey”>加密键</param>
/// <returns></returns>
public static string DesEncrypt(string strText, string strEncrKey)
/// <summary>
/// 解密字符串,注意strEncrKey的长度为8位
/// </summary>
/// <param name=”strText”>待解密的字符串</param>
/// <param name=”sDecrKey”>解密键</param>
/// <returns>解密后的字符串</returns>
public static string DesDecrypt(string strText, string sDecrKey)
/// <summary>
/// 加密数据文件,注意strEncrKey的长度为8位
/// </summary>
/// <param name=”m_InFilePath”>待加密的文件路径</param>
/// <param name=”m_OutFilePath”>输出文件路径</param>
/// <param name=”strEncrKey”>加密键</param>
public static void DesEncrypt(string m_InFilePath, string m_OutFilePath, string strEncrKey)
/// <summary>
/// 解密数据文件,注意strEncrKey的长度为8位
/// </summary>
/// <param name=”m_InFilePath”>待解密的文件路径</param>
/// <param name=”m_OutFilePath”>输出路径</param>
/// <param name=”sDecrKey”>解密键</param>
public static void DesDecrypt(string m_InFilePath, string m_OutFilePath, string sDecrKey)
#endregion
#region 对称加密算法AES RijndaelManaged加密解密
/// <summary>
/// 对称加密算法AES RijndaelManaged加密(RijndaelManaged(AES)算法是块式加密算法)
/// </summary>
/// <param name=”encryptString”>待加密字符串</param>
/// <returns>加密结果字符串</returns>
public static string AES_Encrypt(string encryptString)
/// <summary>
/// 对称加密算法AES RijndaelManaged加密(RijndaelManaged(AES)算法是块式加密算法)
/// </summary>
/// <param name=”encryptString”>待加密字符串</param>
/// <param name=”encryptKey”>加密密钥,须半角字符</param>
/// <returns>加密结果字符串</returns>
public static string AES_Encrypt(string encryptString, string encryptKey)
/// <summary>
/// 对称加密算法AES RijndaelManaged解密字符串
/// </summary>
/// <param name=”decryptString”>待解密的字符串</param>
/// <returns>解密成功返回解密后的字符串,失败返源串</returns>
public static string AES_Decrypt(string decryptString)
/// <summary>
/// 对称加密算法AES RijndaelManaged解密字符串
/// </summary>
/// <param name=”decryptString”>待解密的字符串</param>
/// <param name=”decryptKey”>解密密钥,和加密密钥相同</param>
/// <returns>解密成功返回解密后的字符串,失败返回空</returns>
public static string AES_Decrypt(string decryptString, string decryptKey)
/// <summary>
/// 加密文件流
/// </summary>
/// <param name=”fs”>文件流</param>
/// <returns></returns>
public static CryptoStream AES_EncryptStrream(FileStream fs, string decryptKey)
/// <summary>
/// 解密文件流
/// </summary>
/// <param name=”fs”>文件流</param>
/// <returns></returns>
public static CryptoStream AES_DecryptStream(FileStream fs, string decryptKey)
/// <summary>
/// 对指定文件加密
/// </summary>
/// <param name=”InputFile”>输入文件</param>
/// <param name=”OutputFile”>输出文件</param>
/// <returns></returns>
public static bool AES_EncryptFile(string InputFile, string OutputFile)
/// <summary>
/// 对指定的文件解压缩
/// </summary>
/// <param name=”InputFile”>输入文件</param>
/// <param name=”OutputFile”>输出文件</param>
/// <returns></returns>
public static bool AES_DecryptFile(string InputFile, string OutputFile)
#endregion
#region Base64加密解密
/// <summary>
/// Base64是一種使用64基的位置計數法。它使用2的最大次方來代表僅可列印的ASCII 字元。
/// 這使它可用來作為電子郵件的傳輸編碼。在Base64中的變數使用字元A-Z、a-z和0-9 ,
/// 這樣共有62個字元,用來作為開始的64個數字,最後兩個用來作為數字的符號在不同的
/// 系統中而不同。
/// Base64加密
/// </summary>
/// <param name=”str”>Base64方式加密字符串</param>
/// <returns></returns>
public static string Base64Encrypt(string str)
/// <summary>
/// Base64解密字符串
/// </summary>
/// <param name=”str”>待解密的字符串</param>
/// <returns></returns>
public static string Base64Decrypt(string str)
#endregion
#region MD5加密
/// <summary>
/// 使用MD5加密字符串
/// </summary>
/// <param name=”strText”>待加密的字符串</param>
/// <returns>MD5加密后的字符串</returns>
public static string MD5Encrypt(string strText)
/// <summary>
/// 使用MD5加密的Hash表
/// </summary>
/// <param name=”input”>待加密字符串</param>
/// <returns></returns>
public static string MD5EncryptHash(String input)
/// <summary>
/// 使用Md5加密为16进制字符串
/// </summary>
/// <param name=”input”>待加密字符串</param>
/// <returns></returns>
public static string MD5EncryptHashHex(String input)
/// <summary>
/// MD5 三次加密算法.计算过程: (QQ使用)
/// 1. 验证码转为大写
/// 2. 将密码使用这个方法进行三次加密后,与验证码进行叠加
/// 3. 然后将叠加后的内容再次MD5一下,得到最终验证码的值
/// </summary>
/// <param name=”s”></param>
/// <returns></returns>
public static string EncyptMD5_3_16(string s)
#endregion
/// <summary>
/// SHA256函数
/// </summary>
/// <param name=”str”>原始字符串</param>
/// <returns>SHA256结果(返回长度为44字节的字符串)</returns>
public static string SHA256(string str)
/// <summary>
/// 加密字符串(使用MD5+Base64混合加密)
/// </summary>
/// <param name=”input”>待加密的字符串</param>
/// <returns></returns>
public static string EncryptString(string input)
/// <summary>
/// 解密加过密的字符串(使用MD5+Base64混合加密)
/// </summary>
/// <param name=”input”>待解密的字符串</param>
/// <param name=”throwException”>解密失败是否抛异常</param>
/// <returns></returns>
public static string DecryptString(string input, bool throwException)2) 辅助类EncodeHelper的使用例子代码如下所示
/// <summary>
/// 对字符串加密
/// </summary>
/// <returns></returns>
private string EncodePassword(string passwordText)
{
return EncodeHelper.MD5Encrypt(passwordText);}
private void btnEncrypt_Click(object sender, EventArgs e)
{
string original = “测试加密字符串”;
Console.WriteLine(“original:” + original);
string encrypt = EncodeHelper.SHA256(original);
Console.WriteLine(“EncodeHelper.SHA256” + encrypt);
//DES加解密
encrypt = EncodeHelper.DesEncrypt(original);
Console.WriteLine(“EncodeHelper.DesEncrypt:” + encrypt);
string decrypt = EncodeHelper.DesDecrypt(encrypt);
Console.WriteLine(“EncodeHelper.DesDecrypt:” + decrypt);
//MD5加密
encrypt = EncodeHelper.MD5Encrypt(original);
Console.WriteLine(“EncodeHelper.MD5Encrypt:” + encrypt);
encrypt = EncodeHelper.MD5EncryptHash(original);
Console.WriteLine(“EncodeHelper.MD5EncryptHash:” + encrypt);
encrypt = EncodeHelper.MD5EncryptHashHex(original);
Console.WriteLine(“EncodeHelper.MD5EncryptHashHex” + encrypt);
encrypt = EncodeHelper.EncyptMD5_3_16(original);
Console.WriteLine(“EncodeHelper.EncyptMD5_3_16:” + encrypt);
//Base64加解密
encrypt = EncodeHelper.Base64Encrypt(original);
Console.WriteLine(“EncodeHelper.Base64Encrypt” + encrypt);
decrypt = EncodeHelper.Base64Encrypt(encrypt);
Console.WriteLine(“EncodeHelper.Base64Encrypt” + decrypt);
encrypt = EncodeHelper.AES_Encrypt(original);
Console.WriteLine(“EncodeHelper.AES_Encrypt” + encrypt);
decrypt = EncodeHelper.AES_Decrypt(encrypt);Console.WriteLine(“EncodeHelper.AES_Decrypt” + decrypt);

3、 MD5各种长度加密字符、验证MD5等操作辅助类 MD5Util
实现效果
1)本辅助类主要是用来方便实现MD5各种长度加密字符、验证MD5等操作。
2)MD5即Message-Digest Algorithm 5(信息-摘要算法 5),用于确保信息传输完整一致。是计算机广泛使用的散列算法之一(又译摘要算法、哈希算法)。
3)MD5已经广泛使用在为文件传输提供一定的可靠性方面。例如,服务器预先提供一个MD5校验和,用户下载完文件以后,用MD5算法计算下载文件的MD5校验和,然后通过检查这两个校验和是否一致,就能判断下载的文件是否出错
实现代码
1)辅助类提供的方法接口如下所示:
/// <summary>
/// 获得32位的MD5加密
/// </summary>
public static string GetMD5_32(string input)
/// <summary>
/// 获得16位的MD5加密
/// </summary>
public static string GetMD5_16(string input)
/// <summary>
/// 获得8位的MD5加密
/// </summary>
public static string GetMD5_8(string input)
/// <summary>
/// 获得4位的MD5加密
/// </summary>
public static string GetMD5_4(string input)
/// <summary>
/// 添加MD5的前缀,便于检查有无篡改
/// </summary>
public static string AddMD5Profix(string input)
/// <summary>
/// 移除MD5的前缀
/// </summary>
public static string RemoveMD5Profix(string input)
/// <summary>
/// 验证MD5前缀处理的字符串有无被篡改
/// </summary>
public static bool ValidateValue(string input)
#region MD5签名验证
/// <summary>
/// 对给定文件路径的文件加上标签
/// </summary>
/// <param name=”path”>要加密的文件的路径</param>
/// <returns>标签的值</returns>
public static bool AddMD5(string path)
/// <summary>
/// 对给定路径的文件进行验证,如果一致返回True,否则返回False
/// </summary>
/// <param name=”path”></param>
/// <returns>是否加了标签或是否标签值与内容值一致</returns>public static bool CheckMD5(string path)
2) 辅助类
MD5Util 的使用例子代码如下所示
//为文件增加MD5编码标签,然后验证是否被修改
string file = @”c:\test.xls”;
bool flag2 = MD5Util.AddMD5(file);
Console.WriteLine(flag2);
//对给定路径的文件进行验证,如果一致返回True,否则返回False
bool flag3 = MD5Util.CheckMD5(file);Console.WriteLine(flag3);
4、基于Base64的加密编码辅助类 Base64Util
实现效果
1)本辅助类主要是用来方便实现基于Base64的加密编码。
2)Base64被定义为:Base64内容传送编码被设计用来把任意序列的8位字节描述为一种不易被人直接识别的形式。Base64编码一般在电子邮件中可以查看到,打开一封Email,查看其原始信息(您可以通过收取、导出该邮件用文本编辑器查看)。加密是肯定的,但是加密的目的不是让用户发送非常安全的Email。这种加密方式主要就是“防君子不防小人”。即达到一眼望去完全看不出内容即可。
3)采用Base64编码不仅比较简短,同时也具有不可读性,即所编码的数据不会被人用肉眼所直接看到。
实现代码
1)辅助类提供的方法接口如下所示:
/// <summary>
/// 使用默认的密码表加密字符串
/// </summary>
/// <param name=”input”>待加密字符串</param>
/// <returns></returns>
public static string Encrypt(string input)
/// <summary>
/// 使用默认的密码表解密字符串
/// </summary>
/// <param name=”input”>待解密字符串</param>
/// <returns></returns>
public static string Decrypt(string input)
/// <summary>
/// 获取具有标准的Base64密码表的加密类
/// </summary>
/// <returns></returns>public static Base64Util GetStandardBase64()
2) 辅助类Base64Util的使用例子代码如下所示
private void btnBase64_Click(object sender, EventArgs e)
{
string original = “这是一个测试的Base64加密字符串”;
string encrypt = Base64Util.Encrypt(original);
Console.WriteLine(encrypt);//输出内容:6L*Z5pi_5LiA5Liq5rWL6K*V55qEQmFzZTY05Yqg5b*G5b2X56ym5Liy
string decrypt = Base64Util.Decrypt(encrypt);
Debug.Assert(original == decrypt);//验证相等}
5、QQ密码加密操作辅助类 QQEncryptUtil
实现效果
1)本辅助类主要是用来方便实现QQ密码加密操作。
2)在QQ的很多模拟网页采集数据,需要输入用户账号、密码,其中密码是需要进行加密操作的,一般使用js脚本实现,这里把它转化为C#的代码操作,其实也就是把密码和验证码通过3次MD5加密实现的。
实现代码
1)辅助类提供的方法接口如下所示:
/// <summary>
/// QQ根据密码及验证码对数据进行加密
/// </summary>
/// <param name=”password”>原始密码</param>
/// <param name=”verifyCode”>验证码</param>
/// <returns></returns>public static string EncodePasswordWithVerifyCode(string password, string verifyCode)
2) 辅助类QQEncryptUtil的使用例子代码如下所示
private bool CheckLogin()
{
HttpHelper httpHelper = new HttpHelper();
string refUrl = “http://ui.ptlogin2.qq.com/cgi-bin/login?appid=3000801&s_url=http%3A%2F%2Fqun.qq.com%2Fgod%2Fsucc.htm&f_url=loginerroralert&lang=2052&bgcolor=ffffff&style=1&low_login=1&link_target=blank&target=self&hide_title_bar=1&dummy=1”;
string verifyCode = this.txtVerify.Text;
string postData = string.Format(“u={0}&p={1}&verifycode={2}&aid=3000801&u1=http%3A%2F%2Fqun.qq.com%2Fgod%2Fsucc.htm&h=1&ptredirect=0&ptlang=2052&from_ui=1&dumy=&fp=loginerroralert”,
this.txtUsername.Text, QQEncryptUtil.EncodePasswordWithVerifyCode(this.txtPassword.Text, verifyCode), verifyCode);
string result = httpHelper.GetHtml(“http://ptlogin2.qq.com/login?” + postData, Portal.gc.cookieQun, refUrl);
string errorTxt = result;
bool isLogin = result.Contains(“登录成功!”);
return isLogin;}
CHM帮助文档持续更新中,统一下载地址是: http://www.iqidi.com/download/commonshelp.rar
最新公用类库DLL+XML注释文件下载地址是:http://files.cnblogs.com/wuhuacong/WHC.OrderWater.Commons.rar
主要研究技术:代码生成工具、Visio二次开发、客户关系管理软件、送水管理软件等共享软件开发
专注于Winform开发框架、Web开发框架、WCF开发框架的研究及应用。
转载请注明出处:
撰写人:伍华聪 http://www.iqidi.com标签: 公用类库使用帮助
-
JavaScript MVC 框架技术选型(转)
你很喜欢Gmail和Trello之类的单页面应用,但是不太确定该从何开始。也许你的JavaScript代码是如此的杂乱无章,以致于你很想在下一个项目上尝试下JavaScript MVC库和框架,却苦于没有头绪?我正在撰写一本单页面应用的书,所以我阅读了大量网上的相关资料。在这里我尝试提供一些看法,希望可以帮助你下决定。
简介
这里讨论的是时下最热的框架,AngularJS、Backbone、Ember和Knockout。同时提到了Batman、CANjs、Meteor和Spine,但是没有详细展开。
我们从多个不同的角度考察每个项目,包括社区、领导、成熟度、大小、依赖、互操作性、启发、理念和特性。
社区
社区是一个衡量任何开源项目健康程度的重要指数。以下表格显示了GitHub上每个项目的关注者数量。
你当然不该仅仅根据这些数据做决定,但是它们确实为你提供了关于这些框架的一些感性认识:
最主流:
- Backbone.js
- AngularJS
正在高速成长的:
- AngularJS
- Meteor
- Ember
- Knockout
关注总量较低但是增长迅猛的:
- CANjs
增长性
特别值得注意的是AngularJS 13个月以来的惊人增长(379%)。在你做决定的时候要考虑上这一点。下面的图表比较了13个月以来GitHub关注者的增长速度,可以看出某个项目的社区成长的速度。考虑到原先的社区大小,Meteor(130%)、Ember(104%)、Knockout(76%)和Backbone(64%)的增长速度也很惊人。
领导
了解项目的核心开发者的背景,他们创建框架时尝试解决的问题,有助于你欣赏他们在设计上的决策和动机。例如,David Heinemeier Hansson,流行的Ruby on Rails框架的缔造者,是37signals的签约开发者,从事项目设计,每周只有10小时能花在开发框架上。Ruby on Rails事实上是从他和37signals的签约工作中提取出来的。这一背景有助于你理解为什么这个框架需要将开发效率提升到极限——这意味这使用大量的约定(已经做出的决定)和支架程序(生成的代码)。下面,我将介绍JavaScript MVC 框架的缔造者,也许也能激起你对他们的工作的欣赏。
Backbone
Jeremy Ashkenas和DocumentCloud
Jeremy Ashkenas是CoffeeScript编程语言、Backbone.js JavaScript框架和Underscore.js JavaScript工具库的创立者。根据维基百科,他现在在NYTimes/DocumentCloud从事互动新闻方面的开发。
图片来自The Canadian University Software Engineering Conference。
AngularJS
AngularJS最初由Google的Miško Hevery和Adam Abrons于2009年开发,当时是一个在线JSON存储服务的一部分。Abrons后来离开了这个项目,但是在Google工作的Hevery继续开发,和Google的员工Igor Minár、Vojta Jína一起维护这个库。
图片来自Devoxx 2012
Knockout
Steve Sanderson是Knockout的原作者。Steve Sanderson现在为微软工作,他所在的团队开发ASP.NET、IIS和其他web项目。他以前以外包开发者或顾问身份为Bristol周边的客户开发.NET下的软件,他还为Apress写了一些书,包括《Pro ASP.NET MVC框架》。
Ember
Ember核心成员中最知名的公众人物是Yehuda Katz和Tom Dale。
Yehuda Katz是Ember.js、Ruby on Rails和jQuery的核心开发者,他白天的时间花在他创办的创业公司,Tilde Inc.。Yehuda是畅销书《jQuery in Action》和《Rails 3 in Action》的作者之一。
Tom Dale原先在SproutCore团队工作。他以前是苹果软件工程师,在开发MobileMe和iCloud应用时精通了前端JavaScript技能。
图片来自Ember Team
Meteor
Meteor的开发团队刚刚得到了1.12千万美金,所以他们可以全职开发。他们的团队有12名开发者,每个开发者的简历都让人印象深刻。这个团队拥有雄心勃勃的计划,超越了大多数专注于组织客户端代码和状态的JavaScript MVC框架。Meteor是一个全端框架,包括服务器架构和数据库。
成熟度
评估框架的成熟度可以帮助你理解在项目中使用新技术的风险。未经考验的新框架在文档、扩展性、稳定性(API改变)和支持(寻找了解该框架的开发者来维护代码)方面可能存在问题,这些问题可能导致出乎意料的结果,即使从其他方面看起来决策很明智。需要考虑的项目包括:多少生产环境下的应用使用这些框架?这些应用有多少用户?文档是否良好?例子和教程是否充足?例子是否过时?API是否稳定?其他开发者了解或正打算了解这门技术么?
- Backbone(最成熟)
- 大量3年以上的生产环境应用,包括GroupOn、 FourSquare、USAToday、DocumentCloud。
- 良好的文档。
- 良好的示例代码,但是很多都过时了。
- API非常稳定。
- GitHub上有大量关注者。
- AngularJS(成熟)
- Google将其用于生产环境,但是不像其他项目一样拥有长久的历史记录。
- 良好且持续改进的文档。
- 大量的示例代码。
- GitHub上有大量关注者。
- Knockout(成熟)
- 用于生产环境至今已有2年。
- 良好的文档,内含类似jsfiddle的代码样例。
- API很稳定。
- 大量的示例代码。
- GitHub上有大量关注者。
- Ember.js
- 在两年的开发之后,第一个可用于生产的发布(1.0)在2013年8月30日放出。
- 文档正在改善。
- API在1.0之前都不稳定(这是有意的)。
- 大量示例代码,由于1.0前的API变动,有些已经过时。
- GitHub上有大量关注者。
- Meteor
- 处于开发的早期阶段,较多地用于示例应用
- 文档不错,然而尚不完整
- API仍处于变动之中。
- 一些示例代码。
- GitHub上有大量关注者。
大小
了解每个框架的大小,它会在你的应用中增加多少分量是很重要的。大小会影响性能,不过它同时也会暗示你这个框架的雄心有多大,你学习它可能需要花多少时间,以及它提供多少帮助你构建应用的方式(即特性和鲁棒性)。一个框架的野心越大,特性越多,通常也就意味更难在应用的页面上将它与其他部件组合。轻量的框架更像一个库,将他集成到你的项目中所耗费的精力也相对较小。
包括Backbone和Spine在内的一些项目为自己的轻量而自豪,这些项目更多地将自己视作库,而不是框架。通常这些小型的框架留下了空间,你可以使用你自己的库来实现特定功能,例如模板和路由。我在讨论这些框架的特性的时候将继续讨论这个话题。
包括Ember和AngularJS在内的其他项目雄心勃勃,更适合叫做框架。它们通常拥有更多内建的特性,更少依赖外部库。
下面的列表显示了我更倾向于将哪些项目归入库或框架:
库
框架Backbone
EmberKnockout
AngularJSSpine
BatmanCanJS
Meteor依赖性
使用这些项目构建真实世界的应用的时候还需要哪些库?以下的图表展示了为了保证开发效率每个库所需的依赖,以及这些依赖的大小。
通过从cdnjs下载库,我们收集了这些数据。在实践中,大多数的项目会使用jQuery配合这些框架处理DOM,因为需要动画和AJAX。在移动应用中,使用Zepto.js来代替jQuery处理DOM不是什么稀奇的事。Zepto.js是一个比jQuery轻量得多的库。虽然Zepto.js不支持Internet Explorer,但是移动应用通常不需要为此操心。AngularJS包含了一个jQuery 的缩减版jQLite。但是如果你在项目中使用了jQuery的话,它会被覆盖。AngularJS团队鼓励开发者,如非必要,不要添加完整的jQuery库。为了帮助你做出正确的选择,下面的表格同时显示了移动版(假定使用Zepto.js)和web版(假定使用jQuery)。
互操作性
这一部分讨论是否框架设计为控制整个页面或者它可以被用于现存页面的一个部分——你可能想渐渐将新技术引入现有的项目。前面的库和框架的讨论基本可以体现每个项目的互操作性,库更倾向于很容易地集成到现存的项目,而框架为你做更多的事,但是不容易和其他项目配合。
AngularJS
AngularJS可以和其他库很好地配合,但是它鼓励开发者们考虑是否可以不用jQuery和jQueryUI.事实上Angular内置了一个jQuery的子集jqLite。遵循这一实践的理由是让单元测试更容易,因为很多依赖库和插件设计的时候没有考虑单元测试,相应地更难和单元测试配合。在实践中,大多数的开发者最终还是因为某些特性使用了jQuery.
Backbone
由于Backbone的小尺寸和无预设的架构,将其包含在众多流行的客户端库和服务器端技术中很容易。
Ember.js
被设计为在运行时控制整个页面,所以不太适合用于页面的部分。
Knockout.js
可以在项目中作为小组件使用,不控制整个页面。
启发
记者采访音乐家时最爱问的问题是“你在成长的时候听哪些艺术家的音乐,或者说,谁启发了你?”这个问题常常使得读者能够预期音乐家的声乐。这些框架中大部分的观念都不是全新的,而是来自于创造者以前工作的项目中喜欢的部分。这一部分总结了我从框架创造者的访谈中收集到的关于启发的信息。
AngularJS
HTML类的声明性的语言,Adobe和Flex、微软的WPF\Silverligt等RIA技术给AngularJS的影响很深。这些声明性技术没有”主体“方法,仅仅表达需要发生什么,而不指定具体实现。视图和模型中的数据双向绑定是这一声明式编程风格在绝佳例子。此外,在Google的服务器端Java代码中大量使用的依赖注入和IOC容器(特别是Juice)也启发了AngularJS的创造者。他们重视单元测试,需要框架被设计允许依赖注入,这样测试就可以从其他应用层剥离出来,运行起来也会更快。
Ember
Tom Dale在Quora上谈了Ember受到的影响:
Ember.js刚开始开发的时候,我们从Cocoa等本地应用程序框架引入一些概念,不过后来我们觉得这些概念弊大于利,或者说它们和Web应用程序格格不入。因此,我们开始从Ruby on Rails和Backbone.js 等开源项目中寻找灵感。因此,Ember.js结合了本地应用的强大和现代web的轻量。
此外,Ember.js是SproutCore JavaScript库的进化版,SproutCore停止仿效Cocoa而更多地借鉴jQuery的时候,Ember诞生了,理解这一点很重要。
Knockout
hanselminutes的播客提供了Steve Sanderson受到哪些方面启发的背景信息。总结一下,MVVM设计模式和微软的WPF、Sliverlight等声明性技术是最大的启发者。你可能会发现Knockout的最佳特性——声明性的数据双向绑定——和Anjular相似,因为两者的启发者是相似的。
理念
报纸在报道新闻的时候努力保持中立。唯一的例外是编者案,鼓励表达观点,作者通常在问题上占据一个强烈的立场。但是大多数情况,这两者既不是严格的中立报道,也不是强烈的意见表达,而是位于两者之间的连续统。技术框架也有类似的划分,即是否强主张。例如,Ruby on Rails推崇约定优于配置,并且为开发者做了大量决定,包括文件结构和数据访问。相应地,它被认为是强主张的。其他Sinatra类的服务器端框架更轻量,并不预设文件结构和数据访问。相应的,被看成是无主张的。服务端框架有理念,客户端JavaScript MVC框架同样有,我们讨论的框架也可以被置于强主张和无主张的连续统中考察。让我们看看每个项目,然后讨论他们的理念。
Backbone: 无主张
Backbone是最开明的框架,极度无主张,允许开发者做出自己的决定,有时这会导致代码差异过大而难以维护。唯一的例外是Backbone假定服务器端有一个REST服务,我会在特性部分详细讨论这一点。这一假定可以通过覆盖模型的sync方法来绕过。
AngularJS: 强主张
AngularJS有较强的主张,特别是它强调可测试性和依赖注入。此外,HTML类的声明性编程很棒的理念也在框架中广泛体现。
Ember: 极度强主张
Ember力求开发者仅对应用的特有部分作决定,其余全部交给约定和支架。这个理念和Ruby on Rails和jQuery很接近。这一理念最好的表达出现在emberjs.com的网站上:
不要浪费时间做那些无关紧要的选择。Ember.js吸纳了常见的惯用法,因此你可以专注于应用的特殊部分,而不是重新发明轮子。
Ember标准化了文件和url结构,当然,有必要的时候也允许你覆盖这些设定。你可以预期的是大量的代码会为你生成,大量的类似文件结构的约定。相应地,你需要做出的常规选择更少,因为框架已经为你选定了合理的默认值,你可以着手构建你的应用的特殊部分。
Knockout: 无主张
路由和数据存储留给开发者决定。不预设文件或URL结构。甚至允许用基于字符串的模板替换声明性的基于DOM的模板。
特性
我们可以将这些JavaScript MVC框架看成是帮助开发者构建单页应用的常用特性集合。每个框架实现这些特性的方式,或者不实现这些特性的方式(通过其他库来补全框架的功能)是值得留心的。
JavaScript MVC框架的主要特性是什么?
- HTML和客户端JavaScript对象模型的双向绑定
- 视图模板
- 数据存储(本地存储或者通过服务器存储到数据库)
- URL路由(确保后退按钮和搜索引擎正常工作)
除此以外,一些框架提供常用的语言层面的服务,例如通用的pub/sub事件模型和面向对象的继承支持。
数据绑定
这是最受吹捧的特性。你通过HTML input修改了数据,绑定到input的JavaScript对象马上更新,其他绑定的用户接口元素也随之更新。在很多框架中,反之亦然。如果你修改了JavaScript对象,html会自动刷新。这是一个web上的双向的数据绑定,我们在Flex、Windows Forms、WPF等富客户端应用框架中见过这类绑定。以下的表格显示了哪些框架支持数据绑定。
有些人可能持有异议,因为Backbone和Spine部分支持数据绑定。但是我觉得大量工作需要留给开发者,保险起见,不如说这些库不支持这些特性。
视图模板
客户端的JavaScript数据模型需要穿插在HTML中,这些框架采用两种方式解决问题。
基于字符串的模板(目前最流行的是handlebars.js),将字符串、文本模板中的动态部分替换为模型中的数据。字符串常被提到也饱受争议的特性之一是性能。其缺点是调试控制语句类的逻辑很困难。
基于DOM的模板拥抱标记语言的声明式本性,这是开了挂的html,通过html中的附加属性来描述需要的绑定和事件。这些库需要的代码大大减少,为开发者做了很多事情。
模型(可观察的:跟踪改动)
一些框架(Backbone、Spine)更专注于模型,要求开发者在base模型的基础上扩展JavaScript类,通过
.get()和.set()访问属性,这样就能跟踪改动,模型的变动也会触发事件。KnockoutJS让开发者在原始的JavaScript对象上应用可察封装,然后通过object.propertyName()访问属性(小心,别丢了括号)。其他库(AngularJS)对页面上的所有绑定的DOM元素作脏检查,因为没有标准的get和set访问器。因此将这些库用于大页面时将导致性能问题。这些库不仅需要更少的刷新模板的代码,也不需要你使用特定的get和set访问器来修改模型中的数据,所以你可以使用原始的JavaScript对象。这大大提升了开发效率,这一点在框架的初学者身上体现得尤为明显。
数据存储
这些框架通过以下方式将数据存储到服务器
- 与REST服务自动同步
- 需要开发者自行实现ajax调用,调用针对返回json的web服务
- 同时允许以上两种方式
REST
一些框架默认预设后端有非常整洁的REST JSON服务,并且,至少在默认的情况下,前端与后端频繁交互,在后台异步更新数据,而用户界面响应流畅。这些框架内部使用jQuery或Zepto发送合适的AJAX请求给服务器。用户界面的HTML DOM元素监听应用的JavaScript对象模型的改动,同步机制得到模型属性的更改提醒,将改动发送给REST服务,确保模型和服务器同步。
在线和离线
Backbone默认在客户端保存数据之前发送请求,这样服务器端和客户端同步就很容易。和Backbone非常类似的Spine框架,采用了不同的方式,在异步发送请求到服务器前,先在客户端存储记录,这提供了更好的用户界面响应,在移动应用中常发生的离线状态下也能工作。如果你的项目需要支持离线,需要了解清楚框架对该特性的支持
DIY
这些框架要求开发者使用
$.ajax(jQuery)来调用服务,或者添加兼容的开源库处理数据存储需求。数据存储特性
Meteor之类精心制作的框架拥有更完整的数据存储方案,但是要求服务器端有MongoDB数据库。这类方案试图提供一个扩展性优异的默认解决方案,提供从头到尾的JavaScript开发体验。
以下的表格总结了每个框架是如何处理数据存储的。
路由
将URL路由映射到JavaScript函数,可以支持浏览器的后退按钮。单页应用最大的缺点之一是由于页面无刷新,浏览器历史不会添加条目,所以后退按钮通常无法将用户带回页面的前一状态,除非开发者在主要的状态改变时做一些额外的工作,通过在URL后附加井号,或者,使用现代浏览器的push和pop状态,实现状态跟踪机制。总之,大多数项目都提供基本、初步而有用的功能。Knockout的做法很简单,允许你使用其他的第三方开源库。
苹果对苹果
考察各个框架的特性之后,我发现我并不是在做一个“苹果对苹果”的比较。一个更为公平的比较也许是将AngularJS和EmberJS之类全面的框架与配合第三方库使用的Backbone和KnockoutJS之类的MV*框架进行比较。具体来说,下面的比较会更有意义:
- AngularJS
- EmberJS
- Backbone 搭配 Marionette
- KnockoutJS 搭配 DurandalJS、HistoryJS或SammayJS。
以后的博客中我会继续深入。
告诉我更多
为项目选择JavaScript MVC框架时有大量需要考虑的事项,我希望本文是一个良好的开始。请在评论中分享你使用这些框架的体验,包括它们的优异之处,也包括它们使用上的陷阱。
-
ASP.NET impersonation
采用问答式, 快餐式获取要点.
如何查看当前线程正在什么用户权限上运行?
====================================
string currentUser = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
如何在ASP.NET应用程序中, 使用过了IIS验证的用户的权限来执行每一次请求?
====================================
在web.config文件中, 做如下修改:
<identity impersonate="true" />
如何在ASP.NET应用程序中指定一个用户, 然后让所有的请求都按照这个用户的权限来执行?
====================================
在web.config文件中, 做如下修改:
<identity impersonate="true" userName="accountname" password="password" />
如何在代码中进行impersonate?
====================================
System.Security.Principal.WindowsImpersonationContext impersonationContext; impersonationContext = ((System.Security.Principal.WindowsIdentity)User.Identity).Impersonate(); //Insert your code that runs under the security context of the authenticating user here. impersonationContext.Undo();一个具体的例子, 可以用在aspx中, 当然了用在cs中可以的.
public const int LOGON32_LOGON_INTERACTIVE = 2; public const int LOGON32_PROVIDER_DEFAULT = 0; WindowsImpersonationContext impersonationContext; [DllImport("advapi32.dll")] public static extern int LogonUserA(String lpszUserName, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken); [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern int DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken); [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern bool RevertToSelf(); [DllImport("kernel32.dll", CharSet = CharSet.Auto)] public static extern bool CloseHandle(IntPtr handle); public void Page_Load(Object s, EventArgs e) { if (impersonateValidUser("username", "domain", "password")) { //Insert your code that runs under the security context of a specific user here. undoImpersonation(); } else { //Your impersonation failed. Therefore, include a fail-safe mechanism here. } } private bool impersonateValidUser(String userName, String domain, String password) { WindowsIdentity tempWindowsIdentity; IntPtr token = IntPtr.Zero; IntPtr tokenDuplicate = IntPtr.Zero; if (RevertToSelf()) { if (LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) != 0) { if (DuplicateToken(token, 2, ref tokenDuplicate) != 0) { tempWindowsIdentity = new WindowsIdentity(tokenDuplicate); impersonationContext = tempWindowsIdentity.Impersonate(); if (impersonationContext != null) { CloseHandle(token); CloseHandle(tokenDuplicate); return true; } } } } if (token != IntPtr.Zero) CloseHandle(token); if (tokenDuplicate != IntPtr.Zero) CloseHandle(tokenDuplicate); return false; } private void undoImpersonation() { impersonationContext.Undo(); }资料来源:
How to implement impersonation in an ASP.NET application
http://support.microsoft.com/kb/306158
转自:http://www.cnblogs.com/awpatp/archive/2010/02/02/1662277.html
