.net framework2.0,3.0,3.5的CookieContainer的bug解决方法

用HttpWebRequest发送请求,附上了CookieContainer(CookieContainer里面确定已经包含了所有需要的Cookie),但是当发送请求后某些Cookie并没有发送出去,调试了两天,一直觉得是请求的网站设了什么古怪的限制,使请求老是发送不成功,最后用SocketSniff抓包发现少发送了几个Cookie(因为这些cookie涉及到几个子域名),检查CookieContainer,里面确实有这几个Cookie,最后只好反编译HttpWebRequest,在类CookieModule里发现方法OnSendingHeaders的如下代码,这个是把cookie设置到headers里面的关键地方:

internal static void OnSendingHeaders(HttpWebRequest httpWebRequest)
{
try
{
if (httpWebRequest.CookieContainer != null)
{
string str;
httpWebRequest.Headers.RemoveInternal("Cookie");
string cookieHeader = httpWebRequest.CookieContainer.GetCookieHeader(httpWebRequest.Address, out str);
if (cookieHeader.Length > 0)
{
httpWebRequest.Headers["Cookie"] = cookieHeader;
}
}
}
catch
{
}
}
问题出在GetCookieHeader这个方法里面,某些Cookie的domain判断错误导致没有附加上去。.Net framework4.0以下的都存在此问题。最后把程序框架调到4.0的,就没有这个问题了。当然4.0以下的框架版本可以用下面的方法处理一下CookieContainer里面domain。

  1. Don't use .Add(Cookie), Use only .Add(Uri, Cookie) method.
  2. Call BugFix_CookieDomain each time you add a cookie to the container or before you use .GetCookie or before system use the container.

    private void BugFix_CookieDomain(CookieContainer cookieContainer)
    {
        System.Type _ContainerType = typeof(CookieContainer);
        Hashtable table = (Hashtable)_ContainerType.InvokeMember("m_domainTable",
                                   System.Reflection.BindingFlags.NonPublic |
                                   System.Reflection.BindingFlags.GetField |
                                   System.Reflection.BindingFlags.Instance,
                                   null,
                                   cookieContainer,
                                   new object[] { });
        ArrayList keys = new ArrayList(table.Keys);
        foreach (string keyObj in keys)
        {
            string key = (keyObj as string);
            if (key[0] == '.')
            {
                string newKey = key.Remove(0, 1);
                table[newKey] = table[keyObj];
            }
        }
    }

C#用MD5CryptoServiceProvider把字符串加密成32位和16位Hash值

using System.Text;
using System.Security.Cryptography;

方法1:

16位

public string GetMd5(string str)
{
System.Security.Cryptography.MD5CryptoServiceProvider md5=new MD5CryptoServiceProvider();
string a=BitConverter.ToString(md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(str)),4,8);
a=a.Replace("-","");
return a;
}

32位

public string GetMd5(string str)
{
System.Security.Cryptography.MD5CryptoServiceProvider md5=new MD5CryptoServiceProvider();
string a=BitConverter.ToString(md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(str)));
a=a.Replace("-","");
return a;
}

方法2:

public string Hash(string toHash)
{
MD5CryptoServiceProvider crypto = new MD5CryptoServiceProvider();
byte[] bytes = Encoding.UTF7.GetBytes(toHash);
bytes = crypto.ComputeHash(bytes);
StringBuilder sb = new StringBuilder();
foreach (byte num in bytes)
{
sb.AppendFormat("{0:x2}", num);
}
return sb.ToString();        //32位
return sb.ToString().Substring(8,16);        //16位
}



c#:UNIX时间戳和DateTime的相互转换

// Unix时间戳格式转换为DateTime时间格式
public DateTime GetTime(string timeStamp)
{
    DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
    long lTime = long.Parse(timeStamp + "0000000");
    TimeSpan toNow = new TimeSpan(lTime);
    return dtStart.Add(toNow);
}

// DateTime时间格式转换为Unix时间戳格式
public int ConvertDateTimeInt(System.DateTime time)
{
    System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
    return (int)(time - startTime).TotalSeconds;
}

一个比较全的C#写的ftp类

using System;
using System.Net;
using System.IO;
using System.Text;
using System.Net.Sockets;

/// <summary>
/// FTPClient 的摘要说明。
/// </summary>
public class FTPClient
{
	#region 构造函数
	/// <summary>
	/// 缺省构造函数
	/// </summary>
	public FTPClient()
	{
		strRemoteHost = "";
		strRemotePath = "";
		strRemoteUser = "";
		strRemotePass = "";
		strRemotePort = 21;
		bConnected = false;
	} /// <summary>
	/// 构造函数
	/// </summary>
	/// <param name="remoteHost"></param>
	/// <param name="remotePath"></param>
	/// <param name="remoteUser"></param>
	/// <param name="remotePass"></param>
	/// <param name="remotePort"></param>
	public FTPClient( string remoteHost, string remotePath, string remoteUser, string remotePass, int remotePort )
	{
		strRemoteHost = remoteHost;
		strRemotePath = remotePath;
		strRemoteUser = remoteUser;
		strRemotePass = remotePass;
		strRemotePort = remotePort;
		Connect();
	}
	#endregion

	#region 登陆
	/// <summary>
	/// FTP服务器IP地址
	/// </summary>
	private string strRemoteHost;
	public string RemoteHost
	{
		get
		{
			return strRemoteHost;
		}
		set
		{
			strRemoteHost = value;
		}
	}
	/// <summary>
	/// FTP服务器端口
	/// </summary>
	private int strRemotePort;
	public int RemotePort
	{
		get
		{
			return strRemotePort;
		}
		set
		{
			strRemotePort = value;
		}
	}
	/// <summary>
	/// 当前服务器目录
	/// </summary>
	private string strRemotePath;
	public string RemotePath
	{
		get
		{
			return strRemotePath;
		}
		set
		{
			strRemotePath = value;
		}
	}
	/// <summary>
	/// 登录用户账号
	/// </summary>
	private string strRemoteUser;
	public string RemoteUser
	{
		set
		{
			strRemoteUser = value;
		}
	}
	/// <summary>
	/// 用户登录密码
	/// </summary>
	private string strRemotePass;
	public string RemotePass
	{
		set
		{
			strRemotePass = value;
		}
	} /// <summary>
	/// 是否登录
	/// </summary>
	private Boolean bConnected;
	public bool Connected
	{
		get
		{
			return bConnected;
		}
	}
	#endregion

	#region 链接
	/// <summary>
	/// 建立连接
	/// </summary>
	public void Connect()
	{
		socketControl = new Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp );
		IPEndPoint ep = new IPEndPoint( IPAddress.Parse( RemoteHost ), strRemotePort );
		// 链接
		try
		{
			socketControl.Connect( ep );
		}
		catch( Exception )
		{
			throw new IOException( "Couldn't connect to remote server" );
		}   // 获取应答码
		ReadReply();
		if( iReplyCode != 220 )
		{
			DisConnect();
			throw new IOException( strReply.Substring( 4 ) );
		}   // 登陆
		SendCommand( "USER " + strRemoteUser );
		if( !( iReplyCode == 331 || iReplyCode == 230 ) )
		{
			CloseSocketConnect();//关闭连接
			throw new IOException( strReply.Substring( 4 ) );
		}
		if( iReplyCode != 230 )
		{
			SendCommand( "PASS " + strRemotePass );
			if( !( iReplyCode == 230 || iReplyCode == 202 ) )
			{
				CloseSocketConnect();//关闭连接
				throw new IOException( strReply.Substring( 4 ) );
			}
		}
		bConnected = true;   // 切换到目录
		ChDir( strRemotePath );
	}
	/// <summary>
	/// 关闭连接
	/// </summary>
	public void DisConnect()
	{
		if( socketControl != null )
		{
			SendCommand( "QUIT" );
		}
		CloseSocketConnect();
	}
	#endregion

	#region 传输模式
	/// <summary>
	/// 传输模式:二进制类型、ASCII类型
	/// </summary>
	public enum TransferType { Binary, ASCII }; /// <summary>
	/// 设置传输模式
	/// </summary>
	/// <param name="ttType">传输模式</param>
	public void SetTransferType( TransferType ttType )
	{
		if( ttType == TransferType.Binary )
		{
			SendCommand( "TYPE I" );//binary类型传输
		}
		else
		{
			SendCommand( "TYPE A" );//ASCII类型传输
		}
		if( iReplyCode != 200 )
		{
			throw new IOException( strReply.Substring( 4 ) );
		}
		else
		{
			trType = ttType;
		}
	}
	/// <summary>
	/// 获得传输模式
	/// </summary>
	/// <returns>传输模式</returns>
	public TransferType GetTransferType()
	{
		return trType;
	}

	#endregion

	#region 文件操作
	/// <summary>
	/// 获得文件列表
	/// </summary>
	/// <param name="strMask">文件名的匹配字符串</param>
	/// <returns></returns>
	public string[] Dir( string strMask )
	{
		// 建立链接
		if( !bConnected )
		{
			Connect();
		}   //建立进行数据连接的socket
		Socket socketData = CreateDataSocket();

		//传送命令
		SendCommand( "NLST " + strMask );   //分析应答代码
		if( !( iReplyCode == 150 || iReplyCode == 125 || iReplyCode == 226 ) )
		{
			throw new IOException( strReply.Substring( 4 ) );
		}   //获得结果
		strMsg = "";
		while( true )
		{
			int iBytes = socketData.Receive( buffer, buffer.Length, 0 );
			strMsg += ASCII.GetString( buffer, 0, iBytes );
			if( iBytes < buffer.Length )
			{
				break;
			}
		}
		char[] seperator = { '\n' };
		string[] strsFileList = strMsg.Split( seperator );
		socketData.Close();//数据socket关闭时也会有返回码
		if( iReplyCode != 226 )
		{
			ReadReply();
			if( iReplyCode != 226 )
			{
				throw new IOException( strReply.Substring( 4 ) );
			}
		}
		return strsFileList;
	}
	/// <summary>
	/// 获取文件大小
	/// </summary>
	/// <param name="strFileName">文件名</param>
	/// <returns>文件大小</returns>
	private long GetFileSize( string strFileName )
	{
		if( !bConnected )
		{
			Connect();
		}
		SendCommand( "SIZE " + Path.GetFileName( strFileName ) );
		long lSize = 0;
		if( iReplyCode == 213 )
		{
			lSize = Int64.Parse( strReply.Substring( 4 ) );
		}
		else
		{
			throw new IOException( strReply.Substring( 4 ) );
		}
		return lSize;
	}
	/// <summary>
	/// 删除
	/// </summary>
	/// <param name="strFileName">待删除文件名</param>
	public void Delete( string strFileName )
	{
		if( !bConnected )
		{
			Connect();
		}
		SendCommand( "DELE " + strFileName );
		if( iReplyCode != 250 )
		{
			throw new IOException( strReply.Substring( 4 ) );
		}
	}
	/// <summary>
	/// 重命名(如果新文件名与已有文件重名,将覆盖已有文件)
	/// </summary>
	/// <param name="strOldFileName">旧文件名</param>
	/// <param name="strNewFileName">新文件名</param>
	public void Rename( string strOldFileName, string strNewFileName )
	{
		if( !bConnected )
		{
			Connect();
		}
		SendCommand( "RNFR " + strOldFileName );
		if( iReplyCode != 350 )
		{
			throw new IOException( strReply.Substring( 4 ) );
		}
		// 如果新文件名与原有文件重名,将覆盖原有文件
		SendCommand( "RNTO " + strNewFileName );
		if( iReplyCode != 250 )
		{
			throw new IOException( strReply.Substring( 4 ) );
		}
	}
	#endregion

	#region 目录操作
	/// <summary>
	/// 创建目录
	/// </summary>
	/// <param name="strDirName">目录名</param>
	public void MkDir( string strDirName )
	{
		if( !bConnected )
		{
			Connect();
		}
		SendCommand( "MKD " + strDirName );
		if( iReplyCode != 257 )
		{
			throw new IOException( strReply.Substring( 4 ) );
		}
	}

	/// <summary>
	/// 删除目录
	/// </summary>
	/// <param name="strDirName">目录名</param>
	public void RmDir( string strDirName )
	{
		if( !bConnected )
		{
			Connect();
		}
		SendCommand( "RMD " + strDirName );
		if( iReplyCode != 250 )
		{
			throw new IOException( strReply.Substring( 4 ) );
		}
	}

	/// <summary>
	/// 改变目录
	/// </summary>
	/// <param name="strDirName">新的工作目录名</param>
	public void ChDir( string strDirName )
	{
		if( strDirName.Equals( "." ) || strDirName.Equals( "" ) )
		{
			return;
		}
		if( !bConnected )
		{
			Connect();
		}
		SendCommand( "CWD " + strDirName );
		if( iReplyCode != 250 )
		{
			throw new IOException( strReply.Substring( 4 ) );
		}
		this.strRemotePath = strDirName;
	}

	#endregion

	#region 上传和下载
	/// <summary>
	/// 下载一批文件
	/// </summary>
	/// <param name="strFileNameMask">文件名的匹配字符串</param>
	/// <param name="strFolder">本地目录(不得以\结束)</param>
	public void Get( string strFileNameMask, string strFolder )
	{
		if( !bConnected )
		{
			Connect();
		}
		string[] strFiles = Dir( strFileNameMask );
		foreach( string strFile in strFiles )
		{
			if( !strFile.Equals( "" ) )//一般来说strFiles的最后一个元素可能是空字符串
			{
				Get( strFile, strFolder, strFile );
			}
		}
	}
	/// <summary>
	/// 下载一个文件
	/// </summary>
	/// <param name="strRemoteFileName">要下载的文件名</param>
	/// <param name="strFolder">本地目录(不得以\结束)</param>
	/// <param name="strLocalFileName">保存在本地时的文件名</param>
	public void Get( string strRemoteFileName, string strFolder, string strLocalFileName )
	{
		if( !bConnected )
		{
			Connect();
		}
		SetTransferType( TransferType.Binary );
		if( strLocalFileName.Equals( "" ) )
		{
			strLocalFileName = strRemoteFileName;
		}
		if( !File.Exists( strLocalFileName ) )
		{
			Stream st = File.Create( strLocalFileName );
			st.Close();
		}
		FileStream output = new
		 FileStream( strFolder + "\\" + strLocalFileName, FileMode.Create );
		Socket socketData = CreateDataSocket();
		SendCommand( "RETR " + strRemoteFileName );
		if( !( iReplyCode == 150 || iReplyCode == 125
		 || iReplyCode == 226 || iReplyCode == 250 ) )
		{
			throw new IOException( strReply.Substring( 4 ) );
		}
		while( true )
		{
			int iBytes = socketData.Receive( buffer, buffer.Length, 0 );
			output.Write( buffer, 0, iBytes );
			if( iBytes <= 0 )
			{
				break;
			}
		}
		output.Close();
		if( socketData.Connected )
		{
			socketData.Close();
		}
		if( !( iReplyCode == 226 || iReplyCode == 250 ) )
		{
			ReadReply();
			if( !( iReplyCode == 226 || iReplyCode == 250 ) )
			{
				throw new IOException( strReply.Substring( 4 ) );
			}
		}
	}
	/// <summary>
	/// 上传一批文件
	/// </summary>
	/// <param name="strFolder">本地目录(不得以\结束)</param>
	/// <param name="strFileNameMask">文件名匹配字符(可以包含*和?)</param>
	public void Put( string strFolder, string strFileNameMask )
	{
		string[] strFiles = Directory.GetFiles( strFolder, strFileNameMask );
		foreach( string strFile in strFiles )
		{
			//strFile是完整的文件名(包含路径)
			Put( strFile );
		}
	}
	/// <summary>
	/// 上传一个文件
	/// </summary>
	/// <param name="strFileName">本地文件名</param>
	public void Put( string strFileName )
	{
		if( !bConnected )
		{
			Connect();
		}
		Socket socketData = CreateDataSocket();
		SendCommand( "STOR " + Path.GetFileName( strFileName ) );
		if( !( iReplyCode == 125 || iReplyCode == 150 ) )
		{
			throw new IOException( strReply.Substring( 4 ) );
		}
		FileStream input = new
		 FileStream( strFileName, FileMode.Open );
		int iBytes = 0;
		while( ( iBytes = input.Read( buffer, 0, buffer.Length ) ) > 0 )
		{
			socketData.Send( buffer, iBytes, 0 );
		}
		input.Close();
		if( socketData.Connected )
		{
			socketData.Close();
		}
		if( !( iReplyCode == 226 || iReplyCode == 250 ) )
		{
			ReadReply();
			if( !( iReplyCode == 226 || iReplyCode == 250 ) )
			{
				throw new IOException( strReply.Substring( 4 ) );
			}
		}
	}

	#endregion

	#region 内部函数
	/// <summary>
	/// 将一行应答字符串记录在strReply和strMsg
	/// 应答码记录在iReplyCode
	/// </summary>
	private void ReadReply()
	{
		strMsg = "";
		strReply = ReadLine();
		iReplyCode = Int32.Parse( strReply.Substring( 0, 3 ) );
	} /// <summary>
	/// 建立进行数据连接的socket
	/// </summary>
	/// <returns>数据连接socket</returns>
	private Socket CreateDataSocket()
	{
		SendCommand( "PASV" );
		if( iReplyCode != 227 )
		{
			throw new IOException( strReply.Substring( 4 ) );
		}
		int index1 = strReply.IndexOf( '(' );
		int index2 = strReply.IndexOf( ')' );
		string ipData =
		 strReply.Substring( index1 + 1, index2 - index1 - 1 );
		int[] parts = new int[6];
		int len = ipData.Length;
		int partCount = 0;
		string buf = "";
		for( int i = 0; i < len && partCount <= 6; i++ )
		{
			char ch = Char.Parse( ipData.Substring( i, 1 ) );
			if( Char.IsDigit( ch ) )
				buf += ch;
			else if( ch != ',' )
			{
				throw new IOException( "Malformed PASV strReply: " +
				 strReply );
			}
			if( ch == ',' || i + 1 == len )
			{
				try
				{
					parts[partCount++] = Int32.Parse( buf );
					buf = "";
				}
				catch( Exception )
				{
					throw new IOException( "Malformed PASV strReply: " +
					 strReply );
				}
			}
		}
		string ipAddress = parts[0] + "." + parts[1] + "." +
		 parts[2] + "." + parts[3];
		int port = ( parts[4] << 8 ) + parts[5];
		Socket s = new
		 Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp );
		IPEndPoint ep = new
		 IPEndPoint( IPAddress.Parse( ipAddress ), port );
		try
		{
			s.Connect( ep );
		}
		catch( Exception )
		{
			throw new IOException( "Can't connect to remote server" );
		}
		return s;
	}
	/// <summary>
	/// 关闭socket连接(用于登录以前)
	/// </summary>
	private void CloseSocketConnect()
	{
		if( socketControl != null )
		{
			socketControl.Close();
			socketControl = null;
		}
		bConnected = false;
	}

	/// <summary>
	/// 读取Socket返回的所有字符串
	/// </summary>
	/// <returns>包含应答码的字符串行</returns>
	private string ReadLine()
	{
		while( true )
		{
			int iBytes = socketControl.Receive( buffer, buffer.Length, 0 );
			strMsg += ASCII.GetString( buffer, 0, iBytes );
			if( iBytes < buffer.Length )
			{
				break;
			}
		}
		char[] seperator = { '\n' };
		string[] mess = strMsg.Split( seperator );
		if( strMsg.Length > 2 )
		{
			strMsg = mess[mess.Length - 2];
			//seperator[0]是10,换行符是由13和0组成的,分隔后10后面虽没有字符串,
			//但也会分配为空字符串给后面(也是最后一个)字符串数组,
			//所以最后一个mess是没用的空字符串
			//但为什么不直接取mess[0],因为只有最后一行字符串应答码与信息之间有空格
		}
		else
		{
			strMsg = mess[0];
		}
		if( !strMsg.Substring( 3, 1 ).Equals( " " ) )//返回字符串正确的是以应答码(如220开头,后面接一空格,再接问候字符串)
		{
			return ReadLine();
		}
		return strMsg;
	}
	/// <summary>
	/// 发送命令并获取应答码和最后一行应答字符串
	/// </summary>
	/// <param name="strCommand">命令</param>
	private void SendCommand( String strCommand )
	{
		//Byte[] cmdBytes =
		// Encoding.ASCII.GetBytes((strCommand + "\r\n").ToCharArray());
		byte[] cmdBytes = Encoding.GetEncoding( "gb2312" ).GetBytes( ( strCommand + "\r\n" ).ToCharArray() );
		socketControl.Send( cmdBytes, cmdBytes.Length, 0 );
		ReadReply();
	}
	#endregion

	#region 内部变量
	/// <summary>
	/// 服务器返回的应答信息(包含应答码)
	/// </summary>
	private string strMsg;
	/// <summary>
	/// 服务器返回的应答信息(包含应答码)
	/// </summary>
	private string strReply;
	/// <summary>
	/// 服务器返回的应答码
	/// </summary>
	private int iReplyCode;
	/// <summary>
	/// 进行控制连接的socket
	/// </summary>
	private Socket socketControl;
	/// <summary>
	/// 传输模式
	/// </summary>
	private TransferType trType;
	/// <summary>
	/// 接收和发送数据的缓冲区
	/// </summary>
	private static int BLOCK_SIZE = 512;
	Byte[] buffer = new Byte[BLOCK_SIZE];
	/// <summary>
	/// 编码方式
	/// </summary>
	Encoding ASCII = Encoding.ASCII;
	#endregion
}

完全跨域单点登录实现原理

单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一。SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

跨域单点登录分为以下两种:

1、跨子域单点登录。如 blog.a.com 和 news.a.com 这2个站点同属一个主域.a.com,实现跨子域单点登录很简单,可以利用cookie,设置Domain为".a.com'即可,这里就不再赘叙。

2、完成跨域单点登录。如 http://www.abc.com/ http://www.xyz.com/ 这2个站点之间实现共享一个身份验证系统,只需在一处地方登录,下面主要谈下这种方式的实现方法。

下面简单说说跨域单点登录实现原理:

当用户第一次访问web 应用系统1的时候,因为还没有登录,会被引导到认证中心进行登录;根据用户提供的登录信息,认证系统进行身份效验,如果通过效验,返回给用户一个认证的凭据;用户再访问别的web应用的时候就会将这个Token带上,作为自己认证的凭据,应用系统接受到请求之后会把Token送到认证中心进行效验,检查Token的合法性。如果通过效验,用户就可以在不用再次登录的情况下访问应用系统2和应用系统3了。所有应用系统共享一个身份认证系统。认证系统的主要功能是将用户的登录信息和用户信息库相比较,对用户进行登录认证;认证成功后,认证系统应该生成统一的认证标志,返还给用户。另外,认证系统还应该对Token进行效验,判断其有效性。 所有应用系统能够识别和提取Token信息要实现SSO的功能,让用户只登录一次,就必须让应用系统能够识别已经登录过的用户。应用系统应该能对Token进行识别和提取,通过与认证系统的通讯,能自动判断当前用户是否登录过,从而完成单点登录的功能。比如说,我现在有3个分站点和1个认证中心(总站)。当用户访问分站点的时候,分站点会发Token到验证中心进行验证。验证中心判断用户是否已经登录。如果未登录,则返回到验证中心登录入口进行登录,否之则返回Token验证到分站点,直接进入分站点。

C#读取Word的内容

下了一个电子书,里面居然全部都是word格式的文件,一点都不便于阅读,连个目录都不好翻,只好把它读出来,弄成html格式的。下面是读取word内容的代码,比较简单了。

using System;
using System.IO;
using System.Reflection;
using Word;   

//----------------------------------------------------------------------
static string WordReader( string path )
{
	string WordContent = "";

	Word.Application app = new ApplicationClass();

	object fileName = path;
	object optional = Missing.Value;
	object visible = true;
	if( File.Exists( fileName.ToString() ) )
	{
		Word.Document doc = app.Documents.Open(
		 ref fileName,
		 ref optional,
		 ref optional,
		 ref optional,
		 ref optional,
		 ref optional,
		 ref optional,
		 ref optional,
		 ref optional,
		 ref optional,
		 ref optional,
		 ref visible,
		 ref optional,
		 ref optional,
		 ref optional,
		 ref optional );

		WordContent = doc.Content.Text;

		object saveChanges = WdSaveOptions.wdDoNotSaveChanges;
		object originalFormat = Missing.Value;
		object routeDocument = Missing.Value;
		app.Quit( ref saveChanges, ref originalFormat, ref routeDocument );
	}
	else
	{
		return string.Empty;
	}

	return WordContent;

}

工程中引用“Microsoft Word 11.0 object library”的Microsoft COM组件。该组件提供的类和方法来读取Word文档

在WebBrowser中用SendMessage模拟鼠标点击

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace BrowserMouseClick
{
  public partial class Form1 : Form
  {
	  [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
	  static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

	  [DllImport("user32.dll", SetLastError = true)]
	  static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);

	  [DllImport("user32.dll", CharSet = CharSet.Auto)]
	  static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);

	  public Form1()
	  {
		  InitializeComponent();
	  }

	  private void Form1_Load(object sender, EventArgs e)
	  {
		  webBrowser1.Navigate("http://www.devpub.com");
	  }

	  private void btnMouseClick_Click(object sender, EventArgs e)
	  {
		  int x = 100; // X coordinate of the click
		  int y = 80; // Y coordinate of the click
		  IntPtr handle = webBrowser1.Handle;
		  StringBuilder className = new StringBuilder(100);
		  while (className.ToString() != "Internet Explorer_Server") // The class control for the browser
		  {
			  handle = GetWindow(handle, 5); // Get a handle to the child window
			  GetClassName(handle, className, className.Capacity);
		  }

		  IntPtr lParam = (IntPtr)((y << 16) | x); // The coordinates
		  IntPtr wParam = IntPtr.Zero; // Additional parameters for the click (e.g. Ctrl)
		  const uint downCode = 0x201; // Left click down code
		  const uint upCode = 0x202; // Left click up code
		  SendMessage(handle, downCode, wParam, lParam); // Mouse button down
		  SendMessage(handle, upCode, wParam, lParam); // Mouse button up
	  }
  }
}

想在WebBrowser控件里面模拟鼠标点击,在百度上找了半天,怎么也找不到,还是google强大,在一个国外网站上找到的,代码比较清楚了,不做说明。

用SendMessage在不同程序间发送消息

窗体1中的代码:

	/////////////////////////////////////////
	///file name: Note.cs
	///
	public class Note
	{
		//声明 API 函数
		[DllImport( "User32.dll", EntryPoint = "SendMessage" )]
		private static extern int SendMessage(
			  int hWnd,     // handle to destination window
			  int Msg,     // message
			  int wParam,   // first message parameter
			  int lParam   // second message parameter
		);
		[DllImport( "User32.dll", EntryPoint = "FindWindow" )]
		private static extern int FindWindow( string lpClassName, string lpWindowName );
		//定义消息常数
		public const int USER = 0x500;
		public const int TEST = USER + 1;

		//向窗体发送消息的函数
		private void SendMsgToMainForm( int MSG )
		{
			int WINDOW_HANDLER = FindWindow( null, @"Note Pad" );
			if( WINDOW_HANDLER == 0 )
			{
				throw new Exception( "Could not find Main window!" );
			}
			SendMessage( WINDOW_HANDLER, MSG, 100, 200 );
		}
	}

(全文 ...)

C#判断两个日期是否在同一周,某日期是本月的第几周

判断两个日期是否在同一周

/// <summary>
/// 判断两个日期是否在同一周
/// </summary>
/// <param name="dtmS">开始日期</param>
/// <param name="dtmE">结束日期</param>
/// <returns></returns>
private bool IsInSameWeek(DateTime dtmS, DateTime dtmE)
{
	TimeSpan ts=dtmE - dtmS;
	double dbl=ts.TotalDays;
	int intDow=Convert.ToInt32(dtmE.DayOfWeek);
	if(intDow==0)
		intDow=7;

	if(dbl>=7 || dbl>=intDow)
		return false;
	else
		return true;
}

(全文 ...)

使用ISAPI_Rewrite重写URL后取页面的访问地址

在IIS里面装了ISAPI_Rewrite后,重写URL后在程序里面用Request.RawUrl和Requst.Url取得的地址都是没有经过重写的URL,想要取得重写过的URL必须这么做:在重写的RewriteRule后面[]里面的参数必须带上U,Request.ServerVeriables["HTTP_X_REWRITE_URL"],即可取得页面的重写过的URL。

另附上在php中的取法:

IIS中

$_SERVER['HTTP_X_REWRITE_URL']

Apache使用:

$_SERVER['REDIRECT_QUERY_STRING']或$_SERVER['REDIRECT_URL']