<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>黑暗執行緒</title><link>http://blog.darkthread.net/blogs/darkthreadtw/default.aspx</link><description /><dc:language>zh-CHT</dc:language><generator>CommunityServer 2007.1 (Debug Build: 20917.1142)</generator><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/Darkthread" /><feedburner:info uri="darkthread" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><title>TIPS-使用遠端桌面連線讓Windows XP關機</title><link>http://feedproxy.google.com/~r/Darkthread/~3/ZL46HKqlCNE/post-2012-05-21-shutdown-via-rdp-on-xp.aspx</link><pubDate>Mon, 21 May 2012 09:44:00 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:9061</guid><dc:creator>Jeffrey</dc:creator><slash:comments>4</slash:comments><wfw:commentRss>http://blog.darkthread.net/blogs/darkthreadtw/rsscomments.aspx?PostID=9061</wfw:commentRss><comments>http://blog.darkthread.net/post-2012-05-21-shutdown-via-rdp-on-xp.aspx#comments</comments><description>&lt;span id="PostName"&gt;&lt;/span&gt;
&lt;p&gt;雖然Windows XP已經邁入&lt;a href="http://www.microsoft.com/taiwan/partner/xplifecycle/xplifecycle.htm"&gt;延伸支援&lt;/a&gt;期(只有安全性修補及付費支援)，並將於2014/4/8支援完全終止，但工作周遭仍有好些耆老主機裝載著XP勇健地活者，持續挑戰&amp;quot;作業系統人瑞&amp;quot;的地位。懷著敬老尊賢的心情，在此謹記XP使用技巧一則。&lt;/p&gt;
&lt;p&gt;使用遠端連線登入Windows XP時，即使是系統管理者，在開始選單裡也不會出現關機、重新開機等選項，只有[登出]與[中斷連線]兩種選擇:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/9057/original.aspx" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;網路上有些討論提到可以用shutdown指令替代，不過我找到&lt;strike&gt;&lt;font color="#c0c0c0"&gt;更快&lt;/font&gt;&lt;/strike&gt;的方法是利用Terminal Service Client的快速鍵&amp;quot;Ctrl-Alt-End”，模擬在Windows XP按下Ctrl-Alt-Del的效果，在Windows管理員裡，有個[關機]選單，裡面就有[關機]與[重新開機]選項囉~&lt;/p&gt;
&lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/9058/original.aspx" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#ff6600"&gt;[2012-05-22更新]&lt;/font&gt; 感謝網友Jason, MotoVB補充，經測試，按登入上方的&amp;quot;Windows 安全性&amp;quot;可以叫出Windows作業管理員；網友Mulder補充的Alt-F4則可以直接叫出以下畫面:&lt;/p&gt;
&lt;p&gt;&lt;img border="0" alt="" src="http://blog.darkthread.net/photos/darkthread/images/9068/original.aspx" width="337" height="288" /&gt;&lt;/p&gt;
&lt;p&gt;是最快最無敵的方法!! 謝謝大家的回饋。&lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=9061" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/9RmA7NQzx_SW74hXDQB-5_SJ2vk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9RmA7NQzx_SW74hXDQB-5_SJ2vk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/9RmA7NQzx_SW74hXDQB-5_SJ2vk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9RmA7NQzx_SW74hXDQB-5_SJ2vk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Darkthread/~4/ZL46HKqlCNE" height="1" width="1"/&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Tips/default.aspx">Tips</category><feedburner:origLink>http://blog.darkthread.net/post-2012-05-21-shutdown-via-rdp-on-xp.aspx</feedburner:origLink></item><item><title>IE9相容問題-childNodes行為改變</title><link>http://feedproxy.google.com/~r/Darkthread/~3/HH7wYwGB8q8/post-2012-05-18-ie9-compatibility-issue-of-childnodes.aspx</link><pubDate>Fri, 18 May 2012 13:16:09 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:9053</guid><dc:creator>Jeffrey</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://blog.darkthread.net/blogs/darkthreadtw/rsscomments.aspx?PostID=9053</wfw:commentRss><comments>http://blog.darkthread.net/post-2012-05-18-ie9-compatibility-issue-of-childnodes.aspx#comments</comments><description>&lt;span id="PostName"&gt;&lt;/span&gt;  &lt;p&gt;IE9算是微軟大幅向其他瀏覽器靠攏的改版，在網頁呈現上已做到幾乎與Chrome, Firefox, Safari一致，不過，這也意味著IE9跟IE8的行為有明顯差異。(&lt;a href="http://blog.darkthread.net/post-2011-03-16-ie9-rtw.aspx"&gt;補充&lt;/a&gt;)&lt;/p&gt;  &lt;p&gt;前幾天處理了一個IE8檢視正常網頁在IE9爆炸的案例，在此筆記:&lt;/p&gt;  &lt;p&gt;以下範例可重現問題。程式在網頁新增一個&amp;lt;table&amp;gt;，而在&amp;lt;td&amp;gt;間故意夾雜換行或空白，接著透過&amp;lt;tr&amp;gt; .childNodes找出第二個&amp;lt;td&amp;gt;並取出其中HTML內容的第一個字元。(理論可用jQuery處理，不推此種寫法，但原程式如此)&lt;/p&gt;  &lt;div class="BlogCodeBlock"&gt;   &lt;div class="csharpcode"&gt;     &lt;pre class="alt"&gt;$(&lt;span class="str"&gt;&amp;quot;&amp;lt;table id=&amp;#39;x&amp;#39;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;a01&amp;lt;/td&amp;gt;\n&amp;lt;td&amp;gt;b01&amp;lt;/td&amp;gt; &amp;lt;td&amp;gt;c01&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;quot;&lt;/span&gt;)&lt;/pre&gt;

    &lt;pre&gt;.appendTo(&lt;span class="str"&gt;&amp;quot;body&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre class="alt"&gt;$(&lt;span class="str"&gt;&amp;#39;#x tr&amp;#39;&lt;/span&gt;).each(&lt;span class="kwrd"&gt;function&lt;/span&gt;() {&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="kwrd"&gt;try&lt;/span&gt; {&lt;/pre&gt;

    &lt;pre class="alt"&gt;        alert(&lt;span class="kwrd"&gt;this&lt;/span&gt;.childNodes[1].innerHTML.substr(0, 1));&lt;/pre&gt;

    &lt;pre&gt;    } &lt;span class="kwrd"&gt;catch&lt;/span&gt; (er) {&lt;/pre&gt;

    &lt;pre class="alt"&gt;        alert(&lt;span class="str"&gt;&amp;quot;Error: &amp;quot;&lt;/span&gt; + er);&lt;/pre&gt;

    &lt;pre&gt;    }&lt;/pre&gt;

    &lt;pre class="alt"&gt;});&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;在IE8執行時，可以如預期取得”b”；但是到了IE9，卻會因為childNodes[1].innerHTML == undefined而發生以下錯誤: Error: TypeError: Unable to get value of the property &amp;#39;substr&amp;#39;: object is null or undefined&lt;/p&gt;

&lt;p&gt;經檢測發現這是IE9對childNodes定義不同造成，用以下範例突顯二者差異:&lt;/p&gt;

&lt;div class="BlogCodeBlock"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;$(&lt;span class="str"&gt;&amp;quot;&amp;lt;table id=&amp;#39;x&amp;#39;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;a01&amp;lt;/td&amp;gt;\n&amp;lt;td&amp;gt;b01&amp;lt;/td&amp;gt; &amp;lt;td&amp;gt;c01&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;quot;&lt;/span&gt;)&lt;/pre&gt;

    &lt;pre&gt;.appendTo(&lt;span class="str"&gt;&amp;quot;body&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre class="alt"&gt;$(&lt;span class="str"&gt;&amp;quot;#x tr&amp;quot;&lt;/span&gt;).each(&lt;span class="kwrd"&gt;function&lt;/span&gt;() {&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="kwrd"&gt;var&lt;/span&gt; nodes = &lt;span class="kwrd"&gt;this&lt;/span&gt;.childNodes;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;var&lt;/span&gt; h = [&lt;span class="str"&gt;&amp;quot;&amp;lt;ol&amp;gt;&amp;quot;&lt;/span&gt;];&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;var&lt;/span&gt; i = 0; i &amp;lt; nodes.length; i++) {&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;var&lt;/span&gt; node = nodes[i];&lt;/pre&gt;

    &lt;pre&gt;        h.push(&lt;span class="str"&gt;&amp;quot;&amp;lt;li&amp;gt;&amp;quot;&lt;/span&gt; + node.nodeName + &lt;span class="str"&gt;&amp;quot;:&amp;quot;&lt;/span&gt; + &lt;/pre&gt;

    &lt;pre class="alt"&gt;            (node.innerHTML || escape(node.data)) + &lt;span class="str"&gt;&amp;quot;&amp;lt;/li&amp;gt;&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre&gt;    }&lt;/pre&gt;

    &lt;pre class="alt"&gt;    h.push(&lt;span class="str"&gt;&amp;quot;&amp;lt;/ol&amp;gt;&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre&gt;    $(&lt;span class="str"&gt;&amp;quot;body&amp;quot;&lt;/span&gt;).append(h.join(&lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;));&lt;/pre&gt;

    &lt;pre class="alt"&gt;});&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;試著列舉&amp;lt;tr&amp;gt;的childNodes，在IE8只有三個&amp;lt;td&amp;gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;TD:a01 &lt;/li&gt;

  &lt;li&gt;TD:b01 &lt;/li&gt;

  &lt;li&gt;TD:c01 &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;但在IE9，&amp;lt;td&amp;gt;間的換行以及空白也被算成子節點之一，故共有五個子節點:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;TD:a01 &lt;/li&gt;

  &lt;li&gt;#text:%0A &lt;/li&gt;

  &lt;li&gt;TD:b01 &lt;/li&gt;

  &lt;li&gt;#text:%20 &lt;/li&gt;

  &lt;li&gt;TD:c01 &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;參考W3CSchool關於Node Types的&lt;a title="XML DOM - Node Types" href="http://www.w3schools.com/dom/dom_nodetype.asp"&gt;說明&lt;/a&gt;，除了&amp;lt;TD&amp;gt;Element Node外，Text甚至CDATASection也都算Node的一種，而在Firefox、Chrome中亦是依此邏輯運作。以此而論，先前程式碼可行，反而是因為IE8不合群所致。&lt;/p&gt;

&lt;p&gt;回到案例解決上，用$(this).find(“td:eq(1)”).html()取代原來寫法便能輕鬆解決此一跨瀏覽器問題，而在程式修正前，只能請使用者啟動相容檢視模式先避開此一相容議題。&lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=9053" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Jy3L9qCTViVzqsEOX3Jw2rzk44g/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Jy3L9qCTViVzqsEOX3Jw2rzk44g/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Jy3L9qCTViVzqsEOX3Jw2rzk44g/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Jy3L9qCTViVzqsEOX3Jw2rzk44g/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Darkthread/~4/HH7wYwGB8q8" height="1" width="1"/&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Javascript/default.aspx">Javascript</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/IE/default.aspx">IE</category><feedburner:origLink>http://blog.darkthread.net/post-2012-05-18-ie9-compatibility-issue-of-childnodes.aspx</feedburner:origLink></item><item><title>在Windows 2008主機啟用睡眠功能</title><link>http://feedproxy.google.com/~r/Darkthread/~3/38vLDRh2KFs/post-2012-05-17-enable-sleep-on-windows-2008.aspx</link><pubDate>Wed, 16 May 2012 22:05:55 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:9051</guid><dc:creator>Jeffrey</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://blog.darkthread.net/blogs/darkthreadtw/rsscomments.aspx?PostID=9051</wfw:commentRss><comments>http://blog.darkthread.net/post-2012-05-17-enable-sleep-on-windows-2008.aspx#comments</comments><description>&lt;span id="PostName"&gt;&lt;/span&gt; &lt;p&gt;工作機要告老還鄉，任務型態改變，不再需要24小時運轉。但問題來了，Windows 2008無法像Windows 7一樣召喚好用的Hybrid-Sleep功能，既省電又能快速甦醒，還不怕斷電遺失資料。&lt;/p&gt;  &lt;p&gt;Hybrid-Sleep的官方翻譯是&amp;quot;交互式睡眠&amp;quot;，我覺得翻成&amp;quot;混合式睡眠&amp;quot;或許更好，跟油電混合車的&amp;quot;混合&amp;quot;意思相近，以下是取自微軟網站的&lt;a href="http://windows.microsoft.com/zh-tw/windows7/Sleep-and-hibernation-frequently-asked-questions"&gt;說明&lt;/a&gt;: &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;「交互式睡眠」主要是針對桌上型電腦所設計的功能。交互式睡眠是睡眠與休眠的組合，它會將任何開啟的文件與程式儲存至記憶體與硬碟，然後再使電腦進入低電力狀態，這樣您就可以快速地繼續您的工作。如此一來，如果發生電源中斷，Windows 可以從硬碟還原您的工作。開啟交互式睡眠時，電腦自動進入睡眠會使電腦進入交互式睡眠。桌上型電腦的交互式睡眠通常預設為開啟。&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Windows 2008不能啟用睡眠是因為Hyper-V服務(可參見微軟KB的&lt;a href="http://support.microsoft.com/kb/920730/zh-tw#appliesto"&gt;適用項目&lt;/a&gt;，都強調Windows 2008 &lt;font color="#ff8000"&gt;without&lt;/font&gt; Hyper-V)，但Hyper-V服務預設一開機時自動啟動，且啟動後無法停止。故要解決這個問題，得將Hyper-V設為手動啟動，而Hyper-V核心服務無法透過GUI改變啟動方式，如果不想修改Registry，可使用以下指令: (注意! =跟demand間有一個空白，不可省略)&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;sc config hvboot start= demand&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;設定完成後需重新開機，便可透過以下指令開啟休眠功能:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;powercfg /hibernate on&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;只是開啟休眠功能，開始選單(Start Menu)並未如Windows 7出現睡眠選項:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/9047/original.aspx" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;網路上有人說與顯示卡驅動程式有關，但我更換到最新版仍未解決，並未證實。最後我將主機的&amp;quot;電源按鈕&amp;quot;指定成睡眠，總算找到啟動睡眠的途徑:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/9046/original.aspx" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;網路上找到另外一個&lt;a href="http://answers.microsoft.com/en-us/windows/forum/windows_vista-desktop/desktop-shortcut-for-the-sleep-command/4e57f536-50a8-4942-a84a-290b3dea1ffb"&gt;解法&lt;/a&gt;是透過指令: &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;rundll32 powrprof.dll,SetSuspendState Standby&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;或許因為我的機器用powercfg -a檢測不支援S2 Standby模式，上述指令只會進入休眠(Hibernation)，並非睡眠。但很神奇地，指定電源按鈕就是可以切換為睡眠狀態，表示存在某種指令可以觸發真正的&amp;quot;睡眠&amp;quot;，就留待未來再研究，現在用電源鈕操作已經很OK。&lt;/p&gt;  &lt;p&gt;最後補充: 由於停用了hyboot服務，要啟用Hyper-V VM前要記得透過&amp;quot;sc start hvboot&amp;quot;先啟動服務，VM方能正常執行。而一旦hvboot啟動無法手動中止，就只能透過重新開機恢復未啟動狀態，才能再使用睡眠功能，步驟麻煩一些，應用時要留意。&lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=9051" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/AkOoyrGGbExf5lOzB3jVmpDL1PA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/AkOoyrGGbExf5lOzB3jVmpDL1PA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/AkOoyrGGbExf5lOzB3jVmpDL1PA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/AkOoyrGGbExf5lOzB3jVmpDL1PA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Darkthread/~4/38vLDRh2KFs" height="1" width="1"/&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Tips/default.aspx">Tips</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Windows+2008/default.aspx">Windows 2008</category><feedburner:origLink>http://blog.darkthread.net/post-2012-05-17-enable-sleep-on-windows-2008.aspx</feedburner:origLink></item><item><title>【茶包射手日記】移除Hyper-V VHD搬家後產生的隱藏網卡</title><link>http://feedproxy.google.com/~r/Darkthread/~3/q9FVRfZpk80/post-2012-05-16-remove-hidden-nic.aspx</link><pubDate>Tue, 15 May 2012 21:42:07 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:9045</guid><dc:creator>Jeffrey</dc:creator><slash:comments>2</slash:comments><wfw:commentRss>http://blog.darkthread.net/blogs/darkthreadtw/rsscomments.aspx?PostID=9045</wfw:commentRss><comments>http://blog.darkthread.net/post-2012-05-16-remove-hidden-nic.aspx#comments</comments><description>&lt;span id="PostName"&gt;&lt;/span&gt;  &lt;p&gt;新安裝好Windows 2008 R2，使用先前在其他Hyper-V環境安裝好Winows的VHD磁碟檔當作新建虛擬機器的磁碟來源。一切順利，直到設定固定IP時出現以下錯誤訊息:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font color="#ff8040"&gt;The IP address 192.168.1.100 you have entered for this network adapter is already assigned to another adapter (Microsoft Virutal Machine Bus Network #3) which is no longer present in the computer.&amp;#160; If the same address is assigned to both adapters and they both become active, only one of them will use this address,&amp;#160; This may result in incorrect system configuration.&amp;#160; Do you want to remove the static IP configuration for the absent adpater?&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font color="#ff8040"&gt;您為此網路介面卡輸入的 IP 位址 192.168.1.100 已指派給另一個介面卡 (Microsoft Virutal Machine Bus Network #3) (已不存在於電腦中)。如果為兩個介面卡指派相同的位址，且兩個介面卡都在使用中，則只有其中一個介面卡會使用這個位址。這可能會造成系統設定錯誤。您要移除已不存在的介面卡之靜態 IP 組態嗎?&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;新建VM明明只設定了一張網卡，而從Guest OS的裝置管理員上也只看到一張網卡。推測是VHD中殘留先前被安裝在其他Hyper-V環境時留下的舊網卡設定，新建VM時加入的網卡被視為另一塊新的網卡(MAC Address不同)，而舊網卡在新環境中沒有對應的VM硬體，故被視為裝置不存在，裝置管理員也看不到，但其IP設定值仍被保留(以便裝置插回去時可繼續沿用)，產生了以上警告，雖然上述訊息提供自動將舊網卡IP設定移除的選項，但知道VM上有多餘的無用裝置沒移除，總有種吃完飯臉上卻黏著飯粒的違和感。&lt;/p&gt;  &lt;p&gt;爬文後找到移除隱藏網卡的方法，說明如下:&lt;/p&gt;  &lt;p&gt;先開啟命名列視窗，輸入set devmgr_show_nonpresent_devices=1。這個參數會開放裝置管理員顯示不存在的裝置。&lt;/p&gt;  &lt;p&gt;接著輸入devmgmt.msc開啟裝置管理員，在View選單有個Show hidden devices選項:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/9044/original.aspx" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;哇! 這個VM VHD歷經滄桑，數次被掛在不同VM，留下四張不存在的網卡，二話不說，在無用網卡上按右鍵選&amp;quot;Uninstall&amp;quot;就可以將它們移除囉~&lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=9045" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/89MIm74Z_ep7IXAifgsuZeqZ7TA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/89MIm74Z_ep7IXAifgsuZeqZ7TA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/89MIm74Z_ep7IXAifgsuZeqZ7TA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/89MIm74Z_ep7IXAifgsuZeqZ7TA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Darkthread/~4/q9FVRfZpk80" height="1" width="1"/&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Trouble-Shooting/default.aspx">Trouble-Shooting</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Windows+2008/default.aspx">Windows 2008</category><feedburner:origLink>http://blog.darkthread.net/post-2012-05-16-remove-hidden-nic.aspx</feedburner:origLink></item><item><title>比NPOI更討喜的Excel元件-EPPlus!</title><link>http://feedproxy.google.com/~r/Darkthread/~3/qp1N35Yux80/post-2012-05-12-epplus.aspx</link><pubDate>Sat, 12 May 2012 09:11:00 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:9036</guid><dc:creator>Jeffrey</dc:creator><slash:comments>10</slash:comments><wfw:commentRss>http://blog.darkthread.net/blogs/darkthreadtw/rsscomments.aspx?PostID=9036</wfw:commentRss><comments>http://blog.darkthread.net/post-2012-05-12-epplus.aspx#comments</comments><description>&lt;span id="PostName"&gt;&lt;/span&gt;  &lt;p&gt;前陣子發表 &lt;a href="http://blog.darkthread.net/post-2012-05-02-export-file-struc-as-excel.aspx#9029"&gt;【潛盾機】將檔案結構匯成Excel文件&lt;/a&gt;，從網友佑翔的留言(特此感謝)，認識了一顆被我錯過的l好元件 -- &lt;a title="EPPlus-Create advanced Excel 2007 spreadsheets on the server - Download- EPPlus 2.6.0.1" href="http://epplus.codeplex.com/"&gt;EPPlus&lt;/a&gt;!&lt;/p&gt;  &lt;p&gt;NPOI源於&lt;a href="http://poi.apache.org/"&gt;POI&lt;/a&gt;，在很多介面設計上，帶點Java的觀點與風格，雖然能實現各項Excel操作，但函數介面及呼叫步驟，總讓.NET老鳥感覺不順手，就像用筷子吃手扒雞一樣彆扭。例如: 要寫入文字到新的Cell，必須先CreateRow()，再CreateCell()，而不像在Excel VBA透過.Cells(rowIndex, colIndex)一次到位。&lt;/p&gt;  &lt;p&gt;&lt;a title="讀取 Excel 你還在用 NPOI 嗎-快來試試 LinqToExcel - demo小鋪" href="http://demo.tc/Post/639"&gt;LinqToExcel&lt;/a&gt;的出現為讀取Excel提供方便的額外選擇，能用熟悉的LINQ語法查詢Excel內容是件暢快的事，只可惜LinqToExcel只限於讀取，要產生Excel，還是得回歸NPOI。&lt;/p&gt;  &lt;p&gt;&lt;a title="EPPlus-Create advanced Excel 2007 spreadsheets on the server - Download- EPPlus 2.6.0.1" href="http://epplus.codeplex.com/"&gt;EPPlus&lt;/a&gt;是一個起始於2009年底的Open Source專案，目標鎖定在伺服器端產生&lt;a href="http://en.wikipedia.org/wiki/Microsoft_Office_XML_formats"&gt;Office Open XML&lt;/a&gt; Excel檔(Excel 2007/2010的xlsx，不包含Excel 2003 xls)，提供比NPOI更直覺、更簡便的API介面! 用.Cells[rowIndex, colIndex]就能直接存取欄位，甚至用.Cells[r1, c1, r2, c2]就能取得一段選取範圍，再一口氣改變它們的樣式；而要指定字型顏色時，使用Cells[…].Style.Font.Color.SetColor(Color.Red)就能搞定，不像NPOI需要CreateFont(), CreateCellStyle(), SetFont(), SetCellStyle()一長串操作。這才是.NET客心中理想的好元件呀~~ &lt;/p&gt;  &lt;p&gt;不過我不禁好奇，為何先前很少聽人提起，幾無知名度。私自揣摩，猜想可能與EPPlus只支援xlsx，無法相容於Excel 2003的xls格式，在需顧及不特定使用群時會有Excel版本門檻的考量。(雖然微軟提供免費的&lt;a href="http://www.microsoft.com/downloads/zh-tw/details.aspx?FamilyID=1cd6acf9-ce06-4e1c-8dcf-f33f669dbc3a"&gt;Excel檢視工具&lt;/a&gt;，但需要額外安裝仍會有部署面的考量) 另一方面，這個元件採用LGPL授權，代表如果要包含在產品中散佈，&lt;strike&gt;產品也必須Open Source&lt;/strike&gt;(非100%要Open Source，授權限制可參見下方newbie的留言)，也會造成一些軟體廠商採用上的疑慮。再者，微軟本身提供&lt;a href="http://www.microsoft.com/en-us/download/details.aspx?id=5124"&gt;Open XML SDK&lt;/a&gt;，已涵蓋Excel檔的操作，有些開發者已直接採用SDK，沒想到再花時間評估更便捷元件(呼應了我在前篇文章的&lt;a href="http://blog.darkthread.net/post-2012-05-05-greasemonkey-load-jquery.aspx"&gt;感嘆&lt;/a&gt;，有小錦囊後真的會讓人錯過其他更犀利的選擇)，也可能是原因之一。&lt;/p&gt;  &lt;p&gt;依我的看法，隨著時光飛逝，舊版Excel相容的重要性會逐年下降，而應用於網站時，只要不是販售網站程式本體，倒不必擔憂LGPL的限制(可參照先前的&lt;a href="http://blog.darkthread.net/post-2011-06-05-telerik-ext-for-asp-net-mvc.aspx#7908"&gt;討論&lt;/a&gt;)。至於與Open XML SDK相比，初看語法，EPPlus確實如網友所說，具有&amp;quot;只見新人笑，不見舊人哭&amp;quot;的魅力! 真的可以跟NPOI說Bye Bye囉，在直覺易用上也已把Open XML SDK比下去。總評之後，EPPlus應是可以安心採用的解決方案。&lt;/p&gt;  &lt;p&gt;好東西當然要也要實測體驗一下威力，就同樣用上回的檔案結構匯出Excel案例吧! 這回改用EPPlus來處理寫成Excel的部分。&lt;/p&gt;  &lt;p&gt;要在專案中引用EPPlus，最快的方法一樣是透過NuGet: (還不會用NuGet的人，有沒有覺得自己已經輸在起跑點上?)&lt;/p&gt;  &lt;p&gt;&lt;img class="PopBoxImageSmall" src="http://blog.darkthread.net/photos/darkthread/images/9034/640x480.aspx" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;參考Zeeshan Umar的&lt;a href="http://zeeshanumardotnet.blogspot.com/2010/08/creating-advanced-excel-2007-reports-on.html"&gt;文章&lt;/a&gt;，三兩下就改好程式: &lt;/p&gt;  &lt;div class="BlogCodeBlock"&gt;   &lt;div class="csharpcode"&gt;     &lt;pre class="alt"&gt;    &lt;span class="rem"&gt;//加入擴充方法: SetQuickStyle，指定前景色/背景色/水平對齊&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; SetQuickStyle(&lt;span class="kwrd"&gt;this&lt;/span&gt; ExcelRange range,&lt;/pre&gt;

    &lt;pre class="alt"&gt;        Color foreColor,&lt;/pre&gt;

    &lt;pre&gt;        Color bgColor = &lt;span class="kwrd"&gt;default&lt;/span&gt;(Color),&lt;/pre&gt;

    &lt;pre class="alt"&gt;        ExcelHorizontalAlignment hAlign = ExcelHorizontalAlignment.Left)&lt;/pre&gt;

    &lt;pre&gt;    {&lt;/pre&gt;

    &lt;pre class="alt"&gt;        range.Style.Font.Color.SetColor(foreColor);&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (bgColor != &lt;span class="kwrd"&gt;default&lt;/span&gt;(Color))&lt;/pre&gt;

    &lt;pre class="alt"&gt;        {&lt;/pre&gt;

    &lt;pre&gt;            range.Style.Fill.PatternType = ExcelFillStyle.Solid;&lt;/pre&gt;

    &lt;pre class="alt"&gt;            range.Style.Fill.BackgroundColor.SetColor(bgColor);&lt;/pre&gt;

    &lt;pre&gt;        }&lt;/pre&gt;

    &lt;pre class="alt"&gt;        range.Style.HorizontalAlignment = hAlign;&lt;/pre&gt;

    &lt;pre&gt;    }&lt;/pre&gt;

    &lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="rem"&gt;/// 將目錄下的目錄檔案結構匯出成Excel工作表&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="rem"&gt;/// &amp;lt;param name=&amp;quot;dirPath&amp;quot;&amp;gt;要匯出的目錄路徑&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="rem"&gt;/// &amp;lt;param name=&amp;quot;excelPath&amp;quot;&amp;gt;匯出Excel路徑&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="rem"&gt;/// &amp;lt;param name=&amp;quot;filter&amp;quot;&amp;gt;過濾函數，傳入Path進行判斷，傳回true時表排除&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="rem"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; WebTreeToExcel(&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="kwrd"&gt;string&lt;/span&gt; dirPath, &lt;span class="kwrd"&gt;string&lt;/span&gt; excelPath,&lt;/pre&gt;

    &lt;pre class="alt"&gt;        Func&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;bool&lt;/span&gt;&amp;gt; filter = &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;/pre&gt;

    &lt;pre&gt;    {&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="rem"&gt;//將目錄結構整理成清單&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;        List&amp;lt;WebItem&amp;gt; list = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;WebItem&amp;gt;();&lt;/pre&gt;

    &lt;pre class="alt"&gt;        explore(list, dirPath, 0);&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="rem"&gt;//建立Excel&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;using&lt;/span&gt; (ExcelPackage p = &lt;span class="kwrd"&gt;new&lt;/span&gt; ExcelPackage())&lt;/pre&gt;

    &lt;pre&gt;        {&lt;/pre&gt;

    &lt;pre class="alt"&gt;            ExcelWorksheet sheet = p.Workbook.Worksheets.Add(&lt;span class="str"&gt;&amp;quot;Site Tree&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre&gt;            &lt;span class="kwrd"&gt;int&lt;/span&gt; colIdx = 1;&lt;/pre&gt;

    &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt; colName &lt;span class="kwrd"&gt;in&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;Path;File;Description&amp;quot;&lt;/span&gt;.Split(&lt;span class="str"&gt;&amp;#39;;&amp;#39;&lt;/span&gt;))&lt;/pre&gt;

    &lt;pre&gt;            {&lt;/pre&gt;

    &lt;pre class="alt"&gt;                sheet.Cells[1, colIdx++].Value = colName;&lt;/pre&gt;

    &lt;pre&gt;            }&lt;/pre&gt;

    &lt;pre class="alt"&gt;            &lt;span class="rem"&gt;//修改標題列Style&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;            sheet.Cells[1, 1, 1, 3].SetQuickStyle(Color.Yellow, Color.Green,&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    ExcelHorizontalAlignment.Center);&lt;/pre&gt;

    &lt;pre&gt;&amp;nbsp;&lt;/pre&gt;

    &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;int&lt;/span&gt; rowIdx = 2;&lt;/pre&gt;

    &lt;pre&gt;            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var item &lt;span class="kwrd"&gt;in&lt;/span&gt; list)&lt;/pre&gt;

    &lt;pre class="alt"&gt;            {&lt;/pre&gt;

    &lt;pre&gt;                &lt;span class="rem"&gt;//若bypass檢測傳回true，則略過該筆&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;if&lt;/span&gt; (filter != &lt;span class="kwrd"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; filter(item.Path))&lt;/pre&gt;

    &lt;pre&gt;                    &lt;span class="kwrd"&gt;continue&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre class="alt"&gt;                &lt;span class="rem"&gt;//將Path放在第一欄(稍後隱藏)&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;                sheet.Cells[rowIdx, 1].Value = item.Path;&lt;/pre&gt;

    &lt;pre class="alt"&gt;                &lt;span class="rem"&gt;//存入檔名或目錄名&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;                sheet.Cells[rowIdx, 2].Value = &lt;/pre&gt;

    &lt;pre class="alt"&gt;                    &lt;span class="kwrd"&gt;new&lt;/span&gt; String(&lt;span class="str"&gt;&amp;#39; &amp;#39;&lt;/span&gt;, item.Layer * 4) + item.Name;&lt;/pre&gt;

    &lt;pre&gt;                &lt;span class="kwrd"&gt;if&lt;/span&gt; (item.IsFolder)&lt;/pre&gt;

    &lt;pre class="alt"&gt;                {&lt;/pre&gt;

    &lt;pre&gt;                    sheet.Cells[rowIdx, 2].SetQuickStyle(Color.Blue);&lt;/pre&gt;

    &lt;pre class="alt"&gt;                }&lt;/pre&gt;

    &lt;pre&gt;                rowIdx++;&lt;/pre&gt;

    &lt;pre class="alt"&gt;            }&lt;/pre&gt;

    &lt;pre&gt;            &lt;span class="rem"&gt;//第一欄隱藏&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;            sheet.Column(1).Hidden = &lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre&gt;            &lt;span class="rem"&gt;//自動伸縮欄寬&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;            sheet.Column(2).AutoFit();&lt;/pre&gt;

    &lt;pre&gt;          sheet.Column(2).Width += 2;&lt;/pre&gt;

    &lt;pre class="alt"&gt;          sheet.Column(3).Width = 50;&lt;/pre&gt;

    &lt;pre&gt;            &lt;span class="rem"&gt;//寫入檔案&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;            p.SaveAs(&lt;span class="kwrd"&gt;new&lt;/span&gt; FileInfo(excelPath));&lt;/pre&gt;

    &lt;pre&gt;        }&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;一模一樣的結果，跟上回的NPOI寫法相比，是不是清爽順眼很多呢? 在以xlsx為主的網站應用場合，大家就大膽用下去吧!&lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=9036" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/NdTx7NuPCH2hgM_z3XCKg96cqlw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/NdTx7NuPCH2hgM_z3XCKg96cqlw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/NdTx7NuPCH2hgM_z3XCKg96cqlw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/NdTx7NuPCH2hgM_z3XCKg96cqlw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Darkthread/~4/qp1N35Yux80" height="1" width="1"/&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/.NET/default.aspx">.NET</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/CODE/default.aspx">CODE</category><feedburner:origLink>http://blog.darkthread.net/post-2012-05-12-epplus.aspx</feedburner:origLink></item><item><title>knockout.js!!</title><link>http://feedproxy.google.com/~r/Darkthread/~3/TnjjuSqukJY/post-2012-05-09-knockout-js-intro.aspx</link><pubDate>Tue, 08 May 2012 23:00:05 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:9027</guid><dc:creator>Jeffrey</dc:creator><slash:comments>2</slash:comments><wfw:commentRss>http://blog.darkthread.net/blogs/darkthreadtw/rsscomments.aspx?PostID=9027</wfw:commentRss><comments>http://blog.darkthread.net/post-2012-05-09-knockout-js-intro.aspx#comments</comments><description>&lt;span id="PostName"&gt;&lt;/span&gt;  &lt;p&gt;如果說jQuery是林志玲，那麼knockout.js可比陳妍希，同樣讓人一見傾心!! 這就是我初見knockout.js的感想。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://knockoutjs.com/"&gt;knockout.js&lt;/a&gt;是一套JavaScript UI程式庫，主要用來在網頁實現&lt;a href="http://msdn.microsoft.com/en-us/magazine/dd419663.aspx"&gt;MVVM設計模式&lt;/a&gt;。MVVM已在微軟WPF/Silverlight/WP7中廣泛應用(延伸閱讀: InfoQ的&lt;a href="http://www.infoq.com/cn/news/2011/12/mvvm-frameworks-net"&gt;簡要介紹&lt;/a&gt;、微軟的&lt;a href="http://msdn.microsoft.com/en-us/magazine/dd419663.aspx"&gt;MVVM導論&lt;/a&gt;、&lt;a href="http://blog.sanc.idv.tw/"&gt;天空的垃圾場&lt;/a&gt;則有幾篇&lt;a href="http://blog.sanc.idv.tw/p/wpf-silverlight-wpf-silverlight-wpf.html"&gt;WPF MVVM入門範例&lt;/a&gt;)，用白話來說: &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;在MVVM裡，UI操作涉及的資料被包成ViewModel類別，接著在UI輸入/顯示元素分別標註其對應到ViewModel某個屬性值。當程式碼改變ViewModel屬性值，其對應的輸入/顯示欄位元素便會自動更新；而在UI欄位填入不同內容，ViewModel的資料屬性也會立刻被修改為新值。&lt;/strong&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;這種雙向繫結(Two-Way Binding)的概念，若使用傳統做法得在ViewModel的屬性修改事件寫程式將新值反應到某個顯示/輸入元素上，還得攔截輸入元素的onChange事件，用程式將最新輸入結果反應到ViewMode屬性上，瑣碎的實做細節蠻多的。而不管是Silverlight/WPF或JavaScript，MVVM程式庫的目標即在節省前述自行開發的工夫，只需在顯示/輸入元素上註明其對應的ViewModel屬性，之後全部交給程式庫自動處理，讓程式開發者能優雅地實現MVVM。&lt;/p&gt;  &lt;p&gt;如今，MVVM概念也被搬到網頁開發上，未來大家在ASP.NET MVC的展示中應就會常看到它。在JavaScript領域，過去也有些MVVM程式庫被提出來，例如: 微軟主導的jQuery Data Link Plugin(不過，它跟&lt;a href="http://blog.darkthread.net/post-2010-12-05-jquery-templates-lab-1.aspx"&gt;jQuery Template Plugin&lt;/a&gt;一樣，已&lt;a href="http://www.borismoore.com/2011/10/jquery-templates-and-jsviews-roadmap.html"&gt;停止發展&lt;/a&gt;，未來會由jsView及jsRender接替，但預估要到2012年中才會進入Beta階段)，但顯然都比不上knockout.js所受到的關注與歡迎。&lt;/p&gt;  &lt;p&gt;knockout.js的主要特色為:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;宣告式語法: 透過DOM元素Attribute宣告完成資料繫結(Data Binding)，簡潔方便 &lt;/li&gt;    &lt;li&gt;自動UI更新: 只要Model資料改變，UI立即反映 &lt;/li&gt;    &lt;li&gt;相依性追蹤: 源頭資料變動時，可自動追溯所有關連的資料一起改變 &lt;/li&gt;    &lt;li&gt;支援範本(Template): 開放自訂Template決定Model資料輸出結果，可滿足各式客製需求 &lt;/li&gt;    &lt;li&gt;免費、Open Source &lt;/li&gt;    &lt;li&gt;純JavaScript - 可跟jQuery或其他JavaScript Framework併用無虞&lt;/li&gt;    &lt;li&gt;輕薄短小，Minified版本只有40KB，HTTP壓縮後只有14KB &lt;/li&gt;    &lt;li&gt;跨瀏覽器! 支援IE6+, FF2, Chrome, Opera, Safari(含行動裝置版本) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;要開始體驗knockout.js，建議可由官方網站上&lt;a title="learn.knockoutjs.com" href="http://learn.knockoutjs.com/"&gt;超神奇的Web互動教學&lt;/a&gt;入門:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/9025/640x480.aspx" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;教學網站如上所示，網站左上區塊為操作說明，右上為HTML標籤區，右下方為程式碼區，左下區塊則可立即測試結果。按照操作說明，一個步驟一個步驟在HTML區及程式碼區輸入適當的標籤及程式碼，就能立即體驗knockout.js的魔力。另外，官方網站也有極其詳盡的&lt;a title="Knockout - Introduction" href="http://knockoutjs.com/documentation/introduction.html"&gt;Knockout API說明&lt;/a&gt;，則是深入了解knockout.js的有效途徑。&lt;/p&gt;  &lt;p&gt;要在ASP.NET專案中體驗knockout.js，最簡單的方法是透過NuGet下載程式庫:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/9026/640x480.aspx" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;接著寫幾行程式，就能體驗MVVM的威力，如以下的範例:&lt;/p&gt;  &lt;div class="BlogCodeBlock"&gt;   &lt;div class="csharpcode"&gt;     &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;!&lt;/span&gt;&lt;span class="html"&gt;DOCTYPE&lt;/span&gt; &lt;span class="attr"&gt;html&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;html&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;head&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;title&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;knockout.js First Lab&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;title&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt; &lt;span class="attr"&gt;src&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;../Scripts/knockout-2.1.0.debug.js&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;&amp;lt;/head&amp;gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&amp;lt;body&amp;gt;&lt;/pre&gt;

    &lt;pre&gt;    &amp;lt;input type=&lt;span class="str"&gt;&amp;quot;text&amp;quot;&lt;/span&gt; id=&lt;span class="str"&gt;&amp;quot;txtValue&amp;quot;&lt;/span&gt; data-bind=&lt;span class="str"&gt;&amp;quot;value: myValue&amp;quot;&lt;/span&gt; /&amp;gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &amp;lt;span id=&lt;span class="str"&gt;&amp;quot;spnValue&amp;quot;&lt;/span&gt; data-bind=&lt;span class="str"&gt;&amp;quot;text: myValue&amp;quot;&lt;/span&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/pre&gt;

    &lt;pre&gt;    &amp;lt;script type=&lt;span class="str"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&amp;gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;var&lt;/span&gt; myViewModel =&lt;/pre&gt;

    &lt;pre&gt;        {&lt;/pre&gt;

    &lt;pre class="alt"&gt;            myValue: ko.observable(&lt;span class="str"&gt;&amp;quot;Darkthread&amp;quot;&lt;/span&gt;)&lt;/pre&gt;

    &lt;pre&gt;        }&lt;/pre&gt;

    &lt;pre class="alt"&gt;        ko.applyBindings(myViewModel);&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;body&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;html&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;在以上網頁，我宣告了一個&amp;lt;input&amp;gt;一個&amp;lt;span&amp;gt;，並定義了只有一個myValue屬性的超簡單ViewModel: myViewModel物件。透過data-bind=&amp;quot;value: myValue&amp;quot;將myValue屬性綁到&amp;lt;input&amp;gt;的value值，透過data-bind=&amp;quot;text: myValue&amp;quot;將屬性反映到&amp;lt;span&amp;gt;中，而myValue需透過ko.observable()宣告，knockout.js才能偵測到屬性值的變化，以便連動所有相關的UI元素。最後，要呼叫ko.applyBindings()將myViewModel繫結到網頁元素上，由於本例未引用jQuery，無$.ready()可用，所以把&amp;lt;script&amp;gt;放在網頁的最後端以確保ko.applyBindings()在網頁元素都載入後才執行。&lt;/p&gt;

&lt;p&gt;網頁運行後，&amp;lt;input&amp;gt;與&amp;lt;span&amp;gt;一開始會顯示Darkthread，試著改變&amp;lt;input&amp;gt;的值，可發現&amp;lt;span&amp;gt;會馬上反應修改後的結果。很酷吧!!&lt;/p&gt;

&lt;p&gt;我對ASP.NET MVC 4提到的SPA(&lt;a href="http://www.asp.net/single-page-application"&gt;Single Page Application&lt;/a&gt;)很有興趣，而knockout.js是其中重要的一環，將陸續分享一些學習心得。&lt;/p&gt;

&lt;p&gt;PS: SPA最簡單的比喻就是像GMail那種在同一個網頁中做完全部操作，不觸發任何PostBack的設計哲學。之前我在jQuery教學中也做過&lt;a href="http://msdn.microsoft.com/zh-tw/asp.net/dd722592.aspx"&gt;粗淺示範&lt;/a&gt;，但當時是純手工打造，未來在ASP.NET MVC架構下實現，已有許多現成配套，相關的3rd Party程式庫也更成熟，將會省力很多。&lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=9027" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/jqKsUP4FdCMjVDD42UzhsNsGsAU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/jqKsUP4FdCMjVDD42UzhsNsGsAU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/jqKsUP4FdCMjVDD42UzhsNsGsAU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/jqKsUP4FdCMjVDD42UzhsNsGsAU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Darkthread/~4/TnjjuSqukJY" height="1" width="1"/&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/knockoutjs/default.aspx">knockoutjs</category><feedburner:origLink>http://blog.darkthread.net/post-2012-05-09-knockout-js-intro.aspx</feedburner:origLink></item><item><title>測試ODAC 11.2.0.3 + EF4自動跳號</title><link>http://feedproxy.google.com/~r/Darkthread/~3/rkCp05VO1e0/post-2012-05-08-odac-with-oracle-sequence.aspx</link><pubDate>Mon, 07 May 2012 21:08:33 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:9021</guid><dc:creator>Jeffrey</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://blog.darkthread.net/blogs/darkthreadtw/rsscomments.aspx?PostID=9021</wfw:commentRss><comments>http://blog.darkthread.net/post-2012-05-08-odac-with-oracle-sequence.aspx#comments</comments><description>&lt;span id="PostName"&gt;&lt;/span&gt;  &lt;p&gt;剛好有網友&lt;a href="http://blog.darkthread.net/post-2012-04-18-oracle-ef-release.aspx#8988"&gt;提到&lt;/a&gt;ODAC 11.2.0.3 + EF4配合自動跳號的問題，之前曾用Devart EF元件實現過(且當時發現有SSDL無法自動更新的Bug)，現在有了ODAC EF，又有&lt;a href="http://www.oracle.com/technetwork/developer-tools/visual-studio/overview/index.html"&gt;Oracle Developer Tools for Visual Studio&lt;/a&gt;(ODT)加持，決定用新元件、新工具重新演練一次。&lt;/p&gt;  &lt;p&gt;用ODT建立資料表上回就已示範，這次略過操作步驟，直接建好一個具有ID DECIMAL(10, 0), MTEXT VARCHAR2(100)兩個欄位的資料表MEMO。要在Oracle實現自動跳號，需要Sequence物件，而ODT提供設計Sequence的圖形化編輯介面:   &lt;br /&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/8993/original.aspx" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;下一步是為MEMO建立Trigger，在每次INSERT時，將ID欄位設為Sequence取出的下一次跳號，這部分一樣可透過ODT完成:   &lt;br /&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/8994/original.aspx" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;接著在專案中新增edmx，加入MEMO資料表，記得設定ID欄位的StoreGeneratedPattern屬性為Identity，註明它一個自動跳號識別欄位。   &lt;br /&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/8995/original.aspx" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;寫一小段程式測試連續新增。在建立MEMO物件時，只需指定MTEXT的值，ID的部分不需設定，理論上會啟用自動跳號機制。&lt;/p&gt;  &lt;div class="BlogCodeBlock"&gt;   &lt;div class="csharpcode"&gt;     &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Linq;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Text;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; OracleEF&lt;/pre&gt;

    &lt;pre class="alt"&gt;{&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="kwrd"&gt;class&lt;/span&gt; Program&lt;/pre&gt;

    &lt;pre class="alt"&gt;    {&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args)&lt;/pre&gt;

    &lt;pre class="alt"&gt;        {&lt;/pre&gt;

    &lt;pre&gt;            &lt;span class="kwrd"&gt;using&lt;/span&gt; (MyEntities ctx = &lt;span class="kwrd"&gt;new&lt;/span&gt; MyEntities())&lt;/pre&gt;

    &lt;pre class="alt"&gt;            {&lt;/pre&gt;

    &lt;pre&gt;                MEMO m1 = &lt;span class="kwrd"&gt;new&lt;/span&gt; MEMO() { MTEXT = &lt;span class="str"&gt;&amp;quot;Memo A1&amp;quot;&lt;/span&gt; };&lt;/pre&gt;

    &lt;pre class="alt"&gt;                ctx.MEMO.AddObject(m1);&lt;/pre&gt;

    &lt;pre&gt;                ctx.SaveChanges();&lt;/pre&gt;

    &lt;pre class="alt"&gt;                MEMO m2 = &lt;span class="kwrd"&gt;new&lt;/span&gt; MEMO() { MTEXT = &lt;span class="str"&gt;&amp;quot;Memo A2&amp;quot;&lt;/span&gt; };&lt;/pre&gt;

    &lt;pre&gt;                ctx.MEMO.AddObject(m2);&lt;/pre&gt;

    &lt;pre class="alt"&gt;                ctx.SaveChanges();&lt;/pre&gt;

    &lt;pre&gt;                &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var m &lt;span class="kwrd"&gt;in&lt;/span&gt; ctx.MEMO)&lt;/pre&gt;

    &lt;pre class="alt"&gt;                {&lt;/pre&gt;

    &lt;pre&gt;                    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;{0}.{1}&amp;quot;&lt;/span&gt;, m.ID, m.MTEXT);&lt;/pre&gt;

    &lt;pre class="alt"&gt;                }&lt;/pre&gt;

    &lt;pre&gt;            }&lt;/pre&gt;

    &lt;pre class="alt"&gt;            Console.Read();&lt;/pre&gt;

    &lt;pre&gt;        }&lt;/pre&gt;

    &lt;pre class="alt"&gt;    }&lt;/pre&gt;

    &lt;pre&gt;}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;但程式在第二次ctx.SaveChanges()時爆出錯誤: &lt;font color="#f79646"&gt;ORA-00001: unique constraint (JEFF.PK_MEMO) violated&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;查詢資料表，發現出現一筆ID=0, MTEXT=&amp;quot;Memo A1&amp;quot;的資料，推測是自動跳號失效，該不會又是老問題: &lt;a title="【茶包射手日記】EF4 StoreGeneratedPattern設定無效 - 黑暗執行緒" href="http://blog.darkthread.net/post-2011-07-20-ef4-storegeneratedpattern-bug.aspx"&gt;EF4 StoreGeneratedPattern設定無效 &lt;/a&gt;重演吧? 那就用同樣的方法解決吧!&lt;/p&gt;

&lt;p&gt;在.edmx檔按右鍵選&amp;quot;Open With...&amp;quot;: 
  &lt;br /&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/8996/original.aspx" alt="" /&gt;&lt;/p&gt;

&lt;p&gt;使用XML (Text) Editor開啟.edmx檔:&lt;img src="http://blog.darkthread.net/photos/darkthread/images/8997/original.aspx" alt="" /&gt;&lt;/p&gt;

&lt;p&gt;果不其然，在CSDL段有annotation:StoreGenerationPattern=&amp;quot;Identity&amp;quot;(綠框處)，但SSDL裡原本沒有紅框中的StoreGenerationPattern，要自己補上:
  &lt;br /&gt;&lt;img class="PopBoxImageSmall" src="http://blog.darkthread.net/photos/darkthread/images/8998/640x480.aspx" alt="" /&gt;&lt;/p&gt;

&lt;p&gt;補上屬性後，重新執行程式，測試成功並順利新增兩筆資料。&lt;/p&gt;

&lt;p&gt;測試結果: ODAC 11.2.0.3 + EF4 可支援自動跳號Primary Key，但VS2010 SP1有&lt;a title="【茶包射手日記】EF4 StoreGeneratedPattern設定無效 - 黑暗執行緒" href="http://blog.darkthread.net/post-2011-07-20-ef4-storegeneratedpattern-bug.aspx"&gt;EF4 StoreGeneratedPattern設定無效 &lt;/a&gt;問題仍存在，故每次儲存edmx後記得要確認SSDL中的StoreGenerationPattern屬性。&lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=9021" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/jsPAV4UmsGap3eqZbGBYfy7Oo28/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/jsPAV4UmsGap3eqZbGBYfy7Oo28/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/jsPAV4UmsGap3eqZbGBYfy7Oo28/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/jsPAV4UmsGap3eqZbGBYfy7Oo28/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Darkthread/~4/rkCp05VO1e0" height="1" width="1"/&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/ORACLE/default.aspx">ORACLE</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Entity+Framework/default.aspx">Entity Framework</category><feedburner:origLink>http://blog.darkthread.net/post-2012-05-08-odac-with-oracle-sequence.aspx</feedburner:origLink></item><item><title>筆記-Greasemonkey Script載入jQuery的簡便方法</title><link>http://feedproxy.google.com/~r/Darkthread/~3/35CbmWPW1xw/post-2012-05-05-greasemonkey-load-jquery.aspx</link><pubDate>Sat, 05 May 2012 05:35:37 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:9017</guid><dc:creator>Jeffrey</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://blog.darkthread.net/blogs/darkthreadtw/rsscomments.aspx?PostID=9017</wfw:commentRss><comments>http://blog.darkthread.net/post-2012-05-05-greasemonkey-load-jquery.aspx#comments</comments><description>&lt;span id="PostName"&gt;&lt;/span&gt;  &lt;p&gt;寫Blog文章分享技術心得的好處之一，便是能結識來自四方的達人高手。前幾天貼了一篇用Greasemonkey Script寫RunKeeper記錄匯入外掛的Coding4Fun文章，JavaScript達人Ammon留言，照慣例又補上了寶貴資訊，其中一項是關於Greasemonkey 0.8版後的新功能--&lt;a href="mailto:--@require"&gt;@require宣告&lt;/a&gt;。&lt;/p&gt;  &lt;p&gt;在學習程式的過程中，會陸續接觸到各種情境，如果熱情足運氣好，歷經大小挑戰還沒有被搞到心灰意冷改行賣雞排，你多半能逐漸蒐集齊全解決大小問題的程式範本，成為別人口中很會寫程式的老骨頭。即使遇到很奇怪的需求，也有辦法從口袋掏出個小錦囊來，咔答咔答寫一段Code把問題解決掉。但有趣的是，技術會演進、平台會改版、軟體會升級，五年前寫下的小錦囊，記載要準備汽化燈/瓦斯燈才夠一夜露營照明之需，若沒有人告訴你這年頭LED燈泡配上鋰電池，輕巧無易燃風險就能提供相近的照明，你應該會繼續帶著去漬油跟汽化燈開開心心去露營，雖然還是達成相同目的，卻錯過了應用新技術、新科技省時省力的機會。所以囉，身為開發人員，不斷地補充新資訊是很重要滴，但像Greasemonkey久久才用一次，自然就較少持續關注它的演進發展，我想如果不是Ammon提醒，多年前學會&lt;a href="http://blog.darkthread.net/post-2009-05-28-adjust-lucifer-huge-pic.aspx"&gt;Greasemonkey Script動態載入jQuery的做法&lt;/a&gt;，我應該會一直沿用到六十歲吧! 哈~ 因此，分享程式碼或參與Open Source專案，等同邀請所有網友一起來Code Review，常有意外收獲，以此彌補盲點，避開了古人說的&amp;quot;獨學而無友，則孤陋而寡聞&amp;quot;陷阱，各位愛寫程式的阿宅們，分享好處多多，真的~&lt;/p&gt;  &lt;p&gt;學會個小技巧也能離題扯上大半天，肯定是&amp;quot;初老&amp;quot;，不，是&amp;quot;中老&amp;quot;症狀的&amp;quot;易感嘆愛嘮叼&amp;quot;徵兆。回到主題，以我的實例看一下改用@require的效果。&lt;/p&gt;  &lt;p&gt;原本我是這麼寫的:&lt;/p&gt;  &lt;div class="BlogCodeBlock"&gt;   &lt;div class="csharpcode"&gt;     &lt;pre class="alt"&gt;&lt;span class="rem"&gt;// ==UserScript==&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="rem"&gt;// @name           Marathon&amp;#39;s World-RunKeeper Plugin&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="rem"&gt;// @namespace      darkthread.net&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="rem"&gt;// @include        http://www.marathonsworld.com/app/training.php?*&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="rem"&gt;// ==/UserScript==&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;var&lt;/span&gt; GM_JQ = document.createElement(&lt;span class="str"&gt;&amp;#39;script&amp;#39;&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre&gt;GM_JQ.src = &lt;span class="str"&gt;&amp;#39;http://ajax.aspnetcdn.com/ajax/jquery/jquery-1.7.2.js&amp;#39;&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre class="alt"&gt;GM_JQ.type = &lt;span class="str"&gt;&amp;#39;text/javascript&amp;#39;&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre&gt;document.getElementsByTagName(&lt;span class="str"&gt;&amp;#39;head&amp;#39;&lt;/span&gt;)[0].appendChild(GM_JQ);&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;function&lt;/span&gt; GM_wait() {&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt;(&lt;span class="kwrd"&gt;typeof&lt;/span&gt; unsafeWindow.jQuery == &lt;span class="str"&gt;&amp;#39;undefined&amp;#39;&lt;/span&gt;) &lt;/pre&gt;

    &lt;pre class="alt"&gt;        window.setTimeout(GM_wait,100);&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="kwrd"&gt;else&lt;/span&gt; { $ = unsafeWindow.jQuery; addRunKeeperPlugin(); }&lt;/pre&gt;

    &lt;pre class="alt"&gt;}&lt;/pre&gt;

    &lt;pre&gt;GM_wait();&lt;/pre&gt;

    &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="kwrd"&gt;function&lt;/span&gt; addRunKeeperPlugin() {&lt;/pre&gt;

    &lt;pre class="alt"&gt;        blah blah...&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;改用@require寫法後:&lt;/p&gt;

&lt;div class="BlogCodeBlock"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="rem"&gt;// ==UserScript==&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="rem"&gt;// @name           Marathon&amp;#39;s World-RunKeeper Plugin&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="rem"&gt;// @namespace      darkthread.net&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="rem"&gt;// @include        http://www.marathonsworld.com/app/training.php?*&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="rem"&gt;// @require        http://ajax.aspnetcdn.com/ajax/jquery/jquery-1.7.2.js&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="rem"&gt;// ==/UserScript==&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;blah blah...&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;很省事吧?! 僅以這則筆記分享向Ammon大致敬。&lt;/p&gt;

&lt;p&gt;另外，這回還多學到@resource可以預先載入CSS之類的內容，在Greasemonkey Script中可用&lt;a href="http://wiki.greasespot.net/GM_getResourceText"&gt;GM_getResourceText&lt;/a&gt;(&amp;quot;resource_name”)取出內容，再用&lt;a href="http://wiki.greasespot.net/GM_addStyle"&gt;GM_addStyle&lt;/a&gt;()設定頁面的Style。最後，再補充一個&lt;a href="http://wiki.greasespot.net/GM_log"&gt;GM_log&lt;/a&gt;()，可以在執行期間將偵錯用資訊輸出到主控台，讓Greasemonkey Script的偵測工作簡單一些。以上這些Greasemonkey專屬指令都可以在&lt;a title="Greasemonkey Manual-API - GreaseSpot" href="http://wiki.greasespot.net/Greasemonkey_Manual:API"&gt;Greasemonkey Manual-API - GreaseSpot&lt;/a&gt;找到詳細說明，開始寫作前不妨看一下。&lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=9017" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/c46o_jSYFQ0pj-3leI0QRZlikJ0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/c46o_jSYFQ0pj-3leI0QRZlikJ0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/c46o_jSYFQ0pj-3leI0QRZlikJ0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/c46o_jSYFQ0pj-3leI0QRZlikJ0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Darkthread/~4/35CbmWPW1xw" height="1" width="1"/&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Javascript/default.aspx">Javascript</category><feedburner:origLink>http://blog.darkthread.net/post-2012-05-05-greasemonkey-load-jquery.aspx</feedburner:origLink></item><item><title>【潛盾機】將檔案結構匯成Excel文件</title><link>http://feedproxy.google.com/~r/Darkthread/~3/f-Wog7uLopA/post-2012-05-02-export-file-struc-as-excel.aspx</link><pubDate>Tue, 01 May 2012 21:22:46 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:9007</guid><dc:creator>Jeffrey</dc:creator><slash:comments>5</slash:comments><wfw:commentRss>http://blog.darkthread.net/blogs/darkthreadtw/rsscomments.aspx?PostID=9007</wfw:commentRss><comments>http://blog.darkthread.net/post-2012-05-02-export-file-struc-as-excel.aspx#comments</comments><description>&lt;span id="PostName"&gt;&lt;/span&gt; &lt;p&gt;看圖說故事好了。有個存放專案檔案的資料夾:&lt;/p&gt; &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/8972/original.aspx" alt="" /&gt;&lt;/p&gt; &lt;p&gt;因專案管理要求，需匯出依資料夾層級縮排的Excel文件樣式如下，方便填寫目錄或檔案說明:&lt;/p&gt; &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/8973/original.aspx" alt="" /&gt;&lt;/p&gt; &lt;p&gt;其中還有一點小要求是希望能彈性地略過某些目錄、檔案，例如: obj目錄。覺得這是個很好的NPOI練習題材，於是我寫了以下的小工具:&lt;/p&gt; &lt;div class="BlogCodeBlock"&gt; &lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; DumpWebTree&lt;/pre&gt;&lt;pre&gt;{&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; System.Linq;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; System.Text;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; System.Xml.Linq;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; System.IO;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; NPOI.HSSF.UserModel;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; NPOI.SS.UserModel;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; NPOI.HSSF.Util;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Utility&lt;/pre&gt;&lt;pre&gt;    {&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="rem"&gt;//簡易的目錄/檔案資料物件&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; WebItem&lt;/pre&gt;&lt;pre class="alt"&gt;        {&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Layer; &lt;span class="rem"&gt;//目錄深度&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; IsFolder; &lt;span class="rem"&gt;//是否為目錄&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Name; &lt;span class="rem"&gt;//目錄或檔案名稱&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Path; &lt;span class="rem"&gt;//完整路徑&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;public&lt;/span&gt; WebItem(&lt;span class="kwrd"&gt;string&lt;/span&gt; path, &lt;span class="kwrd"&gt;int&lt;/span&gt; layer, &lt;span class="kwrd"&gt;bool&lt;/span&gt; isFolder = &lt;span class="kwrd"&gt;false&lt;/span&gt;)&lt;/pre&gt;&lt;pre class="alt"&gt;            {&lt;/pre&gt;&lt;pre&gt;                Name = System.IO.Path.GetFileName(path);&lt;/pre&gt;&lt;pre class="alt"&gt;                IsFolder = isFolder;&lt;/pre&gt;&lt;pre&gt;                Path = path;&lt;/pre&gt;&lt;pre class="alt"&gt;                Layer = layer;&lt;/pre&gt;&lt;pre&gt;            }&lt;/pre&gt;&lt;pre class="alt"&gt;        }&lt;/pre&gt;&lt;pre&gt;        &lt;span class="rem"&gt;//用遞迴巡弋所有目錄、檔案&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; explore(List&amp;lt;WebItem&amp;gt; list, &lt;span class="kwrd"&gt;string&lt;/span&gt; path, &lt;span class="kwrd"&gt;int&lt;/span&gt; layer)&lt;/pre&gt;&lt;pre&gt;        {&lt;/pre&gt;&lt;pre class="alt"&gt;            WebItem folder = &lt;span class="kwrd"&gt;new&lt;/span&gt; WebItem(path, layer, &lt;span class="kwrd"&gt;true&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;            list.Add(folder);&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt; d &lt;span class="kwrd"&gt;in&lt;/span&gt; Directory.GetDirectories(path))&lt;/pre&gt;&lt;pre&gt;                explore(list, d, layer + 1);&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt; f &lt;span class="kwrd"&gt;in&lt;/span&gt; Directory.GetFiles(path))&lt;/pre&gt;&lt;pre&gt;            {&lt;/pre&gt;&lt;pre class="alt"&gt;                WebItem file = &lt;span class="kwrd"&gt;new&lt;/span&gt; WebItem(f, layer + 1);&lt;/pre&gt;&lt;pre&gt;                list.Add(file);&lt;/pre&gt;&lt;pre class="alt"&gt;            }&lt;/pre&gt;&lt;pre&gt;        }&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="rem"&gt;//使用Extension Method擴充方法，以較簡便方式建立CellStyle&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; ICellStyle QuickCreateStyle(&lt;/pre&gt;&lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;this&lt;/span&gt; HSSFWorkbook wb,&lt;/pre&gt;&lt;pre&gt;                &lt;span class="kwrd"&gt;short&lt;/span&gt; foreColor, &lt;span class="rem"&gt;//前景色&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;short&lt;/span&gt; backgroundColor = -1, &lt;span class="rem"&gt;//背景色&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;                HorizontalAlignment textAlignment = HorizontalAlignment.LEFT&lt;/pre&gt;&lt;pre class="alt"&gt;            )&lt;/pre&gt;&lt;pre&gt;        {&lt;/pre&gt;&lt;pre class="alt"&gt;            var style = wb.CreateCellStyle();&lt;/pre&gt;&lt;pre&gt;            var font = wb.CreateFont();&lt;/pre&gt;&lt;pre class="alt"&gt;            font.Color = foreColor;&lt;/pre&gt;&lt;pre&gt;            style.SetFont(font);&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (backgroundColor &amp;gt;= 0)&lt;/pre&gt;&lt;pre&gt;            {&lt;/pre&gt;&lt;pre class="alt"&gt;                style.FillForegroundColor = backgroundColor;&lt;/pre&gt;&lt;pre&gt;                style.FillPattern = FillPatternType.SOLID_FOREGROUND;&lt;/pre&gt;&lt;pre class="alt"&gt;            }&lt;/pre&gt;&lt;pre&gt;            style.Alignment = textAlignment;&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; style;&lt;/pre&gt;&lt;pre&gt;        }&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="rem"&gt;/// 將目錄下的目錄檔案結構匯出成Excel工作表&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="rem"&gt;/// &amp;lt;param name=&amp;quot;dirPath&amp;quot;&amp;gt;要匯出的目錄路徑&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="rem"&gt;/// &amp;lt;param name=&amp;quot;excelPath&amp;quot;&amp;gt;匯出Excel路徑&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="rem"&gt;/// &amp;lt;param name=&amp;quot;filter&amp;quot;&amp;gt;過濾函數，傳入Path進行判斷，傳回true時表排除&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; WebTreeToExcel(&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;string&lt;/span&gt; dirPath, &lt;span class="kwrd"&gt;string&lt;/span&gt; excelPath,&lt;/pre&gt;&lt;pre&gt;            Func&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;bool&lt;/span&gt;&amp;gt; filter = &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;/pre&gt;&lt;pre class="alt"&gt;        {&lt;/pre&gt;&lt;pre&gt;            &lt;span class="rem"&gt;//將目錄結構整理成清單&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;            List&amp;lt;WebItem&amp;gt; list = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;WebItem&amp;gt;();&lt;/pre&gt;&lt;pre&gt;            explore(list, dirPath, 0);&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="rem"&gt;//建立Excel&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;            HSSFWorkbook wb = &lt;span class="kwrd"&gt;new&lt;/span&gt; HSSFWorkbook();&lt;/pre&gt;&lt;pre class="alt"&gt;            var sheet = wb.CreateSheet(&lt;span class="str"&gt;&amp;quot;Site Tree&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;            var row = sheet.CreateRow(0);&lt;/pre&gt;&lt;pre class="alt"&gt;            var styleHeader = wb.QuickCreateStyle(&lt;/pre&gt;&lt;pre&gt;                HSSFColor.YELLOW.index, HSSFColor.GREEN.index, &lt;/pre&gt;&lt;pre class="alt"&gt;                HorizontalAlignment.CENTER);&lt;/pre&gt;&lt;pre&gt;            &lt;span class="rem"&gt;//寫入標題&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;int&lt;/span&gt; colIndex = 0;&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt; colName &lt;span class="kwrd"&gt;in&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;Path;File;Description&amp;quot;&lt;/span&gt;.Split(&lt;span class="str"&gt;&amp;#39;;&amp;#39;&lt;/span&gt;))&lt;/pre&gt;&lt;pre class="alt"&gt;            {&lt;/pre&gt;&lt;pre&gt;                var cell = row.CreateCell(colIndex++);&lt;/pre&gt;&lt;pre class="alt"&gt;                cell.SetCellType(CellType.STRING);&lt;/pre&gt;&lt;pre&gt;                cell.SetCellValue(colName);&lt;/pre&gt;&lt;pre class="alt"&gt;                cell.CellStyle = styleHeader;&lt;/pre&gt;&lt;pre&gt;            }&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="rem"&gt;//建立Folder Style&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;            var styleFolder = wb.QuickCreateStyle(HSSFColor.BLUE.index);&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;int&lt;/span&gt; rowIndex = 1;&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var item &lt;span class="kwrd"&gt;in&lt;/span&gt; list)&lt;/pre&gt;&lt;pre class="alt"&gt;            {&lt;/pre&gt;&lt;pre&gt;                &lt;span class="rem"&gt;//若bypass檢測傳回true，則略過該筆&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;if&lt;/span&gt; (filter != &lt;span class="kwrd"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; filter(item.Path))&lt;/pre&gt;&lt;pre&gt;                    &lt;span class="kwrd"&gt;continue&lt;/span&gt;;&lt;/pre&gt;&lt;pre class="alt"&gt;                row = sheet.CreateRow(rowIndex++);&lt;/pre&gt;&lt;pre&gt;                &lt;span class="rem"&gt;//將Path放在第一欄(稍後隱藏)&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;                var cell = row.CreateCell(0);&lt;/pre&gt;&lt;pre&gt;                cell.SetCellValue(item.Path);&lt;/pre&gt;&lt;pre class="alt"&gt;                &lt;span class="rem"&gt;//存入檔名或目錄名&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;                cell = row.CreateCell(1);&lt;/pre&gt;&lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;if&lt;/span&gt; (item.IsFolder)&lt;/pre&gt;&lt;pre&gt;                    cell.CellStyle = styleFolder;&lt;/pre&gt;&lt;pre class="alt"&gt;                cell.SetCellType(CellType.STRING);&lt;/pre&gt;&lt;pre&gt;                cell.SetCellValue(&lt;span class="kwrd"&gt;new&lt;/span&gt; String(&lt;span class="str"&gt;&amp;#39; &amp;#39;&lt;/span&gt;, item.Layer * 4) + item.Name);&lt;/pre&gt;&lt;pre class="alt"&gt;            }&lt;/pre&gt;&lt;pre&gt;            &lt;span class="rem"&gt;//第一欄隱藏&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;            sheet.SetColumnHidden(0, &lt;span class="kwrd"&gt;true&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;            &lt;span class="rem"&gt;//自動伸縮欄寬&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;            sheet.AutoSizeColumn(1);&lt;/pre&gt;&lt;pre&gt;            sheet.SetColumnWidth(1, sheet.GetColumnWidth(1) + 256);&lt;/pre&gt;&lt;pre class="alt"&gt;            sheet.SetColumnWidth(2, 100 * 256);&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;using&lt;/span&gt; (FileStream fs = &lt;/pre&gt;&lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;new&lt;/span&gt; FileStream(excelPath, FileMode.Create))&lt;/pre&gt;&lt;pre&gt;            {&lt;/pre&gt;&lt;pre class="alt"&gt;                wb.Write(fs);&lt;/pre&gt;&lt;pre&gt;            }            &lt;/pre&gt;&lt;pre class="alt"&gt;        }&lt;/pre&gt;&lt;pre&gt;    }&lt;/pre&gt;&lt;pre class="alt"&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;程式不算多，不到150行，但其中用了遞迴、&lt;a href="http://msdn.microsoft.com/zh-tw/library/bb383977.aspx"&gt;擴充方法&lt;/a&gt;(Extension Method)[延伸閱讀: 91的&lt;a href="http://www.dotblogs.com.tw/hatelove/archive/2012/04/24/extension-method-introduction.aspx"&gt;介紹文&lt;/a&gt;]、&lt;a href="http://blog.darkthread.net/post-2009-12-27-action-delegate.aspx"&gt;Func&amp;lt;string, bool&amp;gt;&lt;/a&gt;，寫得蠻開心的。(謎之聲: 大家眼睛看得很花，好嗎?)&lt;/p&gt;
&lt;p&gt;程式不好讀不打緊，使用方法倒挺簡單，傳入要掃瞄的目錄、要匯出的Excel檔路徑，再寫個小函數由路徑決定哪些項目要排除，就OK囉!&lt;/p&gt;
&lt;div class="BlogCodeBlock"&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; DumpWebTree&lt;/pre&gt;&lt;pre class="alt"&gt;{&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;class&lt;/span&gt; Program&lt;/pre&gt;&lt;pre class="alt"&gt;    {&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args)&lt;/pre&gt;&lt;pre class="alt"&gt;        {&lt;/pre&gt;&lt;pre&gt;            Utility.WebTreeToExcel(&lt;/pre&gt;&lt;pre class="alt"&gt;                &lt;span class="str"&gt;@&amp;quot;D:\OracleEF&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;d:\\webtree.xls&amp;quot;&lt;/span&gt;,&lt;/pre&gt;&lt;pre&gt;                (path) =&amp;gt;&lt;/pre&gt;&lt;pre class="alt"&gt;                {&lt;/pre&gt;&lt;pre&gt;                    &lt;span class="rem"&gt;//若路徑中包含\obj，不管目錄或檔案都要排除&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;                    &lt;span class="kwrd"&gt;if&lt;/span&gt; (path.Contains(&lt;span class="str"&gt;@&amp;quot;\obj&amp;quot;&lt;/span&gt;)) &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt;                    &lt;span class="rem"&gt;//其餘納入清單中&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;                    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;false&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt;                });&lt;/pre&gt;&lt;pre class="alt"&gt;        }&lt;/pre&gt;&lt;pre&gt;    }&lt;/pre&gt;&lt;pre class="alt"&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;font color="#f79646"&gt;【後記】&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;之前我用NPOI都是拿來讀取Excel，產生Excel的情境較少，這次算是補足原本欠缺的經驗。建立Excel時，要設定顏色、字型、寬度等眉眉角角的細節很多，我找到作者Tony Qu的部落格，提供了很多很棒的教學文章，推薦大家參考: &lt;a title="NPOI - Tony Qu - 博客园" href="http://www.cnblogs.com/tonyqus/category/182110.html"&gt;NPOI - Tony Qu - 博客园&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;另外，專案要引用NPOI時，請愛用NuGet，可以不用手動下載、安裝、加參考，搞到大粒汗小粒汗囉~&lt;img class="PopBoxImageSmall" src="http://blog.darkthread.net/photos/darkthread/images/8974/640x480.aspx" alt="" /&gt;&lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=9007" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ZlW27rQaGaG1dToEMvA6bXZOSPI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ZlW27rQaGaG1dToEMvA6bXZOSPI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ZlW27rQaGaG1dToEMvA6bXZOSPI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ZlW27rQaGaG1dToEMvA6bXZOSPI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Darkthread/~4/f-Wog7uLopA" height="1" width="1"/&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/_5B6FFE765F6A_/default.aspx">潛盾機</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Excel/default.aspx">Excel</category><feedburner:origLink>http://blog.darkthread.net/post-2012-05-02-export-file-struc-as-excel.aspx</feedburner:origLink></item><item><title>Coding4Fun-RunKeeper記錄轉檔外掛</title><link>http://feedproxy.google.com/~r/Darkthread/~3/hpRj7nAvP6Q/post-2012-04-30-greasemonkey-for-runkeeper-record-import.aspx</link><pubDate>Sun, 29 Apr 2012 22:40:32 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:8983</guid><dc:creator>Jeffrey</dc:creator><slash:comments>1</slash:comments><wfw:commentRss>http://blog.darkthread.net/blogs/darkthreadtw/rsscomments.aspx?PostID=8983</wfw:commentRss><comments>http://blog.darkthread.net/post-2012-04-30-greasemonkey-for-runkeeper-record-import.aspx#comments</comments><description>&lt;span id="PostName"&gt;&lt;/span&gt;  &lt;p&gt;前陣子入手&lt;a href="http://blog.darkthread.net/post-2012-04-22-gps-watch.aspx" target="_blank"&gt;GH-625M GPS心跳錶&lt;/a&gt;，拿來記錄慢跑心跳及里程，還寫了&lt;a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2012/04/24/8961.aspx" target="_blank"&gt;轉檔小程式&lt;/a&gt;將GH-625M的ACT檔轉成&lt;a href="http://runkeeper.com/home" target="_blank"&gt;RunKeeper&lt;/a&gt;社群網站可識別的TCX格式。在Mobile01的討論板上，&lt;a href="http://www.marathonsworld.com" target="_blank"&gt;馬拉松世界&lt;/a&gt;是另一個常被跑友提到的國內的慢跑社群網站，可以登錄練跑記錄，統計月跑量(如下圖紅框)，另外網站裡有全國大小賽事資料，可以針對其中某場比賽新增成績，而社群成員以國內跑友為主，資訊內容與生活圈較有交集，互動性比RunKeeper還有趣。&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/8982/640x480.aspx" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;不過，網站雖然支援GPS手錶或記錄器上傳慢跑記錄，但必須透過&lt;a href="http://www.marathonsworld.com/app/software_download.php" target="_blank"&gt;專屬軟體&lt;/a&gt;(不像是RunKeeper可直接上傳檔案到網站)，而該軟體主要支援站方發行的GPS運動錶(似乎與GH-625M同廠商，看晶片規格屬新一代，感覺C/P值也不錯，但我才入手新玩具所以無緣囉!)及記錄器，其他GPS設備的記錄必須透過GPX檔上傳(無法包含心跳數據)。而我實測還遇到一個小問題，軟體在Windows 7 x64上安裝得不太順利，無法執行，直到在Virtual PC中才測試成功。評估下來，對我來說，上傳到RunKeeper還是比較方便，並且有些額外功能，例如: 可以直接在網頁上校正偏移的GPS追蹤點(用JavaScript實現的，酷!!)、分享到Facebook... 等。看起來，上傳到RunKeeper，再&amp;quot;匯出&amp;quot;到馬拉松世界應是較便利的解決方案。&lt;/p&gt;  &lt;p&gt;經過一番研究，我找到一個不錯的整合切入點。馬拉松世界有個新增日誌的網頁介面，能手動輸入慢跑的日期、時間、里程，在描述區為TextArea可自由輸入文字，甚至要用文字逐一列出每公里的平均Pace及平均心跳率也未嘗不可。&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/8980/original.aspx" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;想在現成網頁加上強化功能? 這是該&lt;a href="http://blog.darkthread.net/post-2007-06-06-tools-trixie-customize-your-web-surfing.aspx" target="_blank"&gt;Greasemonkey&lt;/a&gt;出場的時候囉! 花了三個小時(時間主要消耗在Greasemonkey Script無法用IDE Debug，而我的奶油桂花手頻頻打錯字扯後腿，老花眼則看了好幾遍沒檢查出來... 至於程式部分有jQuery相助，倒是不難寫)，終於成功地在網頁輸入表格中增加&amp;quot;第九又四分之三列--RunKeeper匯入功能&amp;quot;! &lt;/p&gt;  &lt;p&gt;原本的網頁忽然多冒出一個RunKeeper區塊，輸入帳號，右方可帶出該帳號在活動記錄，選取後按【匯入】，外掛程式便會自動由RunKeeper取得網頁，擷取慢跑資訊後自動填入到網頁各欄位，蠻方便的。&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/8981/original.aspx" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;回到技術面，整理這次學到的幾點心得:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;RunKeeper網頁的Client Script一整個jQuery風，讀來格外親切；馬拉松世界則是Ext JS幫。 &lt;/li&gt;    &lt;li&gt;因為目標網頁沒有jQuery，所以在Greasemonkey Script中&lt;a href="http://blog.darkthread.net/post-2009-05-28-adjust-lucifer-huge-pic.aspx"&gt;動態載入jQuery的技巧&lt;/a&gt;又派上用場了。 &lt;/li&gt;    &lt;li&gt;在Greasemonkey中要用AJAX存取其他網站的程式或內容，需使用&lt;a href="http://wiki.greasespot.net/GM_xmlhttpRequest"&gt;GM_xmlhttpRequest&lt;/a&gt;，才能打破Same Origin Policy限制。 &lt;/li&gt;    &lt;li&gt;GM_xmlhttpRequest取回的HTML，轉為DOM較便於jQuery取出特定元素。但原來的HTML中有很多&amp;lt;script&amp;gt;，在非原網站執行會有問題，所以我用了replace(/&amp;lt;script/g, &amp;quot;&amp;lt;no_script&amp;quot;).replace(/&amp;lt;\/script/g, &amp;quot;&amp;lt;/no_script&amp;quot;)的技巧停用所有Script，之後再$(&amp;quot;#divTemp&amp;quot;).html(fixed_html)就能只純粹載入DOM。 &lt;/li&gt;    &lt;li&gt;要解析字串取出特定部分，在JavaScript中一樣要用Regular Expression才是王道，例如: &amp;quot;Apr 29, 2012&amp;quot;字串，要取出年、月、日，可以這樣寫:      &lt;br /&gt;      &lt;div class="BlogCodeBlock"&gt;       &lt;div class="csharpcode"&gt;         &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;var&lt;/span&gt; r = /([A-Za-z]{3}) (\d{1,2}), (\d{4})/.exec(&amp;quot;Apr 29, 2012&amp;quot;);&lt;/pre&gt;

        &lt;pre&gt;&lt;span class="kwrd"&gt;var&lt;/span&gt; yy = r[3];&lt;/pre&gt;

        &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;var&lt;/span&gt; dd = r[2];&lt;/pre&gt;

        &lt;pre&gt;&lt;span class="kwrd"&gt;var&lt;/span&gt; mm = $.inArray(r[1], &lt;span class="str"&gt;&amp;quot;Null;Jan;Feb;Mar;Apr;May;Jun;Jul;Aug;Sep;Oct;Nov;Dec&amp;quot;&lt;/span&gt;.split(&lt;span class="str"&gt;&amp;#39;;&amp;#39;&lt;/span&gt;));&lt;/pre&gt;
      &lt;/div&gt;
    &lt;/div&gt;
原理是在RegExp宣告中用( )分成月、日、年3個群組，在exec()後若比對成功會得到一個陣列，例如: r，其中r[0]會是整段吻合內容，即&amp;quot;Apr 29, 2012&amp;quot;，而r[1]是第一個群組&amp;quot;Apr&amp;quot;，r[2]為&amp;quot;29&amp;quot;，r[3]則為&amp;quot;2012&amp;quot;，以此類推，比自己拆解字串方便許多。 &lt;/li&gt;
&lt;/ol&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=8983" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/g_lEw4q1WuAQeWqnPK2w69e9Xx0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/g_lEw4q1WuAQeWqnPK2w69e9Xx0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/g_lEw4q1WuAQeWqnPK2w69e9Xx0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/g_lEw4q1WuAQeWqnPK2w69e9Xx0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Darkthread/~4/hpRj7nAvP6Q" height="1" width="1"/&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Coding4Fun/default.aspx">Coding4Fun</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/_6261D18D_/default.aspx">慢跑</category><feedburner:origLink>http://blog.darkthread.net/post-2012-04-30-greasemonkey-for-runkeeper-record-import.aspx</feedburner:origLink></item><item><title>側錄.NET程式網路傳輸內容</title><link>http://feedproxy.google.com/~r/Darkthread/~3/_iuWljCuExk/post-2012-04-28-trace-net-networking-traffic.aspx</link><pubDate>Sat, 28 Apr 2012 14:25:05 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:8979</guid><dc:creator>Jeffrey</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://blog.darkthread.net/blogs/darkthreadtw/rsscomments.aspx?PostID=8979</wfw:commentRss><comments>http://blog.darkthread.net/post-2012-04-28-trace-net-networking-traffic.aspx#comments</comments><description>&lt;span id="PostName"&gt;&lt;/span&gt;  &lt;p&gt;前幾天&lt;a href="http://blog.darkthread.net/post-2012-04-23-nuget-server-nupkg-pushing.aspx"&gt;偵查NuGet Server無法上傳問題&lt;/a&gt;時，我用了個有趣的小技巧觀察nuget.exe程式與Server間的網路傳輸內容。&lt;/p&gt;  &lt;p&gt;一般來說，提到監聽網路傳輸，大多人想到的是&lt;a href="http://support.microsoft.com/kb/933741"&gt;Microsoft Network Monitor&lt;/a&gt;、&lt;a href="http://www.wireshark.org/"&gt;Wireshark&lt;/a&gt;之類的Sniffer工具，但.NET有個網路追蹤(&lt;a href="http://msdn.microsoft.com/zh-tw/library/ty48b824.aspx"&gt;Network Tracing&lt;/a&gt;)功能，就鮮為人知了。&lt;/p&gt;  &lt;p&gt;MSDN文章上對於網路追蹤的各參數&lt;a href="http://msdn.microsoft.com/zh-tw/library/ty48b824.aspx"&gt;解說得很清楚&lt;/a&gt;，而且，即便不是自己寫的.NET程式，只要加上*.exe.config就可開啟追蹤記錄功能。於是在nuget.exe的茶包實例中，就順道演練了這個特殊偵錯技巧，做法是新增一個nuget.exe.config放在nuget.exe所在目錄:&lt;/p&gt;  &lt;div class="BlogCodeBlock"&gt;   &lt;div class="csharpcode"&gt;     &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="html"&gt;xml&lt;/span&gt; &lt;span class="attr"&gt;version&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1.0&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;encoding&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;utf-8&amp;quot;&lt;/span&gt; ?&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;configuration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;system.diagnostics&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;sources&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;source&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;System.Net&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;listeners&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;MyNetTrace&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;listeners&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;source&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;source&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;System.Net.HttpListener&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;listeners&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;MyNetTrace&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;listeners&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;      &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;source&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;source&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;System.Net.Sockets&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;listeners&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;MyNetTrace&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;listeners&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;source&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;source&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;System.Net.Cache&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;listeners&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;MyNetTrace&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;listeners&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;      &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;source&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;sources&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;sharedListeners&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;MyNetTrace&amp;quot;&lt;/span&gt; &lt;/pre&gt;

    &lt;pre&gt;           &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;System.Diagnostics.TextWriterTraceListener&amp;quot;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;           &lt;span class="attr"&gt;initializeData&lt;/span&gt; &lt;span class="kwrd"&gt;=&amp;quot;D:\SocketEx.log&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;sharedListeners&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;switches&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;System.Net&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Verbose&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;System.Net.Sockets&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Information&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;System.Net.Cache&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Information&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;System.Net.HttpListener&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Information&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;switches&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;system.diagnostics&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;  &lt;/pre&gt;

    &lt;pre&gt; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;configuration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;加入config檔後，nuget.exe執行時會將網路傳輸過程的記錄資訊(甚至包含傳輸內容)寫入D:\SocketEx.log檔案。重新執行nuget.exe push將程式包上傳至NuGet Server 1.7版，在SocketEx.log中可以看到詳盡的傳送歷程，包含了nuget.exe利用HTTP PUT Request將程式包內容(連.nupkg的二進位內容也被一併記錄下來)傳送到網站。&lt;/p&gt;

&lt;p&gt;&lt;img class="PopBoxImageSmall" src="http://blog.darkthread.net/photos/darkthread/images/8953/640x480.aspx" alt="" /&gt;&lt;/p&gt;

&lt;p&gt;上傳後Web Server回應HTTP Status 201, Created。(新增資料後傳回HTTP 201符合&lt;a href="http://blog.darkthread.net/post-2012-03-22-restful-websvc-on-aspnet35.aspx"&gt;Restful API風格&lt;/a&gt;) 由來往封包判讀一切正常，但Server端就是沒有寫入程式包，ProcMon也抓不到任何嘗試寫入.nupkg的行為，直到換成NuGet Server 1.9版後問題才消失。&lt;/p&gt;

&lt;p&gt;&lt;img class="PopBoxImageSmall" src="http://blog.darkthread.net/photos/darkthread/images/8954/640x480.aspx" alt="" /&gt;&lt;/p&gt;

&lt;p&gt;展示完畢，順便也在此叮嚀，&lt;font color="#ff8040"&gt;若程式必須透過網路傳送敏感資訊，請務必SSL或加密演算法加上保護&lt;/font&gt;。除了.NET的網路追蹤功能，有心人士還有很多手段可以偷取傳輸內容(也不限定.NET程式，任何語言的程式都有風險)。藉由加密，才能在被竊聽時，提高破解難度，提供最基本的資安防護。&lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=8979" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/_04vGJ8pM_njPZ3aOkbGU6aUenw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/_04vGJ8pM_njPZ3aOkbGU6aUenw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/_04vGJ8pM_njPZ3aOkbGU6aUenw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/_04vGJ8pM_njPZ3aOkbGU6aUenw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Darkthread/~4/_iuWljCuExk" height="1" width="1"/&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Security/default.aspx">Security</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/.NET/default.aspx">.NET</category><feedburner:origLink>http://blog.darkthread.net/post-2012-04-28-trace-net-networking-traffic.aspx</feedburner:origLink></item><item><title>【茶包射手日記】先行編譯網站的錯誤訊息陷阱</title><link>http://feedproxy.google.com/~r/Darkthread/~3/gkOIjsOP5Ro/post-2012-04-26-misleading-error-msg-of-precompiled-web.aspx</link><pubDate>Thu, 26 Apr 2012 00:24:12 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:8968</guid><dc:creator>Jeffrey</dc:creator><slash:comments>1</slash:comments><wfw:commentRss>http://blog.darkthread.net/blogs/darkthreadtw/rsscomments.aspx?PostID=8968</wfw:commentRss><comments>http://blog.darkthread.net/post-2012-04-26-misleading-error-msg-of-precompiled-web.aspx#comments</comments><description>&lt;span id="PostName"&gt;&lt;/span&gt;  &lt;p&gt;ASP.NET Web Site專案在發佈(Publish)時有個選項&amp;quot;Allow this precompiled site to be updatable&amp;quot;(&lt;a href="http://blog.darkthread.net/post-2006-09-05-kb-asp-net-2-0.aspx" target="_blank"&gt;舊文參考&lt;/a&gt;)，選取後，除了將所有.cs預先編譯成DLL外，發佈的.aspx內容也會被改成只有一行文字，純粹供IIS偵測檔案是否存在用:     &lt;br /&gt;&amp;quot;This is a marker file generated by the precompilation tool, and should not be deleted!&amp;quot;     &lt;br /&gt;    &lt;br /&gt;而.aspx原本的HTML標籤、JavaScript等內容，其實已被編譯封裝進bin目錄的DLL中(全部編譯成一顆DLL或一個.aspx一顆DLL)，而另外bin目錄會新增一個default.aspx.&lt;em&gt;nnnnnnnn&lt;/em&gt;.compiled檔案(其中nnnnnnnn為8碼16進位雜湊碼，例如35f098fcf、538e2dd1)，內容為XML，指出該aspx被儲存在哪一個組件的哪一個型別中，如下例:&lt;/p&gt;  &lt;p&gt;&lt;font color="#00ff00"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;      &lt;br /&gt;&amp;lt;preserve resultType=&amp;quot;3&amp;quot; virtualPath=&amp;quot;/PreComWeb/Default.aspx&amp;quot; hash=&amp;quot;35f098fcf&amp;quot; filehash=&amp;quot;6bbd7e3038e2dd1&amp;quot; flags=&amp;quot;100000&amp;quot; &lt;font color="#ffff00"&gt;assembly=&amp;quot;App_Web_vglx0yba&amp;quot;&lt;/font&gt; &lt;font color="#ffff00"&gt;type=&amp;quot;ASP.default_aspx&amp;quot;&lt;/font&gt;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;filedeps&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;filedep name=&amp;quot;/PreComWeb/Default.aspx&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;filedep name=&amp;quot;/PreComWeb/Default.aspx.cs&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/filedeps&amp;gt;       &lt;br /&gt;&amp;lt;/preserve&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;如此，即便只是網頁上HTML元素標籤或JavaScript、CSS Style的小修改，也必須修改原始程式後重新編譯、發佈，不可能直接編輯正式主機上的.aspx進行修改(如此亦可降低網頁被篡改的風險)。&lt;/p&gt;  &lt;p&gt;若我們故意將bin/default.aspx.cdcab7d2.compiled刪除，則會出現以下錯誤:&lt;/p&gt;  &lt;p&gt;&lt;i&gt;&lt;font color="#f79646"&gt;The file &amp;#39;/precomweb/default.aspx&amp;#39; has not been pre-compiled, and cannot be requested.&lt;/font&gt;&lt;/i&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/8966/original.aspx" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;少了compiled檔就找不到對應的aspx內容，很合理，到目前為止都符合我所理解的先行編譯網站運作原則。&lt;/p&gt;  &lt;p&gt;不過，前幾天就遇上一枚離奇茶包。網站發佈到另一台主機後，部分網頁爆出以上訊息，直覺上是先行編譯的環節出了問題，於是仔細檢查了PrecompiledApp.config、bin下的相關*.aspx.nnnnnnnn.compiled與對應DLL都存在，怎麼都無法解釋為何ASP.NET一直抱怨預先編譯機制出錯。由於訊息中出現0x80004005(Access Denied)，也使用了ProcMon監看，亦未發現任何讀寫檔案失敗的軌跡。&lt;/p&gt;  &lt;p&gt;最後在一篇&lt;a href="http://connect.microsoft.com/VisualStudio/feedback/details/614493/misleading-error-message-the-file-default-aspx-has-not-been-pre-compiled-and-cannot-be-requested" target="_blank"&gt;Microsoft Connect回報&lt;/a&gt;裡找到線索，&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&amp;quot;It&amp;#39;s a false error, indicative of a specific assembly it cannot load. To give you the specific one(s) it is having trouble with, clear out the entire compiled version and deploy your uncompiled code instead. Launch it and you should get the lovely yellow and white Server Error page telling you exactly what assembly it can&amp;#39;t load. Figure out how to get that assembly loaded and repeat. Once your site comes up completely then wipe out the uncompiled version and replace with the precompiled version and you are all set.&amp;quot;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;意思是，這是個誤導效果十足的錯誤訊息，真正的錯誤可能源於該網頁執行時無法載入必要的組件，建議的解決方式是先部署非先行編譯的版本到該主機上，再執行同一網頁。此時應可看到一般的ASP.NET錯誤訊息回報，指出是哪顆DLL載入發生問題，排除後再重上預先編譯版本。在本案例中，使用前述做法，也真的找到了錯誤根源，網頁用了某個舊版DLL版本才有的方法，排除後問題即告解除。&lt;/p&gt;  &lt;p&gt;試著重現及驗證此茶包:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;新建立一個Web Site Project &lt;/li&gt;    &lt;li&gt;利用NuGet加入JSON.NET &lt;/li&gt;    &lt;li&gt;在Default.aspx.cs中加入以下程式      &lt;div class="BlogCodeBlock"&gt;       &lt;div class="csharpcode"&gt;         &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;/pre&gt;

        &lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/pre&gt;

        &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Linq;&lt;/pre&gt;

        &lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Web;&lt;/pre&gt;

        &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Web.UI;&lt;/pre&gt;

        &lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Web.UI.WebControls;&lt;/pre&gt;

        &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Newtonsoft.Json;&lt;/pre&gt;

        &lt;pre&gt;&amp;#160;&lt;/pre&gt;

        &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;partial&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; _Default : System.Web.UI.Page&lt;/pre&gt;

        &lt;pre&gt;{&lt;/pre&gt;

        &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Page_Load(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;

        &lt;pre&gt;    {&lt;/pre&gt;

        &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;string&lt;/span&gt; r = JsonConvert.SerializeObject(DateTime.Now);&lt;/pre&gt;

        &lt;pre&gt;        Response.Write(r);&lt;/pre&gt;

        &lt;pre class="alt"&gt;        Response.End();&lt;/pre&gt;

        &lt;pre&gt;    }&lt;/pre&gt;

        &lt;pre class="alt"&gt;}&lt;/pre&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/li&gt;

  &lt;li&gt;發佈到新目錄F:\PreComWebPublish並掛上IIS 
    &lt;br /&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/8965/original.aspx" alt="" /&gt;&amp;#160; &lt;/li&gt;

  &lt;li&gt;測試IIS上的網站正常 &lt;/li&gt;

  &lt;li&gt;故意刪除bin/Newtonsoft.Json.dll &lt;/li&gt;

  &lt;li&gt;重測出現&lt;i&gt;The file &amp;#39;/precomweb/default.aspx&amp;#39; has not been pre-compiled, and cannot be requested. 
      &lt;br /&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/8966/original.aspx" alt="" /&gt;&lt;/i&gt; &lt;/li&gt;

  &lt;li&gt;將未編譯過的default.aspx, default.aspx.cs複製到F:\PreComWebPublish並刪除PrecompiledApp.config，記得要IISRESET &lt;/li&gt;

  &lt;li&gt;錯誤訊息改變了，明確指出缺少Newtonsoft.Json 
    &lt;br /&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/8967/original.aspx" alt="" /&gt; &lt;/li&gt;
&lt;/ol&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=8968" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/G5jKPtvQlaggSOlC2GvCTqGZ3K0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/G5jKPtvQlaggSOlC2GvCTqGZ3K0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/G5jKPtvQlaggSOlC2GvCTqGZ3K0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/G5jKPtvQlaggSOlC2GvCTqGZ3K0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Darkthread/~4/gkOIjsOP5Ro" height="1" width="1"/&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Trouble-Shooting/default.aspx">Trouble-Shooting</category><feedburner:origLink>http://blog.darkthread.net/post-2012-04-26-misleading-error-msg-of-precompiled-web.aspx</feedburner:origLink></item><item><title>VS11 &amp; ASP.NET 4.5研討會筆記</title><link>http://feedproxy.google.com/~r/Darkthread/~3/GQ9iEUf4Evs/post-2012-04-25-vs11-and-aspnet-45-beta-seminar.aspx</link><pubDate>Wed, 25 Apr 2012 13:19:39 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:8962</guid><dc:creator>Jeffrey</dc:creator><slash:comments>2</slash:comments><wfw:commentRss>http://blog.darkthread.net/blogs/darkthreadtw/rsscomments.aspx?PostID=8962</wfw:commentRss><comments>http://blog.darkthread.net/post-2012-04-25-vs11-and-aspnet-45-beta-seminar.aspx#comments</comments><description>&lt;span id="PostName"&gt;&lt;/span&gt;  &lt;p&gt;參加了&lt;a title="跨行動裝置網站開發 - 使用 ASP.NET 4.5 Beta &amp;amp; Visual Studio 11 Beta" href="http://www.microsoft.com/taiwan/events/1204_visualstudio11beta-mobile/"&gt;跨行動裝置網站開發 - 使用 ASP.NET 4.5 Beta &amp;amp; Visual Studio 11 Beta&lt;/a&gt;研討會，照例筆記心得備忘。&lt;/p&gt;  &lt;p&gt;以綜合整理今天聽到我較關注的部分: (筆記只會摘記關鍵字當索引，本次課程會有錄影檔，有興趣的朋友可留意&lt;a href="https://www.facebook.com/msdn.taiwan"&gt;MSDN FB粉絲團&lt;/a&gt;公告)&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;font color="#ff8000"&gt;&lt;strong&gt;Visual Studio 11新功能&lt;/strong&gt;&lt;/font&gt;      &lt;ol&gt;       &lt;li&gt;JavaScript終於支援Go To Definition功能囉! 像C#一樣，在函數名稱上按F12，就可跳到function宣告所在位置看Code，等這功能等好久嚕... (另外保哥分享: Go To Definition後，按Ctrl+”-“可以快速回到先前檢視位置) &lt;/li&gt;        &lt;li&gt;Preview Tab: 點選Solution Explorer或搜尋結果的htm, js, css, cs項目可立即預覽其內容，打字編輯後自動切成開啟狀態。 &lt;/li&gt;        &lt;li&gt;Page Inspector: 可即時檢視網頁呈現效果，等於在VS11內建了一個IE，並可用IE Dev Tools檢視DOM元素、CSS屬性等。 &lt;/li&gt;        &lt;li&gt;自動感應&amp;lt;DOCTYPE&amp;gt;決定用何種HTML標準檢核標籤內容。 &lt;/li&gt;        &lt;li&gt;HTML結尾Tag自動連動。例如: 將&amp;lt;div&amp;gt;改成&amp;lt;span&amp;gt;時，其對應的&amp;lt;/div&amp;gt;也會自動改成&amp;lt;/span&amp;gt;。 &lt;/li&gt;        &lt;li&gt;在HTML View &amp;lt;asp:***&amp;gt;按右鍵也可叫出Server Control附屬的設定視窗(例如: &amp;lt;asp:GridView&amp;gt;按右鍵叫出UI修改Column設定，以前必須切到Design View才能進行) &lt;/li&gt;        &lt;li&gt;選取一段HTML直接轉成WebForm User Control。 &lt;/li&gt;        &lt;li&gt;Intellisense自動完成可用&amp;quot;td&amp;quot;帶出&amp;quot;t&amp;quot;ext-&amp;quot;d&amp;quot;ecoration &lt;/li&gt;        &lt;li&gt;強化的CSS顏色選擇器: #ffffff色碼的位置可叫出顏色選擇器，並會提示同網頁使用過的顏色優先挑選，當然也支援自訂顏色及滴管取色。 &lt;/li&gt;        &lt;li&gt;支援CSS Hacks，方便編輯IE6, IE7才能識別套用的樣式，以降服萬惡的IE。 &lt;/li&gt;        &lt;li&gt;針對CSS3規格，如border-radius，以往需分別寫成-webkit, –o, -moz等專屬語法以確保跨瀏覽器一致，在VS11只要寫標準CSS3樣式，VS11會自動補齊各瀏覽器專用版本。 &lt;/li&gt;        &lt;li&gt;CSS有縮排效果，例如: #boo span會比#boo內縮。 &lt;/li&gt;        &lt;li&gt;用JavaScript指令動態載入的JS也支援Intellisense，Beta版還不Work，RTM才會OK。 &lt;/li&gt;        &lt;li&gt;jQuery Template部分也支援高亮(Syntax Highlight)顯示。 &lt;/li&gt;        &lt;li&gt;支援WinJS(Win8 Metro App)，要開發Win8程式要靠VS11。Expression Blend 5對於WinJS設計提供額外支援。(例如: 呈現清單範本展開的樣子) &lt;/li&gt;        &lt;li&gt;JavaScript Intellisense支援XML Documentation為函數定義多載(overloading)呼叫參數說明。 &lt;/li&gt;        &lt;li&gt;VS11支援自動更新，會主動通知有更新可下載安裝。 &lt;/li&gt;     &lt;/ol&gt;   &lt;/li&gt;    &lt;li&gt;&lt;font color="#ff8000"&gt;&lt;strong&gt;ASP.NET 4.5改良&lt;/strong&gt;&lt;/font&gt;       &lt;ol&gt;       &lt;li&gt;ASP.Net Web API: 實現Restful Style API(&lt;a href="http://blog.darkthread.net/post-2012-03-22-restful-websvc-on-aspnet35.aspx"&gt;延伸閱讀&lt;/a&gt;) &lt;/li&gt;        &lt;li&gt;支援*.js、*.css打包壓縮，&amp;lt;script src=”folderName/js”&amp;gt;可自動將目錄下所有js打包並壓縮，因順序會有影響，如要控制需在檔名上做手腳。 &lt;/li&gt;        &lt;li&gt;已內建Anti-Cross Site Scripting Library，&lt;a href="http://msdn.microsoft.com/en-us/library/system.web.security.antixss.antixssencoder.htmlencode(v=vs.110).aspx"&gt;AntiXssEncoder.HtmlEncode&lt;/a&gt;，或用懶人法&amp;lt;%#&lt;span style="background-color:yellow;color:red;"&gt;:&lt;/span&gt; Eval(“PropName”) %&amp;gt; &lt;/li&gt;        &lt;li&gt;WebSocket支援: &lt;a href="http://msdn.microsoft.com/en-us/library/system.net.websockets.websocket(v=vs.110).aspx"&gt;WebSocket&lt;/a&gt; Class &lt;/li&gt;        &lt;li&gt;ASP.NET 4.5最多可增加35%速度，節省35%記憶體。(最理想的狀況) &lt;/li&gt;        &lt;li&gt;&amp;lt;asp:GridView ItemType=”ModelType”&amp;gt;可Bind至Model類別，強型別寫法&amp;lt;%# Item.PropName%&amp;gt;比傳統&amp;lt;%# Eval(“PropName”)%&amp;gt;好寫不易出錯。 &lt;/li&gt;        &lt;li&gt;Universal Provider: Membership、Profile、Role、Session不限定SQL Server。 &lt;/li&gt;        &lt;li&gt;方便的非同步程式語法&lt;a href="http://msdn.microsoft.com/en-us/library/hh191443(v=vs.110).aspx"&gt;await async&lt;/a&gt; &lt;/li&gt;        &lt;li&gt;ASP.NET Validator改為&lt;a href="http://blog.ericsk.org/archives/699"&gt;Unobtrusive&lt;/a&gt;風格，以data-val-*方式標註檢核要求，不再產生額外JavaScript Code。 &lt;/li&gt;        &lt;li&gt;TextBox增加ValidateRequestMode，可單獨設定特定TextBox允許HTML標籤字元(參考: &lt;a title="多想兩分鐘，你可以不用 validateRequest=-false- - 黑暗執行緒" href="http://blog.darkthread.net/post-2012-02-01-pass-request-validation.aspx"&gt;多想兩分鐘，你可以不用 validateRequest=-false&lt;/a&gt;) &lt;/li&gt;        &lt;li&gt;IQueryable vs IEnumerate: IQueryable來源可以是資料庫/Web Service，不用先將全部資料寫入記憶體、並可支援&lt;a href="http://www.asp.net/web-api/overview/web-api-routing-and-actions/paging-and-querying"&gt;OData查詢&lt;/a&gt;(實現條件查詢/分頁功能) &lt;/li&gt;     &lt;/ol&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;【延伸閱讀】&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://teacher.syset.com/viewtopic.mspx?t=5650"&gt;曹祖聖老師--使用 jQuery Mobile 設計跨行動裝置網站 投影片與範例&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blog.miniasp.com/post/2012/04/21/Visual-Studio-11-Beta-development-environment-options-tips.aspx"&gt;保哥--Visual Studio 11 Beta 開發環境選項設定技巧與心得筆記&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a title="Features NO ONE NOTICED in Visual Studio 11 Express Beta for Web - Scott Hanselman" href="http://www.hanselman.com/blog/FeaturesNOONENOTICEDInVisualStudio11ExpressBetaForWeb.aspx"&gt;Features NO ONE NOTICED in Visual Studio 11 Express Beta for Web - Scott Hanselman&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a title="HTML5, CSS3 and Javascript improvements in Visual Studio 11" href="http://blog.goyello.com/2012/03/02/html5-css3-and-javascript-improvements-in-visual-studio-11/"&gt;HTML5, CSS3 and Javascript improvements in Visual Studio 11&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=8962" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/uHNh79LYoUjizH0ln0taYTRgD1E/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/uHNh79LYoUjizH0ln0taYTRgD1E/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/uHNh79LYoUjizH0ln0taYTRgD1E/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/uHNh79LYoUjizH0ln0taYTRgD1E/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Darkthread/~4/GQ9iEUf4Evs" height="1" width="1"/&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/VS11/default.aspx">VS11</category><feedburner:origLink>http://blog.darkthread.net/post-2012-04-25-vs11-and-aspnet-45-beta-seminar.aspx</feedburner:origLink></item><item><title>Coding4Fun–GPS心跳表記錄檔轉TCX</title><link>http://feedproxy.google.com/~r/Darkthread/~3/Gpc8OwOHy2I/8961.aspx</link><pubDate>Mon, 23 Apr 2012 22:50:00 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:8961</guid><dc:creator>Jeffrey</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://blog.darkthread.net/blogs/darkthreadtw/rsscomments.aspx?PostID=8961</wfw:commentRss><comments>http://blog.darkthread.net/blogs/darkthreadtw/archive/2012/04/24/8961.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://runkeeper.com/home" target="_blank"&gt;RunKeeper&lt;/a&gt;是個有趣的健身社群網站，在WP7、iPhone、Android等手機平台都有App，利用手機GPS定位邊慢跑邊記錄，能算出時速、里程、消耗卡路里等，之後還可上傳到網站，產生精美報告，結合Google Map呈現跑步路線，提供坡度爬升、平均速度的曲線圖，最後還可將結果分享到Facebook、Twitter等社群平台，平添運動健身的樂趣! 除了透過App記錄，RunKeeper也支援GPS記錄檔上傳，換句話說，GPS手錶或其他導航裝置也可當作RunKeeper的記錄工具，甚至比App再多出心跳記錄功能。&lt;/p&gt;  &lt;p&gt;之前試過抓著HD7執行RunKeeper App跑完&lt;a href="http://runkeeper.com/user/JeffreyLee/activity/80721418" target="_blank"&gt;政大環山道&lt;/a&gt;，邊跑邊看速度讓慢跑更有趣，只是抓著有點重量的手機跑步，總要擔心一個手滑摔機，會淚灑跑道，難免礙手礙腳，無法盡情奔跑。之前看過有人用手機臂套把iPhone綁在手臂上，不過手臂多掛162公克的重物，多少會影響平衡，而臂套必須束緊防滑，會造成一些不適感，也不算很完美的方案。現在有了GPS手錶，就方便多了。&lt;/p&gt;  &lt;p&gt;話說&lt;a href="http://blog.darkthread.net/post-2012-04-22-gps-watch.aspx" target="_blank"&gt;新入手&lt;/a&gt;的心跳錶雖然便宜大碗，但畢竟難比國際大廠，整合應用上不如Garmin產品吃香。以RunKeeper的GPS記錄檔匯入功能為例，它支援&lt;a href="http://www.topografix.com/gpx.asp" target="_blank"&gt;GPX&lt;/a&gt;、&lt;a href="http://developer.garmin.com/schemas/tcx/v2/" target="_blank"&gt;TCX&lt;/a&gt;兩種格式(TCX為Garmin發展的規格，除地理資訊外，還可包含心跳率、自行車踏頻等資料)，Gramin裝置可直接匯出整合。而GH-625M搭配的是自家的GS-Sport Traning Gym軟體，可由手錶載入記錄、繪製Google Map路線圖及速度、高度、心跳曲線圖，並能依日期歸檔，功能尚可，但不如RunKeeper報表來得精美，且少了社群分享功能也少了幾分趣味。&lt;/p&gt;  &lt;p&gt;&lt;img class="PopBoxImageSmall" src="http://blog.darkthread.net/photos/darkthread/images/8959/640x480.aspx" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;GS-Sport Training Gym可將跑步歷程匯出成GPX格式，但心跳率部分使用自創的XML Schema儲存，RunKeeper無法識別。而在Garmin的規格中，TCX才支援心跳，於是我想到若能將其轉為TCX格式，就可實現連同心跳資料一起匯入RunKeeper的夢想。&lt;/p&gt;  &lt;p&gt;做了簡單的研究:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;關於TCX，Garmin提供了很詳細的&lt;a href="http://developer.garmin.com/schemas/tcx/v2/" target="_blank"&gt;規格&lt;/a&gt;，還有Sample(&lt;a href="http://developer.garmin.com/schemas/tcx/v2/samples/FitnessCoursesDetail.tcx"&gt;TCX Fitness Courses Detail&lt;/a&gt;)可參考，要做出符合規格的XML不難。&lt;/li&gt;    &lt;li&gt;GS-Sport Training Gym除了可將運動路線匯出成GPX外，還有一個更有趣的匯出格式ACT，用Notepad++打開ACT檔一看:      &lt;br /&gt;&lt;img class="PopBoxImageSmall" src="http://blog.darkthread.net/photos/darkthread/images/8960/640x480.aspx" alt="" /&gt;&amp;nbsp; &lt;br /&gt;有沒有&amp;quot;他鄉遇故知&amp;quot;的激動感呀? 這不就是.NET DataSet的XML儲存格式嗎? 小試之後，確認用DataSet.LoadXml()就能將它還原回內含三個DataTable的.NET DataSet物件，處理起來比GPX還方便。(猜想GS-Sport Training Gym應該是用.NET開發的)&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;此等天時地利人和，還不寫個轉檔程式自用，豈不人神共憤，天地難容，沒資格被稱作資深.NET開發人員?&lt;/p&gt;  &lt;p&gt;所以，不到150行，TCX轉檔程式就完成囉! 編譯成WinForm型式，就仿照&lt;a href="http://blog.darkthread.net/post-2012-04-12-keep-csv-leading-zeros-in-excel.aspx"&gt;【潛盾機】避免Excel開啟CSV時截掉左補零的小工具&lt;/a&gt;原理，執行後選取ACT檔案，轉成TCX後存於同一目錄下。&lt;/p&gt;  &lt;div class="BlogCodeBlock"&gt;   &lt;div class="csharpcode"&gt;     &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Linq;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Text;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Data;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.IO;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Windows.Forms;&lt;/pre&gt;

    &lt;pre&gt;&amp;nbsp;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; Act2Tcx&lt;/pre&gt;

    &lt;pre&gt;{&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;class&lt;/span&gt; Program&lt;/pre&gt;

    &lt;pre&gt;    {&lt;/pre&gt;

    &lt;pre class="alt"&gt;        [STAThread]&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args)&lt;/pre&gt;

    &lt;pre class="alt"&gt;        {&lt;/pre&gt;

    &lt;pre&gt;            OpenFileDialog openFile = &lt;span class="kwrd"&gt;new&lt;/span&gt; OpenFileDialog();&lt;/pre&gt;

    &lt;pre class="alt"&gt;            openFile.Filter = &lt;span class="str"&gt;&amp;quot;GS-Sport ACT File|*.act&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (openFile.ShowDialog() == DialogResult.OK)&lt;/pre&gt;

    &lt;pre class="alt"&gt;            {&lt;/pre&gt;

    &lt;pre&gt;                Course c = Load(openFile.FileName);&lt;/pre&gt;

    &lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;string&lt;/span&gt; tcxFile = Path.Combine(&lt;/pre&gt;

    &lt;pre&gt;                    Path.GetDirectoryName(openFile.FileName), &lt;/pre&gt;

    &lt;pre class="alt"&gt;                    c.Name.Replace(&lt;span class="str"&gt;&amp;quot;:&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;) + &lt;span class="str"&gt;&amp;quot;.tcx&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre&gt;                File.WriteAllText(tcxFile, c.ToXml());&lt;/pre&gt;

    &lt;pre class="alt"&gt;                MessageBox.Show(&lt;span class="str"&gt;&amp;quot;Done! - &amp;quot;&lt;/span&gt; + tcxFile);&lt;/pre&gt;

    &lt;pre&gt;            }&lt;/pre&gt;

    &lt;pre class="alt"&gt;        }&lt;/pre&gt;

    &lt;pre&gt;&amp;nbsp;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; Course Load(&lt;span class="kwrd"&gt;string&lt;/span&gt; file)&lt;/pre&gt;

    &lt;pre&gt;        {&lt;/pre&gt;

    &lt;pre class="alt"&gt;            DataSet ds = &lt;span class="kwrd"&gt;new&lt;/span&gt; DataSet();&lt;/pre&gt;

    &lt;pre&gt;            ds.ReadXml(file);&lt;/pre&gt;

    &lt;pre class="alt"&gt;            DataTable trackmaster = ds.Tables[&lt;span class="str"&gt;&amp;quot;trackmaster&amp;quot;&lt;/span&gt;];&lt;/pre&gt;

    &lt;pre&gt;            DataTable trackPoints = ds.Tables[&lt;span class="str"&gt;&amp;quot;TrackPoints&amp;quot;&lt;/span&gt;];&lt;/pre&gt;

    &lt;pre class="alt"&gt;            DataRow row = trackmaster.Rows[0];&lt;/pre&gt;

    &lt;pre&gt;            DateTime startTime = DateTime.ParseExact(&lt;/pre&gt;

    &lt;pre class="alt"&gt;            row[&lt;span class="str"&gt;&amp;quot;TrackName&amp;quot;&lt;/span&gt;].ToString() + &lt;span class="str"&gt;&amp;quot; &amp;quot;&lt;/span&gt; + row[&lt;span class="str"&gt;&amp;quot;StartTime&amp;quot;&lt;/span&gt;].ToString(),&lt;/pre&gt;

    &lt;pre&gt;                &lt;span class="str"&gt;&amp;quot;yyyy-M-dd HH:mm:ss&amp;quot;&lt;/span&gt;, &lt;span class="kwrd"&gt;null&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre class="alt"&gt;            Course c = &lt;span class="kwrd"&gt;new&lt;/span&gt; Course()&lt;/pre&gt;

    &lt;pre&gt;            {&lt;/pre&gt;

    &lt;pre class="alt"&gt;                Name = &lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(&lt;span class="str"&gt;&amp;quot;{0:yyyy-MM-dd HH:mm:ss} {1:N0}m&amp;quot;&lt;/span&gt;, startTime,&lt;/pre&gt;

    &lt;pre&gt;                       &lt;span class="kwrd"&gt;decimal&lt;/span&gt;.Parse(row[&lt;span class="str"&gt;&amp;quot;Distence&amp;quot;&lt;/span&gt;].ToString()))&lt;/pre&gt;

    &lt;pre class="alt"&gt;            };&lt;/pre&gt;

    &lt;pre&gt;            DateTime currTime = startTime;&lt;/pre&gt;

    &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (DataRow tp &lt;span class="kwrd"&gt;in&lt;/span&gt; trackPoints.Rows)&lt;/pre&gt;

    &lt;pre&gt;            {&lt;/pre&gt;

    &lt;pre class="alt"&gt;                c.TrackPoints.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; TrackPoint()&lt;/pre&gt;

    &lt;pre&gt;                {&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    Time = currTime,&lt;/pre&gt;

    &lt;pre&gt;                    AltitudeMeters = &lt;span class="kwrd"&gt;decimal&lt;/span&gt;.Parse(tp[&lt;span class="str"&gt;&amp;quot;Altitude&amp;quot;&lt;/span&gt;].ToString()),&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    HeartRateBpm = &lt;span class="kwrd"&gt;decimal&lt;/span&gt;.Parse(tp[&lt;span class="str"&gt;&amp;quot;HeartRate&amp;quot;&lt;/span&gt;].ToString()),&lt;/pre&gt;

    &lt;pre&gt;                    LatitudeDegrees = &lt;span class="kwrd"&gt;decimal&lt;/span&gt;.Parse(tp[&lt;span class="str"&gt;&amp;quot;Latitude&amp;quot;&lt;/span&gt;].ToString()),&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    LongitudeDegrees = &lt;span class="kwrd"&gt;decimal&lt;/span&gt;.Parse(tp[&lt;span class="str"&gt;&amp;quot;Longitude&amp;quot;&lt;/span&gt;].ToString())&lt;/pre&gt;

    &lt;pre&gt;                });&lt;/pre&gt;

    &lt;pre class="alt"&gt;                currTime = currTime.AddSeconds(&lt;span class="kwrd"&gt;double&lt;/span&gt;.Parse(tp[&lt;span class="str"&gt;&amp;quot;IntervalTime&amp;quot;&lt;/span&gt;].ToString()));&lt;/pre&gt;

    &lt;pre&gt;            }&lt;/pre&gt;

    &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; c;&lt;/pre&gt;

    &lt;pre&gt;        }&lt;/pre&gt;

    &lt;pre class="alt"&gt;    }&lt;/pre&gt;

    &lt;pre&gt;&amp;nbsp;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Course&lt;/pre&gt;

    &lt;pre&gt;    {&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Name;&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; List&amp;lt;TrackPoint&amp;gt; TrackPoints = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;TrackPoint&amp;gt;();&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ToXml()&lt;/pre&gt;

    &lt;pre&gt;        {&lt;/pre&gt;

    &lt;pre class="alt"&gt;            StringBuilder sb = &lt;span class="kwrd"&gt;new&lt;/span&gt; StringBuilder();&lt;/pre&gt;

    &lt;pre&gt;            TrackPoint st = TrackPoints.First(), ed = TrackPoints.Last();&lt;/pre&gt;

    &lt;pre class="alt"&gt;            sb.AppendFormat(&lt;span class="str"&gt;@&amp;quot;&amp;lt;?xml version=&amp;quot;&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;1.0&amp;quot;&lt;/span&gt;&lt;span class="str"&gt;&amp;quot; encoding=&amp;quot;&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;UTF-8&amp;quot;&lt;/span&gt;&lt;span class="str"&gt;&amp;quot; standalone=&amp;quot;&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;no&amp;quot;&lt;/span&gt;&lt;span class="str"&gt;&amp;quot; ?&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;&amp;lt;TrainingCenterDatabase xmlns=&amp;quot;&lt;span class="str"&gt;&amp;quot;http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2&amp;quot;&lt;/span&gt;&lt;span class="str"&gt;&amp;quot; xmlns:xsi=&amp;quot;&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;/span&gt;&lt;span class="str"&gt;&amp;quot; xsi:schemaLocation=&amp;quot;&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2 http://www.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd&amp;quot;&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;  &amp;lt;Folders/&amp;gt;&lt;/pre&gt;

    &lt;pre&gt;  &amp;lt;Courses&amp;gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &amp;lt;Course&amp;gt;&lt;/pre&gt;

    &lt;pre&gt;      &amp;lt;Name&amp;gt;{0}&amp;lt;/Name&amp;gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;      &amp;lt;Lap&amp;gt;&lt;/pre&gt;

    &lt;pre&gt;        &amp;lt;TotalTimeSeconds&amp;gt;{1}&amp;lt;/TotalTimeSeconds&amp;gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &amp;lt;DistanceMeters&amp;gt;{2}&amp;lt;/DistanceMeters&amp;gt;&lt;/pre&gt;

    &lt;pre&gt;        &amp;lt;BeginPosition&amp;gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;          &amp;lt;LatitudeDegrees&amp;gt;{3}&amp;lt;/LatitudeDegrees&amp;gt;&lt;/pre&gt;

    &lt;pre&gt;          &amp;lt;LongitudeDegrees&amp;gt;{4}&amp;lt;/LongitudeDegrees&amp;gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &amp;lt;/BeginPosition&amp;gt;&lt;/pre&gt;

    &lt;pre&gt;        &amp;lt;EndPosition&amp;gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;          &amp;lt;LatitudeDegrees&amp;gt;{5}&amp;lt;/LatitudeDegrees&amp;gt;&lt;/pre&gt;

    &lt;pre&gt;          &amp;lt;LongitudeDegrees&amp;gt;{6}&amp;lt;/LongitudeDegrees&amp;gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &amp;lt;/EndPosition&amp;gt;&lt;/pre&gt;

    &lt;pre&gt;        &amp;lt;AverageHeartRateBpm xsi:type=&amp;quot;&lt;span class="str"&gt;&amp;quot;HeartRateInBeatsPerMinute_t&amp;quot;&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;          &amp;lt;Value&amp;gt;{7}&amp;lt;/Value&amp;gt;&lt;/pre&gt;

    &lt;pre&gt;        &amp;lt;/AverageHeartRateBpm&amp;gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &amp;lt;MaximumHeartRateBpm xsi:type=&amp;quot;&lt;span class="str"&gt;&amp;quot;HeartRateInBeatsPerMinute_t&amp;quot;&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;          &amp;lt;Value&amp;gt;{8}&amp;lt;/Value&amp;gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &amp;lt;/MaximumHeartRateBpm&amp;gt;&lt;/pre&gt;

    &lt;pre&gt;        &amp;lt;Intensity&amp;gt;Active&amp;lt;/Intensity&amp;gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;      &amp;lt;/Lap&amp;gt;&lt;/pre&gt;

    &lt;pre&gt;      &amp;lt;Track&amp;gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&amp;quot;, Name,&lt;/pre&gt;

    &lt;pre&gt;              (ed.Time - st.Time).TotalSeconds,&lt;/pre&gt;

    &lt;pre class="alt"&gt;              0, &lt;span class="rem"&gt;//DistanceMeters, RunKeeper不需，省略&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;              st.LatitudeDegrees, st.LongitudeDegrees,&lt;/pre&gt;

    &lt;pre class="alt"&gt;              ed.LatitudeDegrees, ed.LongitudeDegrees,&lt;/pre&gt;

    &lt;pre&gt;              0, &lt;span class="rem"&gt;//AverageHeartRateBpm, RunKeeper不需，省略&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;              TrackPoints.Select(o =&amp;gt; o.HeartRateBpm).Max() &lt;span class="rem"&gt;//MaximumHeartRateBpm&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;              );&lt;/pre&gt;

    &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (TrackPoint tp &lt;span class="kwrd"&gt;in&lt;/span&gt; TrackPoints)&lt;/pre&gt;

    &lt;pre&gt;                sb.AppendLine(tp.ToXml());&lt;/pre&gt;

    &lt;pre class="alt"&gt;            sb.AppendLine(&lt;span class="str"&gt;@&amp;quot;     &amp;lt;/Track&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;    &amp;lt;/Course&amp;gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;  &amp;lt;/Courses&amp;gt;&lt;/pre&gt;

    &lt;pre&gt;&amp;lt;/TrainingCenterDatabase&amp;gt;&amp;quot;);&lt;/pre&gt;

    &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; sb.ToString();&lt;/pre&gt;

    &lt;pre&gt;        }&lt;/pre&gt;

    &lt;pre class="alt"&gt;    }&lt;/pre&gt;

    &lt;pre&gt;&amp;nbsp;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; TrackPoint&lt;/pre&gt;

    &lt;pre&gt;    {&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; DateTime Time;&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;decimal&lt;/span&gt; LatitudeDegrees;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;decimal&lt;/span&gt; LongitudeDegrees;&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;decimal&lt;/span&gt; AltitudeMeters;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;decimal&lt;/span&gt; DistanceMeters;&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;decimal&lt;/span&gt; HeartRateBpm;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ToXml()&lt;/pre&gt;

    &lt;pre&gt;        {&lt;/pre&gt;

    &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(&lt;span class="str"&gt;@&amp;quot;&amp;lt;Trackpoint&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;          &amp;lt;Time&amp;gt;{0:yyyy-MM-ddTHH:mm:ssZ}&amp;lt;/Time&amp;gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;          &amp;lt;Position&amp;gt;&lt;/pre&gt;

    &lt;pre&gt;            &amp;lt;LatitudeDegrees&amp;gt;{1}&amp;lt;/LatitudeDegrees&amp;gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;            &amp;lt;LongitudeDegrees&amp;gt;{2}&amp;lt;/LongitudeDegrees&amp;gt;&lt;/pre&gt;

    &lt;pre&gt;          &amp;lt;/Position&amp;gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;          &amp;lt;AltitudeMeters&amp;gt;{3}&amp;lt;/AltitudeMeters&amp;gt;&lt;/pre&gt;

    &lt;pre&gt;          &amp;lt;DistanceMeters&amp;gt;{4}&amp;lt;/DistanceMeters&amp;gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;          &amp;lt;HeartRateBpm xsi:type=&amp;quot;&lt;span class="str"&gt;&amp;quot;HeartRateInBeatsPerMinute_t&amp;quot;&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;            &amp;lt;Value&amp;gt;{5}&amp;lt;/Value&amp;gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;          &amp;lt;/HeartRateBpm&amp;gt;&lt;/pre&gt;

    &lt;pre&gt;          &amp;lt;SensorState&amp;gt;Absent&amp;lt;/SensorState&amp;gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &amp;lt;/Trackpoint&amp;gt;&amp;quot;, Time, LatitudeDegrees, LongitudeDegrees,&lt;/pre&gt;

    &lt;pre&gt;        AltitudeMeters, DistanceMeters, HeartRateBpm);&lt;/pre&gt;

    &lt;pre class="alt"&gt;        }&lt;/pre&gt;

    &lt;pre&gt;    }&lt;/pre&gt;

    &lt;pre class="alt"&gt;}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;就這樣，我的GH-625M記錄也能上傳&lt;a href="http://runkeeper.com/user/JeffreyLee/activity/83088111" target="_blank"&gt;RunKeeper&lt;/a&gt;囉! 會寫程式真好~~&lt;/p&gt;

&lt;p&gt;&lt;img class="PopBoxImageSmall" src="http://blog.darkthread.net/photos/darkthread/images/8958/640x480.aspx" alt="" /&gt;&lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=8961" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/4fnvFJGjTq-DiUGB9ZoemZqDaBw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4fnvFJGjTq-DiUGB9ZoemZqDaBw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/4fnvFJGjTq-DiUGB9ZoemZqDaBw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4fnvFJGjTq-DiUGB9ZoemZqDaBw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Darkthread/~4/Gpc8OwOHy2I" height="1" width="1"/&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Coding4Fun/default.aspx">Coding4Fun</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/_6261D18D_/default.aspx">慢跑</category><feedburner:origLink>http://blog.darkthread.net/blogs/darkthreadtw/archive/2012/04/24/8961.aspx</feedburner:origLink></item><item><title>NuGet Server之上傳功能</title><link>http://feedproxy.google.com/~r/Darkthread/~3/qG5Cmw8uKdw/post-2012-04-23-nuget-server-nupkg-pushing.aspx</link><pubDate>Mon, 23 Apr 2012 13:29:00 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:8957</guid><dc:creator>Jeffrey</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://blog.darkthread.net/blogs/darkthreadtw/rsscomments.aspx?PostID=8957</wfw:commentRss><comments>http://blog.darkthread.net/post-2012-04-23-nuget-server-nupkg-pushing.aspx#comments</comments><description>&lt;span id="PostName"&gt;&lt;/span&gt;  &lt;p&gt;最近安裝&lt;a href="http://blog.darkthread.net/post-2011-09-03-nuget-1-5-support-authentication.aspx"&gt;NuGet私服&lt;/a&gt;，試用NuGet Servrer 1.7版，發現1.4版起NuGet Server加入了&lt;a href="http://docs.nuget.org/docs/release-notes/nuget-1.4#NuGet_Server_Support_for_Pushing_Packages_using_NuGet.exe"&gt;用nuget.exe上傳程式包&lt;/a&gt;的功能。&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/8950/640x480.aspx" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;安裝好伺服器後，並在web.config中設定apiKey參數，基本上等同上傳密碼，只要知道apiKey就可使用nuget.exe上傳及刪除NuGet Server程式包。apiKey要注意密碼強度並嚴防外洩，GUID是很不錯的選擇，此處為求簡短易讀，暫用著名的展示用密碼--p@ ssW0rd當作apiKey。&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/8951/640x480.aspx" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;要進行上傳還需要nuget.exe工具程式，要取得可先下載&lt;a title="NuGet - Download- NuGet.exe Command Line bootstrapper" href="http://nuget.codeplex.com/releases/view/58939"&gt;NuGet.exe Command Line bootstrapper&lt;/a&gt;，執行後會自動下載最新版，接著即可用    &lt;br /&gt;nuget push some.nupkg –s httq://yourNuGetServer/ your_password    &lt;br /&gt;指令將程式包上傳到NuGet Server的Packages目錄。&lt;/p&gt;  &lt;p&gt;不過，遇上一段小插曲，使用NuGet Server 1.7版，上傳後會回應&amp;quot;Your package was pushed&amp;quot;，但卻怎麼都不會新增到Packages目錄，檢視IIS Log及使用ProcMon觀察均未發現錯誤跡象，感覺上NuGet Server收下上傳內容，什麼事都沒做卻回應&amp;quot;搞定了&amp;quot;。&lt;/p&gt;  &lt;p&gt;最後，從&lt;a href="http://nuget.codeplex.com/SourceControl/list/changesets"&gt;CodePlex&lt;/a&gt;下載NuGet Server 1.9版原始程式碼自行編譯，push/delete功能在1.9版一切正常，測試結果如下:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/8952/original.aspx" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;補充兩點: &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;當使用不正確的apiKey(如上圖中的wrongPassword)，push仍會得到Your package was pushed訊息(但程式包並未上傳成功)，但delete時則會抛回Access denied for package &amp;#39;...&amp;#39; &lt;/li&gt;    &lt;li&gt;nuget list可列舉伺服器上的程式包清單，但-s參數指定URL時要多加/nuget，與push/delete不同。 &lt;/li&gt; &lt;/ol&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=8957" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/-o32ItGiqDB4QxJKUwwe9Xg7zdg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-o32ItGiqDB4QxJKUwwe9Xg7zdg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/-o32ItGiqDB4QxJKUwwe9Xg7zdg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-o32ItGiqDB4QxJKUwwe9Xg7zdg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Darkthread/~4/qG5Cmw8uKdw" height="1" width="1"/&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/NuGet/default.aspx">NuGet</category><feedburner:origLink>http://blog.darkthread.net/post-2012-04-23-nuget-server-nupkg-pushing.aspx</feedburner:origLink></item></channel></rss>

