<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>JIN Weijie</title>
	<atom:link href="http://www.jinweijie.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.jinweijie.com</link>
	<description>Maximizing Quality of Life, Being Earth Friendly.</description>
	<lastBuildDate>Mon, 05 Dec 2011 00:01:12 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Step by Step Setup Git Server on Windows with CopSSH + msysGit and Integrate Git with Visual Studio</title>
		<link>http://www.jinweijie.com/git/step-by-step-setup-git-server-on-windows-with-copssh-msysgit-and-integrate-git-with-visual-studio/</link>
		<comments>http://www.jinweijie.com/git/step-by-step-setup-git-server-on-windows-with-copssh-msysgit-and-integrate-git-with-visual-studio/#comments</comments>
		<pubDate>Sun, 04 Dec 2011 10:51:52 +0000</pubDate>
		<dc:creator>jinweijie</dc:creator>
				<category><![CDATA[git]]></category>

		<guid isPermaLink="false">http://www.jinweijie.com/git/step-by-step-setup-git-server-on-windows-with-copssh-msysgit-and-integrate-git-with-visual-studio/</guid>
		<description><![CDATA[First of all, let me clarify that Git doesn’t need to specify the side for client and server. Your workstation can be both the client and server. That means you can get code from other computer, you’re the client; while others can also get code from your computer, you’re the server. That’s why Git is [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>First of all, let me clarify that Git doesn’t need to specify the side for client and server. Your workstation can be both the client and server. That means you can get code from other computer, you’re the client; while others can also get code from your computer, you’re the server. That’s why Git is great.</p>
<p>In this post, the “Git server” means to make your computer available for others to pull/push code from/to.</p>
<p><strong><font color="#008000">The post is long because it’s step by step and with lots of screenshots. In fact, it just takes about 10 minutes to setup all.</font></strong></p>
<p><em>Note: CopSSH is not open source any more, please buy it if you want to use it.</em></p>
<h2>We need the following software:</h2>
<p>Software required to setup a Git server:    <br /><a href="http://www.itefix.no/i2/copssh" target="_blank">CopSSH</a> (install on the server side)     <br /><a href="http://code.google.com/p/msysgit/" target="_blank">msysgit</a> (install both on the server side and client side)     <br /><a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html" target="_blank">PuTTY</a> (install both on the server side and client side)</p>
<p>Software required to integrate with Visual Studio:    <br /><a href="http://code.google.com/p/gitextensions/" target="_blank">GitExtensions</a> (install both on the server side and client side)</p>
<h1>Setup steps</h1>
<h2>1. Install msysgit.</h2>
<p>a. When you installing the msysgit, please choose c:\Git as the installation directory, because the space in the directory name may cause issue in bash commands.<a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image.png" rel="lightbox">      <br /><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb.png" width="474" height="363" /></a></p>
<p>b. In the “Adjusting your PATH environment”, I recommend to select “Use Git Bash only”.<a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image1.png" rel="lightbox">      <br /><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb1.png" width="475" height="365" /></a>     <br />c. Other settings are default. After installation, you get the icon <a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image2.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb2.png" width="59" height="60" /></a> on your desktop. You can try it with git command, if you get the following screen, you’ve installed the msysgit successfully.     <br /><a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image3.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb3.png" width="406" height="385" /></a></p>
<p>d. Add <strong>C:\Git\bin</strong> and <strong>C:\Git\libexec\git-core</strong> to Path. <font color="#ff0000">This step is very important.</font>     <br /><a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image4.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb4.png" width="398" height="482" /></a></p>
<h2>2. Install CopSSH</h2>
<p>a. Just like the msysgit, we don’t install the CopSSH in program files folder to avoid some space issues. We install it to <strong>c:\ICW</strong><a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image5.png" rel="lightbox">      <br /><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb5.png" width="473" height="363" /></a></p>
<p>b. Just use the default account as CopSSH provides:<a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image6.png" rel="lightbox">      <br /><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb6.png" width="471" height="362" /></a></p>
<p>c. After installation, open <strong>COPSSH Control Panel</strong><a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image7.png" rel="lightbox">      <br /><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb7.png" width="370" height="114" /></a></p>
<p>d. Click <strong>Add</strong> button in <strong>Users</strong> tab     <br /><a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image8.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb8.png" width="403" height="340" /></a></p>
<p>e. Choose an existed user on your computer(You can create one in computer management). Here in my sample the user is <strong>jinweijie</strong><a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image9.png" rel="lightbox">      <br /><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb9.png" width="429" height="369" /></a></p>
<p>f. Allow all the access:    <br /><a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image10.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb10.png" width="429" height="310" /></a></p>
<p>g. After the user is activated, click the <strong>Keys…</strong> button in the <strong>Activated Users</strong> section:     <br /><a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image11.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb11.png" width="437" height="368" /></a></p>
<p>h. Click <strong>Add</strong>:     <br /><a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image12.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb12.png" width="438" height="367" /></a></p>
<p>i. Use default key settings:    <br /><a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image13.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb13.png" width="512" height="334" /></a></p>
<p>j. Enter the Passphrase and File name:    <br /><a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image14.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb14.png" width="520" height="340" /></a></p>
<p>k. The private key will be save to <strong>c:\ICW\home\jinweijie\ryan-vm-01_2048.ppk</strong><a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image15.png" rel="lightbox">      <br /><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb15.png" width="595" height="275" /></a></p>
<p><em>[test step]</em>Now we try to use the activated user to log on through SSH, open Git Bash, enter commands:     <br /><em>ssh </em><em>jinweijie@ryan-vm-01</em>     <br />enter “yes” to continue     <br /><a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image16.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb16.png" width="546" height="368" /></a></p>
<p><em>[test step]</em>After enter your passwords (the windows account’s password), then you try to run git as the ssh user, but it isn’t perform as you expected:     <br /><a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image17.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb17.png" width="545" height="365" /></a>     <br />That’s because CopSSH cannot find the git.exe on the server, so we need to tell CopSSH the git path.</p>
<h2>3. Config CopSSH with Git path.</h2>
<p>a. Open <strong>C:\ICW\etc\profile</strong> with your favorite editor, add <font color="#ff0000">:/cygdrive/c/git/bin:/cygdrive/c/git/libexec/git-core</font><font color="#000000"> (don’t forget the starting colon) to <strong>PATH</strong> ,&#160; the whole line will be:       <br /><em>export PATH=&quot;/bin:$syspath:$winpath:/cygdrive/c/git/bin:/cygdrive/c/git/libexec/git-core&quot;</em></font><font color="#000000">      <br />Then Save.</font>     <br /><a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image18.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb18.png" width="619" height="355" /></a></p>
<p>b. Restart the CopSSH by click twice the big button in CopSSH Control Panel:    <br /><a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image19.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb19.png" width="443" height="376" /></a></p>
<p>c. If we run <strong>Git Bash</strong> again, <em>ssh jinweijie@ryan-vm-01</em>, enter your password and run the<strong> git command</strong>, git should be found this time:     <br /><a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image20.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb20.png" width="508" height="515" /></a></p>
<h2>4. Configure private key on client</h2>
<p>a. Copy the private key(we generated in step <strong>1-k</strong>) from server to client.     <br /><a href="http://www.jinweijie.com/wp-content/uploads/2011/12/SNAGHTMLc1563.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="SNAGHTMLc1563" border="0" alt="SNAGHTMLc1563" src="http://www.jinweijie.com/wp-content/uploads/2011/12/SNAGHTMLc1563_thumb.png" width="610" height="342" /></a></p>
<p>b. On the <strong>client side</strong>, use <strong>puttygen.exe</strong> to load the key(if you set the password in 1-j, you need to enter the password while loading the key):     <br /><a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image21.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb21.png" width="541" height="421" /></a></p>
<p>c.&#160; Click “Save private key” to save a copy of private key for plink.exe to recognize.    <br /><a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image22.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb22.png" width="598" height="266" /></a></p>
<h2>5. Create repository, integrate with Visual Studio</h2>
<p>a. Install <strong>gitextensions</strong> on both server and client.     <br /><a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image23.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb23.png" width="462" height="357" /></a></p>
<p>b. Since we have already install the msysgit in step 1-a, we skip the “Install MsysGit”. But if you haven’t install msysgit on the client machine, you can check the checkbox and install it.    <br /><a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image24.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb24.png" width="442" height="343" /></a></p>
<p>c. Install to <strong>C:\GitExtensions\</strong>, Other settings are default.     <br /><a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image25.png" rel="lightbox"><strong><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb25.png" width="443" height="343" /></strong></a></p>
<p>d. <strong>On the server side</strong>, open Git Extensions, click “Create new repository”     <br /><a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image26.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb26.png" width="474" height="170" /></a>&#160;</p>
<p>e. Set the path to the project name<strong> under you CopSSH user’s home directory</strong>, select “<strong>Central repository, no working dir</strong>”(because we are the server),&#160; then “<strong>Initialize</strong>”:     <br /><a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image27.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb27.png" width="503" height="129" /></a></p>
<p>f. <strong>On the client side,</strong> open Git Extensions, click “Clone repository”:     <br /><a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image29.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb29.png" width="566" height="142" /></a></p>
<p>g. <strong>On the client side,</strong> the repository address should be <strong>ssh://jinweijie@ryan-vm-01/ICW/home/jinweijie/mydotnetproject</strong> Please be aware that, the repository should begin with c:\ on the server.     <br /><a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image30.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb30.png" width="571" height="226" /></a></p>
<p>h. <strong>On the client side,</strong> click “Load SSH Key” and load the key which was saved in step <strong>4-b</strong>:     <br /><a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image31.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb31.png" width="547" height="380" /></a></p>
<p>i. <strong>On the client side,</strong>&#160; enter the password if you set password to the key, then click <strong>Clone</strong>:     <br /><a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image32.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb32.png" width="539" height="405" /></a></p>
<p>j. <strong>On the client side,</strong> add ignore files:     <br /><a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image33.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb33.png" width="493" height="430" /></a></p>
<p>k. <strong>On the client side,</strong> open Visual Studio, create a project to mydotnetproject folder(which is the cloned repository), you may find the files are already under git source control:     <br /><a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image34.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb34.png" width="499" height="350" /></a></p>
<p>l. Click the “Commit” button on the menu bar, then click “Commit &amp; Push”:    <br /><a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image35.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb35.png" width="498" height="389" /></a></p>
<p>m. Push succeeded:    <br /><a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image36.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb36.png" width="501" height="364" /></a></p>
<p>n. <strong>On the server side</strong>, you can find the new pushed files:     <br /><a href="http://www.jinweijie.com/wp-content/uploads/2011/12/image37.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/12/image_thumb37.png" width="510" height="373" /></a></p>
<p><strong>That’s all, happy GITTING! <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://www.jinweijie.com/wp-content/uploads/2011/12/wlEmoticon-smile.png" /></strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jinweijie.com/git/step-by-step-setup-git-server-on-windows-with-copssh-msysgit-and-integrate-git-with-visual-studio/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Migrate/Move Albums of Picasa Desktop Application</title>
		<link>http://www.jinweijie.com/picasa/migrate-move-albums-of-picasa-desktop-application/</link>
		<comments>http://www.jinweijie.com/picasa/migrate-move-albums-of-picasa-desktop-application/#comments</comments>
		<pubDate>Fri, 07 Oct 2011 13:49:28 +0000</pubDate>
		<dc:creator>jinweijie</dc:creator>
				<category><![CDATA[picasa]]></category>
		<category><![CDATA[album]]></category>
		<category><![CDATA[migrate]]></category>

		<guid isPermaLink="false">http://www.jinweijie.com/picasa/migratemove-albums-of-picasa-desktop-application/</guid>
		<description><![CDATA[Scenario I have a new computer and I want to move the Picasa(It’s the desktop application, not online album) album from my old computer to the new computer. The photos are the same, but the root folder is different. In this case, the old location is on the desktop, and the new location will be [...]]]></description>
			<content:encoded><![CDATA[<p></p><h2>Scenario</h2>
<p>I have a new computer and I want to move the Picasa(It’s the desktop application, not online album) album from my old computer to the new computer. The photos are the same, but the root folder is different. In this case, the old location is on the <strong>desktop</strong>, and the new location will be <strong>c:\my_new_albums</strong> . The album name for demo is <strong>Test Album</strong>.</p>
<p>The album on the old computer looks like:</p>
<p><a href="http://www.jinweijie.com/wp-content/uploads/2011/10/1.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="1" border="0" alt="1" src="http://www.jinweijie.com/wp-content/uploads/2011/10/1_thumb.png" width="616" height="134" /></a></p>
<h2>Steps</h2>
<p>1. Menu <strong>Tools</strong> –&gt; <strong>Back Up Pictures…</strong></p>
<p><a href="http://www.jinweijie.com/wp-content/uploads/2011/10/21.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2" border="0" alt="2" src="http://www.jinweijie.com/wp-content/uploads/2011/10/2_thumb1.png" width="460" height="243" /></a></p>
<p>2. In the dialog, in the first section,&#160; click <strong>New Set</strong>. Then in the popup, give a name of your backup, then choose <strong>Disk-to-disk backup(for external and network drives)</strong>. Click <strong>Create</strong>.</p>
<p>In the second section, click <strong>Select None</strong>. This is important because we just want to move the structure of the album.</p>
<p>Click <strong>Burn</strong>.</p>
<p><a href="http://www.jinweijie.com/wp-content/uploads/2011/10/31.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="3" border="0" alt="3" src="http://www.jinweijie.com/wp-content/uploads/2011/10/3_thumb1.png" width="449" height="316" /></a></p>
<p>3. You can find your backup files under <strong>C:\Picasa Backup\</strong> . The album information is stored in C:\Picasa Backup\$Application Data\Google\Picasa2Albums\(hash code)\(hash code).pal . <strong>Open it using your favorite text editor</strong>.</p>
<p><a href="http://www.jinweijie.com/wp-content/uploads/2011/10/4.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="4" border="0" alt="4" src="http://www.jinweijie.com/wp-content/uploads/2011/10/4_thumb.png" width="617" height="322" /></a></p>
<p>4. Replace the old path(on the old computer) with new path(on the new computer). In my case, I replace the <strong>$Desktop</strong> with <strong>[C]\my_new_albums</strong> .</p>
<p><a href="http://www.jinweijie.com/wp-content/uploads/2011/10/51.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="5" border="0" alt="5" src="http://www.jinweijie.com/wp-content/uploads/2011/10/5_thumb1.png" width="448" height="359" /></a></p>
<p>5. Copy the <strong>Picasa Backup</strong> folder(which is exported in Step 2) to the new computer. And make sure your photos already <strong>exist in the new location</strong>.</p>
<p><a href="http://www.jinweijie.com/wp-content/uploads/2011/10/61.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="6" border="0" alt="6" src="http://www.jinweijie.com/wp-content/uploads/2011/10/6_thumb1.png" width="451" height="345" /></a></p>
<p>6. In the <strong>Picasa Backup</strong> folder, run the <strong>PicasaRestore.exe</strong>. Choose <strong>Original locations</strong>. Click <strong>Next</strong>.</p>
<p><a href="http://www.jinweijie.com/wp-content/uploads/2011/10/71.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="7" border="0" alt="7" src="http://www.jinweijie.com/wp-content/uploads/2011/10/7_thumb1.png" width="451" height="333" /></a></p>
<p>7. Click <strong>Restore</strong>.</p>
<p><a href="http://www.jinweijie.com/wp-content/uploads/2011/10/8.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="8" border="0" alt="8" src="http://www.jinweijie.com/wp-content/uploads/2011/10/8_thumb.png" width="449" height="347" /></a></p>
<p>8. You’ve done. Open your Picasa and check if the album restored. Make sure your photos already exist in Picasa.</p>
<p><a href="http://www.jinweijie.com/wp-content/uploads/2011/10/91.png" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="9" border="0" alt="9" src="http://www.jinweijie.com/wp-content/uploads/2011/10/9_thumb1.png" width="449" height="384" /></a></p>
<p>That’s it, hope it helps.<img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://www.jinweijie.com/wp-content/uploads/2011/10/wlEmoticon-smile.png" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jinweijie.com/picasa/migrate-move-albums-of-picasa-desktop-application/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Modify Nextgen Gallery to Extract Picasa&#8217;s Caption</title>
		<link>http://www.jinweijie.com/wordpress/modify-nextgen-gallery-to-extract-picasas-caption/</link>
		<comments>http://www.jinweijie.com/wordpress/modify-nextgen-gallery-to-extract-picasas-caption/#comments</comments>
		<pubDate>Tue, 04 Oct 2011 03:20:02 +0000</pubDate>
		<dc:creator>jinweijie</dc:creator>
				<category><![CDATA[wordpress]]></category>
		<category><![CDATA[nextgen]]></category>

		<guid isPermaLink="false">http://www.jinweijie.com/wordpress/modify-nextgen-gallery-to-extract-picasas-caption/</guid>
		<description><![CDATA[I use Picasa to manage my photos locally and Nextgen gallery(a wordpress plugin) as my online photo albums. And in Picasa, captions can be added to photo’s meta tags, like this: When upload to Nextgen gallery, I would like to have this caption to be added to the photo’s title and description. So I modified [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>I use Picasa to manage my photos locally and Nextgen gallery(a wordpress plugin) as my online photo albums.</p>
<p>And in Picasa, captions can be added to photo’s meta tags, like this:</p>
<p><a href="http://www.jinweijie.com/wp-content/uploads/2011/10/nextgen_gallery_pre.jpg" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="nextgen_gallery_pre" border="0" alt="nextgen_gallery_pre" src="http://www.jinweijie.com/wp-content/uploads/2011/10/nextgen_gallery_pre_thumb.jpg" width="598" height="390" /></a></p>
<p>When upload to Nextgen gallery, I would like to have this caption to be added to the photo’s title and description. So I modified the Nextgen gallery to support this.</p>
<p>The modifications in Nextgen gallery plugin:</p>
<h3>1. Modify admin/function.php:</h3>
<p>At line number 661, replace </p>
<pre class="brush: php;">$alttext = empty( $meta['title'] ) ? $image-&gt;alttext : $meta['title'];

// get the caption / description field
$description = empty( $meta['caption'] ) ? $image-&gt;description : $meta['caption'];</pre>
<p>with</p>
<pre class="brush: php;">if (!$alttext = $meta['title'])
    $alttext = ($meta['keywords'] . &quot; &quot; . $meta['camera']);

// get the caption / description field
if (!$description = $meta['caption'])
    $description = ($meta['exif_desc'] . &quot; &quot; . $meta['keywords'] );
else
    $description = ( $description . ' [EXIF :: ' . $meta['exif_desc'] . ']' );

if( trim($alttext) == &quot;&quot; || trim($alttext) == &quot;Exif_JPEG_PICTURE&quot; ){
    if( $meta['caption'] )
        $alttext = $meta['caption'];
    else
        $alttext = $description;
}</pre>
<p>At line 734, add:</p>
<pre class="brush: php;">$meta['exif_desc'] = ($pdata-&gt;get_META('camera') . &quot; :: &quot; . $pdata-&gt;get_META('focal_length') .  &quot; :: &quot; . $pdata-&gt;get_META('shutter_speed') . &quot; :: &quot; . $pdata-&gt;get_META('aperture') . &quot; :: ISO &quot; . $pdata-&gt;get_META('iso') . &quot; :: &quot; . $pdata-&gt;get_META('created_timestamp'));</pre>
<h3>2. Modify lib/meta.php:</h3>
<p>At line 237, replace:</p>
<pre class="brush: php;">if ($this-&gt;iptc_data[$key])
    $meta[$value] = trim(utf8_encode(implode(&quot;, &quot;, $this-&gt;iptc_data[$key])));</pre>
<p>with</p>
<pre class="brush: php;">if($this-&gt;iptc_data[$key] &amp;&amp; $key == &quot;2#120&quot;){
    $meta[$value] = mb_convert_encoding(implode(&quot;, &quot;, $this-&gt;iptc_data[$key]), 'UTF-8', 'gb2312');
}
else if($this-&gt;iptc_data[$key]){
    $meta[$value] = trim(utf8_encode(implode(&quot;, &quot;, $this-&gt;iptc_data[$key])));
}</pre>
<p>And the final result looks like:</p>
<p><a href="http://www.jinweijie.com/wp-content/uploads/2011/10/nextgen_gallery_result1.jpg" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="nextgen_gallery_result" border="0" alt="nextgen_gallery_result" src="http://www.jinweijie.com/wp-content/uploads/2011/10/nextgen_gallery_result_thumb1.jpg" width="620" height="488" /></a></p>
<p>You may download the modified package <strong><a href="http://www.jinweijie.com/download/nextgen-gallery_1.8.3_modified.zip" target="_blank">here</a></strong>. (in the package, there are also some modification in the UI, you may compare the package with the original one to see the difference.)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jinweijie.com/wordpress/modify-nextgen-gallery-to-extract-picasas-caption/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mask Mobile Number Using C#</title>
		<link>http://www.jinweijie.com/c/mask-mobile-number-using-c-4/</link>
		<comments>http://www.jinweijie.com/c/mask-mobile-number-using-c-4/#comments</comments>
		<pubDate>Fri, 30 Sep 2011 07:07:12 +0000</pubDate>
		<dc:creator>jinweijie</dc:creator>
				<category><![CDATA[c#]]></category>

		<guid isPermaLink="false">http://www.jinweijie.com/c/mask-mobile-number-using-c-4/</guid>
		<description><![CDATA[A small piece of code which mask any string with specific mask characters. // Mask the mobile. // Usage: MaskMobile(&#34;13456789876&#34;, 3, &#34;****&#34;) =&#62; &#34;134****9876&#34; public static string MaskMobile(string mobile, int startIndex, string mask) { if (string.IsNullOrEmpty(mobile)) return string.Empty; string result = mobile; int starLengh = mask.Length; if (mobile.Length &#62;= startIndex) { result = mobile.Insert(startIndex, mask); [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>A small piece of code which mask any string with specific mask characters.</p>
<p>
<pre class="brush: csharp;">// Mask the mobile.
// Usage: MaskMobile(&quot;13456789876&quot;, 3, &quot;****&quot;) =&gt; &quot;134****9876&quot;
public static string MaskMobile(string mobile, int startIndex, string mask)
{
    if (string.IsNullOrEmpty(mobile))
        return string.Empty;

    string result = mobile;
    int starLengh = mask.Length;

    if (mobile.Length &gt;= startIndex)
    {
        result = mobile.Insert(startIndex, mask);
        if (result.Length &gt;= (startIndex + starLengh * 2))
            result = result.Remove((startIndex + starLengh), starLengh);
        else
            result = result.Remove((startIndex + starLengh), result.Length - (startIndex + starLengh));

    }

    return result;
}</pre></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jinweijie.com/c/mask-mobile-number-using-c-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting Started with Selenium in CSharp</title>
		<link>http://www.jinweijie.com/c/getting-started-with-selenium-in-csharp/</link>
		<comments>http://www.jinweijie.com/c/getting-started-with-selenium-in-csharp/#comments</comments>
		<pubDate>Tue, 31 May 2011 06:51:27 +0000</pubDate>
		<dc:creator>jinweijie</dc:creator>
				<category><![CDATA[c#]]></category>
		<category><![CDATA[automation]]></category>
		<category><![CDATA[selenium]]></category>
		<category><![CDATA[test]]></category>

		<guid isPermaLink="false">http://www.jinweijie.com/c/getting-started-with-selenium-in-csharp/</guid>
		<description><![CDATA[Selenium is a suite of tools to automate web app testing across many platforms. You may download and use Selenium from http://seleniumhq.org/ In this post, I would like to introduce the basic usage of Selenium in .Net development. Create Selenium instance In Selenium 2.0, there is a concept named WebDriver which is used to interacting [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>Selenium is a suite of tools to automate web app testing across many platforms.</p>
<p>You may download and use Selenium from <a href="http://seleniumhq.org/">http://seleniumhq.org/</a></p>
<p>In this post, I would like to introduce the basic usage of Selenium in .Net development.</p>
<h2>Create Selenium instance</h2>
<p>In Selenium 2.0, there is a concept named <strong>WebDriver</strong> which is used to interacting with browsers. There are three build-in drivers in Selenium 2.0b3, FirefoxDriver, InternetExplorerDriver, ChromeDriver.</p>
<p>After adding Selenium reference to your project, you can use the Selenium WebDriver to control the browsers to do the automatic things. First, you need to create an instance of one of the drivers:</p>
<pre class="brush: csharp;">RemoteWebDriver driver;

public SeleniumDemo()
{
    driver = new InternetExplorerDriver();
}</pre>
<h2>Navigate web pages</h2>
<p>When you got your WebDriver instance, you can send commands to WebDriver to operate browsers, for example, let the web browser visit Google:</p>
<pre class="brush: csharp;">driver.Url = &quot;http://google.com/&quot;;
driver.Navigate();</pre>
<h2>Find elements in a web page</h2>
<p>After landing some page, you probably want to check when some specific elements are on the page. You have several ways to do so thanks to the nice APIs from Selenium. For example, you want to make sure a textbox with id “txtMyData” existing on the page. You can write:</p>
<pre class="brush: csharp;">IWebElement txtMyData = driver.FindElementById(&quot;txtMyData&quot;);</pre>
<p>Then you want to set the text of the textbox:</p>
<pre class="brush: csharp;">txtMyData.SendKeys( &quot;blar blar blar...&quot; );</pre>
<p>After that, you want to submit the form by clicking the submit button:</p>
<pre class="brush: csharp;">IWebElement btnSubmit = driver.FindElementById(&quot;btnSubmit&quot;);
btnSubmit.Click();</pre>
<p>The form should be submitted.</p>
<p>You can use other ways to find elements like by className, xpath, etc.</p>
<h2>Wait elements loaded in Selenium</h2>
<p>When you do the browser automation, one thing you need to be aware is that you cannot operate elements until they loaded in browser. So in Selenium, there is a way to wait for the element appearing in the page. </p>
<p>For example, in the previous sample, we want to make sure the submit button is loaded before submitting:</p>
<p>first, we need to create an <strong>WebDriverWait</strong> instance:</p>
<pre class="brush: csharp;">RemoteWebDriver driver;
WebDriverWait wait;

public SeleniumDemo()
{
    driver = new InternetExplorerDriver();
    //the wait will check the element intervally until the expire time.
    wait = new WebDriverWait( driver, new TimeSpan( 0, 0, 3 ) );
}</pre>
<p>Then we change the submitting code:</p>
<pre class="brush: csharp;">IWebElement btnSubmit = wait.Until( d =&gt; d.FindElement( By.Id( &quot;btnSubmit&quot; ) ) );
btnSubmit.Click();</pre>
<p>Another way to wait when executing:</p>
<pre class="brush: csharp;">Thread.Sleep(5000);//wait for 5 seconds</pre>
<h2>Summary</h2>
<p>This is just a brief introduction of Selenium. I think you may able to write some automation tests with these basic concepts. It’s a lot of fun playing with Selenium, just try it.<img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://www.jinweijie.com/wp-content/uploads/2011/05/wlEmoticon-smile.png" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jinweijie.com/c/getting-started-with-selenium-in-csharp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Copy files between servers in different(without) domains</title>
		<link>http://www.jinweijie.com/asp-net/copy-files-between-servers-in-differentwithout-domains/</link>
		<comments>http://www.jinweijie.com/asp-net/copy-files-between-servers-in-differentwithout-domains/#comments</comments>
		<pubDate>Fri, 15 Apr 2011 08:49:00 +0000</pubDate>
		<dc:creator>jinweijie</dc:creator>
				<category><![CDATA[asp.net]]></category>
		<category><![CDATA[copy_file]]></category>
		<category><![CDATA[different_domain]]></category>

		<guid isPermaLink="false">http://www.jinweijie.com/asp-net/copy-files-between-servers-in-differentwithout-domains/</guid>
		<description><![CDATA[It’s quite tough there days because of the file uploading failure on our live servers. The situation is that we have the Application Server and DB server(which also used as file server) in two different domains(in fact, both servers are not in domain). At first, we use the following code to save files to another [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>It’s quite tough there days because of the file uploading failure on our live servers. The situation is that we have the Application Server and DB server(which also used as file server) in two different domains(in fact, both servers are not in domain). </p>
<p>At first, we use the following code to save files to another server:</p>
<pre class="brush: csharp;">file.SaveAs(newFilePath);</pre>
<p>The code is ok if two servers are in same domain. But it fails in the situation describe above. We cannot change the environment, so we can just do an impersonation to logon the file server first, then copy the files, we updated the code:</p>
<p>The definition:</p>
<pre class="brush: csharp;">#region consts

const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
const int LOGON32_PROVIDER_DEFAULT = 0;

#endregion

#region Windowns API

[DllImport(&quot;advapi32.DLL&quot;, SetLastError = true)]
public static extern int LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

#endregion</pre>
<p>Copy file code:</p>
<pre class="brush: csharp;">//do the impersonation to save the file
IntPtr admin_token = default(IntPtr);
WindowsIdentity wid_current = WindowsIdentity.GetCurrent();
WindowsIdentity wid_admin = null;
WindowsImpersonationContext wic = null;
string domain = &quot;your_domain_or_target_server_name&quot;;
string userName = &quot;target_server_local_user_name&quot;;
string password = &quot;target_server_local_user_password&quot;;

try
{
    if (LogonUser(userName, domain, password, LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_DEFAULT, ref admin_token) != 0)
    {
        wid_admin = new WindowsIdentity(admin_token);
        wic = wid_admin.Impersonate();

        //write the file
        file.SaveAs(newFilePath);
    }
}
catch (System.Exception se)
{
    int ret = Marshal.GetLastWin32Error();
    throw;
}
finally
{
    if (wic != null)
    {
        wic.Undo();
    }
}</pre>
<p>Then it should work.<img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://www.jinweijie.com/wp-content/uploads/2011/04/wlEmoticon-smile1.png" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jinweijie.com/asp-net/copy-files-between-servers-in-differentwithout-domains/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaScript File Selection Simulation</title>
		<link>http://www.jinweijie.com/javascript/javascript-file-selection-simulation/</link>
		<comments>http://www.jinweijie.com/javascript/javascript-file-selection-simulation/#comments</comments>
		<pubDate>Tue, 12 Apr 2011 08:32:35 +0000</pubDate>
		<dc:creator>jinweijie</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[fileupload]]></category>

		<guid isPermaLink="false">http://www.jinweijie.com/javascript/javascript-file-selection-simulation/</guid>
		<description><![CDATA[Context The build-in file selection elements of browsers are ugly and cannot be customized easily. If developer need to change the appearance of the file selection element, it’s almost impossible because of some security issues. So I wrote this script to simulate the file input selection by javascript so that the end user can click [...]]]></description>
			<content:encoded><![CDATA[<p></p><h2>Context</h2>
<p>The build-in file selection elements of browsers are ugly and cannot be customized easily.    <br />If developer need to change the appearance of the file selection element, it’s almost impossible because of some security issues. So I wrote this script to simulate the file input selection by javascript so that the end user can click upon an image to open the dialog, and the image button can be customized to any of style.</p>
<h2>Compatiblity</h2>
<p>Tested in IE6, IE7, IE8, Firefox4, Chrome10.</p>
<h2>Use the script</h2>
<ol>
<li>Link the js file to your page.</li>
<pre class="brush: xml;">&lt;script type=&quot;text/javascript&quot; src=&quot;file_selection_simulation.js&quot;&gt;&lt;/script&gt;</pre>
<li>Create HTML elements.</li>
<pre class="brush: xml;">&lt;div style=&quot;position:relative;width:102px;height:29px;&quot;&gt;
    &lt;input id=&quot;file_trigger&quot; class=&quot;file-trigger&quot; type=&quot;button&quot; value=&quot;Select File...&quot; /&gt;
    &lt;div id=&quot;real_file_container&quot; class=&quot;file-container&quot;&gt;&lt;input id=&quot;real_file&quot; type=&quot;file&quot; class=&quot;real-file&quot;/&gt;&lt;/div&gt;
&lt;/div&gt;</pre>
<li>Add some style.</li>
<pre class="brush: css;">&lt;style type=&quot;text/css&quot;&gt;
    .file-container{
        width:18px;
        height:20px;
        overflow:hidden;
        position:absolute;
        filter:alpha(opacity=0);
        opacity: 0;
        top:0;
        left:0;
    }
    .real-file{
        margin-left:-150px;
    }

    /*the trigger normally should be customized*/
    .file-trigger{
        background-image:url(button.jpg);
        border:0;
        width:102px;
        height:29px;
        color:white;
    }
&lt;/style&gt;</pre>
<li>Initialize the fileSelectManager instance.</li>
</ol>
<pre class="brush: js;">&lt;script type=&quot;text/javascript&quot;&gt;
    var fManager = new _smt.fileSelectManager( 'file_trigger', 'real_file_container', 'real_file');
    fManager.init();
&lt;/script&gt;</pre>
<h2>Result</h2>
<p>The script will attach event handler function to the trigger and file container element. The effect is, when the end user move his mouse over the trigger, the file container will move to right under the mouse position. If the user click his mouse, he is clicking the file selection element actually.</p>
<p><a href="http://www.jinweijie.com/wp-content/uploads/2011/04/clip_image002.jpg" class="thickbox" rel="lightbox[344]"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="clip_image002" border="0" alt="clip_image002" src="http://www.jinweijie.com/wp-content/uploads/2011/04/clip_image002_thumb.jpg" width="141" height="63" /></a></p>
<p>Finally, the script will set the selected file name to the trigger:</p>
<p><a href="http://www.jinweijie.com/wp-content/uploads/2011/04/clip_image004.jpg" class="thickbox" rel="lightbox[344]"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="clip_image004" border="0" alt="clip_image004" src="http://www.jinweijie.com/wp-content/uploads/2011/04/clip_image004_thumb.jpg" width="125" height="56" /></a></p>
<h2>Demo Download</h2>
<p>Click <a href="http://www.jinweijie.com/download/file_selection_simulation.zip" target="_blank">here</a> to download the full working sample. <img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://www.jinweijie.com/wp-content/uploads/2011/04/wlEmoticon-smile.png" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jinweijie.com/javascript/javascript-file-selection-simulation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Object-Oriented Javascript borrow context for event handling</title>
		<link>http://www.jinweijie.com/javascript/object-oriented-javascript-borrow-context-for-event-handling/</link>
		<comments>http://www.jinweijie.com/javascript/object-oriented-javascript-borrow-context-for-event-handling/#comments</comments>
		<pubDate>Fri, 18 Mar 2011 08:27:33 +0000</pubDate>
		<dc:creator>jinweijie</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[contex]]></category>
		<category><![CDATA[event]]></category>
		<category><![CDATA[object-oriented]]></category>

		<guid isPermaLink="false">http://www.jinweijie.com/javascript/object-oriented-javascript-borrow-context-for-event-handling/</guid>
		<description><![CDATA[In object oriented Javascript programing, I used the following method to create “class”(in fact, there’s no class concept in Javascript): var MyObj = function(){ }; MyObj.prototype={ aaa : function(){ } , bbb : function(){ } , ccc : function(){ } }; Now I want to implement: Click an element in the page, call the aaa [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>In object oriented Javascript programing, I used the following method to create “class”(in fact, there’s no class concept in Javascript):</p>
<pre class="brush: js;">var MyObj = function(){
};

MyObj.prototype={
    aaa : function(){
    }
    ,
    bbb : function(){
    }
    ,
    ccc : function(){
    }
};</pre>
<p>Now I want to implement:</p>
<p>Click an element in the page, call the aaa method in MyObj instance, then in aaa method, call ccc method. Attach event to the element in bbb method.</p>
<p>So I can write like this:</p>
<pre class="brush: js;">&lt;div id=&quot;someA&quot;&gt;Click Me&lt;/div&gt;
&lt;script&gt;
var MyObj = function(){
};

MyObj.addEvent = function(oTarget, sEventType, fnHandler) {
    if (oTarget.addEventListener) {
        oTarget.addEventListener(sEventType, fnHandler, false);
    } else if (oTarget.attachEvent) {
        oTarget.attachEvent(&quot;on&quot; + sEventType, fnHandler);
    } else {
        oTarget[&quot;on&quot; + sEventType] = fnHandler;
    }
};

MyObj.prototype={
    aaa : function(event){
        alert(event);
        this.ccc();
    }
    ,
    bbb : function(){
        MyObj.addEvent( document.getElementById(&quot;someA&quot;), &quot;click&quot;, this.aaa );
    }
    ,
    ccc : function(){
        alert(&quot;in ccc;&quot;);
    }
};

var o = new MyObj();
o.bbb();

&lt;/script&gt;</pre>
<p>In aaa method, we get the event, but wait,<strong> this.ccc();</strong> raises error: <font color="#ff0000">this.ccc is not a function</font></p>
<p>What’s the problem? </p>
<p>Because, when the click event fires on the element, the aaa method is executed but the context/scope is not in the instance of MyObj, in another word, <strong>this</strong> is the div element.</p>
<p>The solution:</p>
<p>In this situation, we can use the <strong>call</strong> method of <strong>Function</strong> to borrow the context from the MyObj instance, so that the <strong>this.ccc()</strong> method is available in <strong>aaa </strong>method at execution time. First let’s see the definition of call method(from <a href="http://www.javascriptkit.com/jsref/function.shtml">http://www.javascriptkit.com/jsref/function.shtml</a>):</p>
<blockquote>
<p>Lets you call a function (funcA) as if it&#8217;s a method of another function (funcB). Specifically, the &quot;<code>this</code>&quot; keyword when used inside funcA now returns funcB. The two methods <code>apply()</code> and <code>call()</code> are useful when you wish an object to &quot;borrow&quot; a method from another object and use it within its own context.</p>
</blockquote>
<p>Then we write a help method:</p>
<pre class="brush: js;">MyObj.BindAsEventListener = function(object, fun) {
    return function(event) {
        return fun.call(object, (event || window.event));
    }
};</pre>
<p>At last, we modify the code to make it work:</p>
<pre class="brush: js;">&lt;div id=&quot;someA&quot;&gt;Click Me&lt;/div&gt;
&lt;script&gt;
var MyObj = function(){
    //borrow the context from MyObj instance to _aaa method
    //so that when _aaa is being executed, this keyword is combined to the instance of MyObj
    this._aaa = MyObj.BindAsEventListener( this, this.aaa );
};

//add event helper method
MyObj.addEvent = function(oTarget, sEventType, fnHandler) {
    if (oTarget.addEventListener) {
        oTarget.addEventListener(sEventType, fnHandler, false);
    } else if (oTarget.attachEvent) {
        oTarget.attachEvent(&quot;on&quot; + sEventType, fnHandler);
    } else {
        oTarget[&quot;on&quot; + sEventType] = fnHandler;
    }
};

//use call to borrow context
MyObj.BindAsEventListener = function(object, fun) {
    return function(event) {
        return fun.call(object, (event || window.event));
    }
};

//the MyObj &quot;class&quot;
MyObj.prototype={
    aaa : function(event){
        alert(event);
        this.ccc();
    }
    ,
    bbb : function(){
        MyObj.addEvent( document.getElementById(&quot;someA&quot;), &quot;click&quot;, this._aaa );
    }
    ,
    ccc : function(){
        alert(&quot;in ccc;&quot;);
    }
};

var o = new MyObj();
o.bbb();

&lt;/script&gt;</pre>
<p>Please refer the comments in the code, that’s it. <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://www.jinweijie.com/wp-content/uploads/2011/03/wlEmoticon-smile.png" /></p>
<p>You can also <a href="http://www.jinweijie.com/download/context_event.html" target="_blank">download a executable sample</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jinweijie.com/javascript/object-oriented-javascript-borrow-context-for-event-handling/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>新浪微博RSS生成器Ver 1.0 同步Twitter帐号</title>
		<link>http://www.jinweijie.com/asp-net/sina-micro-blog-rss-generator-sync-twitter/</link>
		<comments>http://www.jinweijie.com/asp-net/sina-micro-blog-rss-generator-sync-twitter/#comments</comments>
		<pubDate>Mon, 14 Mar 2011 03:38:21 +0000</pubDate>
		<dc:creator>jinweijie</dc:creator>
				<category><![CDATA[asp.net]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[internet]]></category>
		<category><![CDATA[Generator]]></category>
		<category><![CDATA[RSS]]></category>
		<category><![CDATA[Sina]]></category>
		<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://www.jinweijie.com/asp-net/sina-micro-blog-rss-generator-sync-twitter/</guid>
		<description><![CDATA[同时在用twitter和新浪微博，在twitter上主要看贴为主，在新浪微博上发帖比较多。于是就想到是否搞一下将新浪微博同步到twitter上。搜索了下，发现月光博客上提供了解决方案，不过稍有遗憾的是没有图片的同步。于是就自己用asp.net实现了下，用下来感觉还行，所以分享一下，同时提供源代码，如果有定制开发的朋友可以修改源码，但如果再发布时候，请注明出处，先谢谢了！ 下载 新浪微博RSS生成器Ver 1.0 发布包 新浪微博RSS生成器Ver 1.0 源代码 部署步骤 首先，需要一个.Net Framework 2.0以上的IIS环境。 将SinaFeed_Bin_ver_1.0.zip解压以后，部署成网站或者虚拟目录。 将包里面的db文件夹赋予network service以及aspnet用户可写权限，偷懒且安全的话，给everyone即可。 运行起来的话，应该会是个Authentication Error的错误，这是正常的，因为接下来要配置下。 同步原理 用FeedBurner绑定Twitter，在FeedBurner中配置Rss源到SinaFeed应用。当FeedBurner每次来ping的时候，SinaFeed抓取新浪微博的内容，检查是否已经抓取过，把结果保存在Access数据库中，返回Rss给FeedBurner。 实现功能 同步新浪微博到Twitter。 包含图片链接，可配置。 包含转发原文及作者。 配置 在Web.Config里，有以下几个可以配置的选项： 代理服务器相关，例如你的网站访问外网需要代理的话，请设置一下配置： UseProxy , ProxyAddress, ProxyPort, ProxyDomain, ProxyUserName, ProxyUserPassword AuthCodeConfig 配置在应用里的授权码，自己设定一个，例如abc，当外面请求RSS的时候，需要在Url传递一个AuthCode，要和所配置的（abc）一直，程序才会返回结果，否则报Authentication Error错误。 AllowedUserIds 允许被处理新浪微博Id，如何得到你的Id？只要点击“关注”，在Url里就会出现你的Id，例如，我的Id是：1650422717 。SinaFeed支持多个Id，用逗号(,) 分割。 RssChannelUrl 所生成的Rss的ChannelUrl RssBaseGuid 所生成的Rss的唯一标识 RssTitle 所生成的Rss的标题 RssDescription 所生成的Rss的描述 使用步骤 例如，你部署在www.example.com上，虚拟目录为SinaFeed，你的新浪Id为1650422717，AuthCodeConfig你配置了jinweijiesinafeed那么 访问http://www.example.com/SinaFeed/Default.aspx?SinaUserId=1650422717&#38;AuthCode=jinweijiesinafeed 就可以得到用户1650422717的Rss了。 另外的一些可传参数的配置： UseOriginalImage 是否使用原来的大图片，默认True，如果False的话，将会使用新浪微博的缩略图。 [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>同时在用twitter和新浪微博，在twitter上主要看贴为主，在新浪微博上发帖比较多。于是就想到是否搞一下将新浪微博同步到twitter上。搜索了下，发现<a href="http://www.williamlong.info/" target="_blank">月光博客</a>上提供了<a href="http://www.williamlong.info/archives/2080.html" target="_blank">解决方案</a>，不过稍有遗憾的是没有图片的同步。于是就自己用asp.net实现了下，用下来感觉还行，所以分享一下，同时提供源代码，如果有定制开发的朋友可以修改源码，但如果再发布时候，请注明出处，先谢谢了！</p>
<h2>下载</h2>
<p><a href="http://www.jinweijie.com/download/SinaFeed_Bin_ver_1.0.zip" target="_blank">新浪微博RSS生成器Ver 1.0 发布包</a></p>
<p><a href="http://www.jinweijie.com/download/SinaFeed_Src_ver_1.0.zip" target="_blank">新浪微博RSS生成器Ver 1.0 源代码</a></p>
<h2>部署步骤</h2>
<ol>
<li>首先，需要一个.Net Framework 2.0以上的IIS环境。 </li>
<li>将SinaFeed_Bin_ver_1.0.zip解压以后，部署成网站或者虚拟目录。 </li>
<li>将包里面的db文件夹赋予network service以及aspnet用户可写权限，偷懒且安全的话，给everyone即可。 </li>
<li>运行起来的话，应该会是个Authentication Error的错误，这是正常的，因为接下来要配置下。 </li>
</ol>
<h2>同步原理</h2>
<p>用FeedBurner绑定Twitter，在FeedBurner中配置Rss源到SinaFeed应用。当FeedBurner每次来ping的时候，SinaFeed抓取新浪微博的内容，检查是否已经抓取过，把结果保存在Access数据库中，返回Rss给FeedBurner。</p>
<h2>实现功能</h2>
<ul>
<li>同步新浪微博到Twitter。 </li>
<li>包含图片链接，可配置。 </li>
<li>包含转发原文及作者。 </li>
</ul>
<h2>配置</h2>
<p>在Web.Config里，有以下几个可以配置的选项：</p>
<p><strong>代理服务器相关</strong>，例如你的网站访问外网需要代理的话，请设置一下配置：     <br />UseProxy , ProxyAddress, ProxyPort, ProxyDomain, ProxyUserName, ProxyUserPassword</p>
<p><strong>AuthCodeConfig</strong> 配置在应用里的授权码，自己设定一个，例如abc，当外面请求RSS的时候，需要在Url传递一个AuthCode，要和所配置的（abc）一直，程序才会返回结果，否则报Authentication Error错误。</p>
<p><strong>AllowedUserIds</strong> 允许被处理新浪微博Id，如何得到你的Id？只要点击“关注”，在Url里就会出现你的Id，例如，我的Id是：1650422717 。SinaFeed支持多个Id，用逗号(,) 分割。</p>
<p><strong>RssChannelUrl</strong> 所生成的Rss的ChannelUrl</p>
<p><strong>RssBaseGuid</strong> 所生成的Rss的唯一标识</p>
<p><strong>RssTitle</strong> 所生成的Rss的标题</p>
<p><strong>RssDescription</strong> 所生成的Rss的描述</p>
<h2>使用步骤</h2>
<p>例如，你部署在<a href="http://www.example.com">www.example.com</a>上<u>，</u>虚拟目录为SinaFeed，你的新浪Id为1650422717，AuthCodeConfig你配置了jinweijiesinafeed那么</p>
<p>访问<a href="http://www.example.com/SinaFeed/Default.aspx?SinaUserId=1650422717&amp;AuthCode=jinweijiesinafeed">http://www.example.com/SinaFeed/Default.aspx?SinaUserId=1650422717&amp;AuthCode=jinweijiesinafeed</a></p>
<p>就可以得到用户1650422717的Rss了。</p>
<p>另外的一些可传参数的配置：</p>
<p><strong>UseOriginalImage</strong> 是否使用原来的大图片，默认True，如果False的话，将会使用新浪微博的缩略图。</p>
<p><strong>RssMaxItemCount</strong> 返回RSS Items的最大数量。</p>
<p><strong>AttachImageToEnclosure</strong> 是否将图片已Enclosure的方式发布到RSS</p>
<p><strong>AttachImageToTitle</strong> 是否将图片地址添加到RSS Item的Title后面。</p>
<p><strong>AttachImageToDescription</strong> 是否将图片地址添加到RSS Item的Description后面。</p>
<p><strong>AttachOriginalMblogToRT</strong> 如果是转发微博，是否添加原微博到。     </p>
<p>一般我的配置：</p>
<p><a href="http://www.example.com/SinaFeed/Default.aspx?SinaUserId=1650422717&amp;AuthCode=jinweijiesinafeed&amp;AttachImageToDescription=true">http://www.example.com/SinaFeed/Default.aspx?SinaUserId=1650422717&amp;AuthCode=jinweijiesinafeed&amp;AttachImageToDescription=true</a></p>
<h2>同步结果</h2>
<p><strong>新浪微博</strong>：</p>
<p><a class="thickbox" href="http://www.jinweijie.com/wp-content/uploads/2011/03/image.png" rel="lightbox[329]"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/03/image_thumb.png" width="373" height="649" /></a></p>
<p><strong>Twitter</strong>:</p>
<p><a class="thickbox" href="http://www.jinweijie.com/wp-content/uploads/2011/03/image1.png" rel="lightbox[329]"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/03/image_thumb1.png" width="398" height="484" /></a></p>
<h2>FeedBurner的配置</h2>
<p>有了RSS，然后我们就可以配置FeedBurner来绑定Twitter帐号了。</p>
<ol>
<li>首先，你需要一个FeedBurner的帐号，需要翻个墙，如何注册这里就不赘述了，大家应该各有神通吧。 </li>
<li>然后填入你的SinaFeed应用的地址：      <br /><a class="thickbox" href="http://www.jinweijie.com/wp-content/uploads/2011/03/image2.png" rel="lightbox[329]"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/03/image_thumb2.png" width="420" height="235" /></a> </li>
<li>在Publicize tab里的Socialize菜单绑定你的Twitter帐号，保存。      <br /><a class="thickbox" href="http://www.jinweijie.com/wp-content/uploads/2011/03/image3.png" rel="lightbox[329]"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.jinweijie.com/wp-content/uploads/2011/03/image_thumb3.png" width="426" height="356" /></a> </li>
<li>一般FeedBurner更新周期是30分钟，你也可以用它的ping功能，马上实现同步。 </li>
</ol>
<h2>我的新浪微博</h2>
<p>有任何问题可以加<a href="http://t.sina.com.cn/jinweijie" target="_blank">我的微博</a>进行讨论。我的新浪微博和twitter都是@jinweijie 。谢谢！</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jinweijie.com/asp-net/sina-micro-blog-rss-generator-sync-twitter/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Add UTF-8 Signature(BOM) at the Start of Response File</title>
		<link>http://www.jinweijie.com/asp-net/add-utf-8-signaturebom-at-the-start-of-response-file/</link>
		<comments>http://www.jinweijie.com/asp-net/add-utf-8-signaturebom-at-the-start-of-response-file/#comments</comments>
		<pubDate>Mon, 31 Jan 2011 02:50:55 +0000</pubDate>
		<dc:creator>jinweijie</dc:creator>
				<category><![CDATA[asp.net]]></category>
		<category><![CDATA[bom]]></category>
		<category><![CDATA[utf8]]></category>

		<guid isPermaLink="false">http://www.jinweijie.com/uncategorized/add-utf-8-signaturebom-at-the-start-of-response-file/</guid>
		<description><![CDATA[In ASP.Net, if you write a file to the client using code like this: HttpContext.Current.Response.Clear(); HttpContext.Current.Response.AddHeader( &#34;content-disposition&#34;, string.Format( &#34;attachment; filename={0}&#34;, fileName ) ); HttpContext.Current.Response.ContentType = &#34;application/ms-excel&#34;; using( StringWriter sw = new StringWriter() ) { using( HtmlTextWriter htw = new HtmlTextWriter( sw ) ) { // Create a form to contain the grid Table table = [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>In ASP.Net, if you write a file to the client using code like this:</p>
<pre class="brush: csharp;">HttpContext.Current.Response.Clear();
HttpContext.Current.Response.AddHeader( &quot;content-disposition&quot;, string.Format( &quot;attachment; filename={0}&quot;, fileName ) );
HttpContext.Current.Response.ContentType = &quot;application/ms-excel&quot;;

using( StringWriter sw = new StringWriter() )
{
    using( HtmlTextWriter htw = new HtmlTextWriter( sw ) )
    {
        //  Create a form to contain the grid
        Table table = new Table();

        //  render the table into the htmlwriter
        table.RenderControl( htw );

        //  render the htmlwriter into the response
        HttpContext.Current.Response.Write( sw.ToString() );

        HttpContext.Current.Response.End();

    }
}</pre>
<p>My situation is to render a table to a file named xxx.xls(Excel file) and send to the client. And the file contains Chinese or other languages, it may cause some error codes in the file. This could happen randomly, sometimes error codes sometimes not.</p>
<p>After trying, I found if you save the file to UTF-8 with Signature, the error codes gone.</p>
<p>Then I tried to add the BOM the file before sending to the client:</p>
<pre class="brush: csharp;">HttpContext.Current.Response.Clear();
HttpContext.Current.Response.AddHeader( &quot;content-disposition&quot;, string.Format( &quot;attachment; filename={0}&quot;, fileName ) );
HttpContext.Current.Response.ContentType = &quot;application/ms-excel;charset=UTF-8;&quot;;

//prepare a memory stream
MemoryStream ms = new MemoryStream();

using( StreamWriter sw = new StreamWriter( ms ) )
{
    using( HtmlTextWriter htw = new HtmlTextWriter( sw ) )
    {
        //  Create a form to contain the grid
        Table table = new Table();

        //process your table here

        //  render the table into the htmlwriter
        table.RenderControl( htw );

        //remember to flush
        htw.Flush();

        //add the BOM
        byte[] bBOM = new byte[] { 0xEF, 0xBB, 0xBF };
        byte[] bContent = ms.ToArray();
        byte[] bToWrite = new byte[bBOM.Length + bContent.Length];

        //combile the BOM and the content
        bBOM.CopyTo( bToWrite, 0 );
        bContent.CopyTo( bToWrite, bBOM.Length );

        //write to the client
        HttpContext.Current.Response.Write( Encoding.UTF8.GetString( bToWrite ) );
        HttpContext.Current.Response.Flush();
        HttpContext.Current.Response.End();

        ms.Dispose();
    }
}</pre>
<p>The file being rendered will be added the BOM at the beginning.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jinweijie.com/asp-net/add-utf-8-signaturebom-at-the-start-of-response-file/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

