2007-12-27

深入 Microsoft.VisualBasic.Strings.StrConv 簡繁轉換

昨天又遇到一個簡繁轉換的需求, 雖然這個問題以前已經處理過了, 但是以前是用自己建立的 b52gb 和 gb2b5 的對應表來完成這個需求(VB6 的話就用 StrConv 方法來達成), 在 .NET 環境中, Microsoft.VisualBasic.dll 裡也有提供 Strings.StrConv 方法, 而且用法和原來的 VB6 幾乎是如出一轍, 可是昨天在使用 StrConv 的時候卻意外發現了一些奇怪的現象, 特別深入研究了一下, 順便記錄下來!

先來觀察 Strings.StrConv 方法的簽名:

public static string StrConv(string str, VbStrConv Conversion, [Optional, DefaultParameterValue(0)] int LocaleID)

第三個參數和 MSDN 上的文件有點不同, 上面的簽名是從 Reflector 中摘出來的, 也是這篇文章要記錄的重點, 先來看一些範例:

    a1 = Strings.StrConv("书樂う반", VbStrConv.TraditionalChinese, 0x0404);    // a1 = "?樂??"
    a2 = Strings.StrConv("书樂う반", VbStrConv.SimplifiedChinese, 0x0404);     // a2 = "????"

    b1 = Strings.StrConv("书樂う반", VbStrConv.TraditionalChinese, 0x0804);    // b1 = "書樂う?"
    b2 = Strings.StrConv("书樂う반", VbStrConv.SimplifiedChinese, 0x0804);     // b2 = "书乐う?"

    c1 = Strings.StrConv("书樂う반", VbStrConv.TraditionalChinese, 0x0412);    // c1 = "?樂う반"
    c2 = Strings.StrConv("书樂う반", VbStrConv.SimplifiedChinese, 0x0412);     // c2 = "??う반"

    d1 = Strings.StrConv("书樂う반", VbStrConv.TraditionalChinese, 0x0009);    // d1 = "書樂う반"
    d2 = Strings.StrConv("书樂う반", VbStrConv.SimplifiedChinese, 0x0009);     // d2 = "书乐う반"

上面 8 個範例的第一個參數摻雜了簡中、繁中、日文和韓文, 第二個參數區分了轉簡體和轉繁體, 第三個參數是 localeID 的部分, 分別包含了 zh-TW (0x0404), zh-CN (0x0840), ko-KR (0x0412), en (0x0009), 讓我們來仔細觀察一下結果, 一切的玄機都在第三個 localeID 參數身上. 我們先假設第三個參數 localeID 是用來表示來源字串的字集, 所以如果這個假設成立的話..., 來看看結果:

  1. a1: 嗯, 一切如預期的結果, 第一步應該先將 "书樂う반" 轉成符合 zh-TW (0x0404) 的字集, 所以結果是 "?樂??", 然後再根據第二個參數 VbStrConv.TraditionalChinese 結果變成了 "?樂??", 正確!
  2. a2: 第一步同上, 然後再根據第二個參數 VbStrConv.SimplifiedChinese 結果應該要變成 "?乐??", 可是 a2 的結果卻得到了 "????", 不如預期!
  3. b1: 第一步應該先將 "书樂う반" 轉成符合 zh-CN 的字集, 所以結果是 "书樂う?", (簡體字集是有包含繁體形態 "樂" 這個字的), 第二個參數 VbStrConv.TraditionalChinese, 所以結果變成 "書樂う?", 正確!
  4. b2: 正確!
  5. c1: 韓文字集不太了解, 從結果推測韓文的漢字集如果沒有 "书" 這個字的話, 結果應該算是正確的!
  6. c2: 從 c1 的結果本來預期應該得到 "?乐う반", 可是結果卻是 "??う반", 不如預期!
  7. d1: 咦!!! 怎麼會這樣, 完全不如預期, 竟然得到如此漂亮的結果, 本來預期是 4 個 "?" 的!!!
  8. d2: 一樣得到令人搞不清楚為什麼美麗結果!!!

這到底是怎麼一回事? 是假設錯誤嗎? 可是還有什麼別的可能嗎? 為了解開這個謎團, 於是又祭出了殺手工具 "Reflector", 仔細觀察了 Microsoft.VisualBasic.dll 內的程式碼, 終於了解箇中奧秘!

先來看一下 StrConv 方法反向工程之後的一小部分程式碼(還沒到重點, 所以只節錄最後幾行),

image

再來追進 vbLCMapString 看一看, 也是看下半部就行了:

image

橘黃色是和 Encoding 相關的程式碼, 綠色紅色底線的部分是 Win32 API 用來處理字碼轉換的函式, 綠色底線的函式有一個後綴字 A, 而且輸入的參數是 byte[], 而紅色底線部分的函式則沒有後綴字, 輸入的參數是 string.

看到這兒, 答案已經呼之欲出了, 之所以結果會不如預期都是因為 encoding.GetBytes() 和 encoding.GetString() 這兩個方法給弄砸的, 如果可以跳過它們直接叫用底下畫紅線的 UnsafeNativeMethods.LCMapString 的話, 就不會有那些討厭的問號產生了, 那要怎麼樣才能避過那段我們不想要的程式碼呢? 看一下那個底下有畫虛線的部分 "encoding.IsSingleByte", 嗯! 沒錯, 這就是為什麼 d1, d2 的結果這麼令人驚訝的原因了, 因為 en 的 Encoding 就是 SingleByte 所以會直接跳過 Unicode 和 MBCS 互轉的部分, 而直接進行 Unicode 的轉碼, 於是得到美麗的答案, 整個過程分析完畢!

雖然已經知道整個來龍去脈, 但是如果能再了解一下那個神奇的 Win32API: LCMapString 的話, 想必觀念又可以再更清楚一些. 所以我們再來看看 LCMapString 的重點吧! 嗯~~重點在哪兒咧? 以此篇文章的需求 "簡繁轉換" 來看的話, 只有第二個參數 dwMapFlags 值得我們注意, 打開 MSDN 的文件, 透過索引找到 LCMapString 的章節, 我們可以看到以下的內容,

image

針對 Windows NT 4.0 以後的作業系統, Microsoft 已經早就幫程式設計師們準備好了一個現成的系統函式來達成簡繁轉換的工作了(唉! 為什麼沒有早點知道!), 看你是要轉簡體 (LCMAP_SIMPLIFIED_CHINESE), 或是轉繁體 (LCMAP_TRADITIONAL_CHINESE), 只要給個參數, 一切就搞定了, 就是這麼簡單!

 

結論

如果您的需求和我一樣, 只是想把文字內容的簡繁部分轉換, 並不是想轉成 big5 或 gb, 整個輸出入都是 unicode, 而且也不想破壞其他非簡繁文字部分的話, 那麼結論就是照著本篇文章的一開始的 d1, d2 範例呼叫 VB 的 Strings.StrConv 帶上 0x0009 或是其他 SingleByte 字集的 localeID 當成第三個參數就可以啦!!!

如果不想引入 Microsoft.VisualBasic.dll (別問為什麼, 純屬個人偏好) 又想要做到相同的效果, 做法也很簡單, 請參考以下的範例程式碼!!!

public static class ChineseStringUtility
{
    internal const int LOCALE_SYSTEM_DEFAULT = 0x0800;
    internal const int LCMAP_SIMPLIFIED_CHINESE = 0x02000000;
    internal const int LCMAP_TRADITIONAL_CHINESE = 0x04000000;

    [DllImport("kernel32", CharSet = CharSet.Auto, SetLastError = true)]
    internal static extern int LCMapString(int Locale, int dwMapFlags, string lpSrcStr, int cchSrc, [Out] string lpDestStr, int cchDest);

    public static string ToSimplified(string source)
    {
        String target = new String(' ', source.Length);
        int ret = LCMapString(LOCALE_SYSTEM_DEFAULT, LCMAP_SIMPLIFIED_CHINESE, source, source.Length, target, source.Length);
        return target;
    }

    public static string ToTraditional(string source)
    {
        String target = new String(' ', source.Length);
        int ret = LCMapString(LOCALE_SYSTEM_DEFAULT, LCMAP_TRADITIONAL_CHINESE, source, source.Length, target, source.Length);
        return target;
    }
}

2007-12-19

建立 Localized JavaScript

從前在 asp 時代就有這樣子的需求, 那時候是用 Excel 表製作字串對應表, 再透過程式產生各種不同的 JavaScript 檔, 最後再根據需求動態引入不同的 JavaScript 來達成, 其實這個解決方案也還算不錯, 因為 Excel 可以由程式設計師以外的人來進行相關的翻譯工作, 一切 OK 之後, 再透過轉檔程式產生一堆的 JavaScript 即可!

到了 ASP.NET 時代, 透過 System.Web.Extensions.dll 的 ScriptResourceAttribue 將整個動作整合的更好了(但是要做的事情其實差不了多少, 只是比較美而已), 實作的步驟如下:

  1. 建立一個 Class Library Project, 取名為 LocalizingScriptResources, 並刪除那個多餘的 Class1.cs.
  2. 加入 System.Web.dll 和 System.Web.Extensions.dll 參考.
  3. 新增一個 MyResource.resx 資源檔, 並作以下的編輯:
     image
  4. 新增一個 MyScript.js, 將 Build Action 設為 Embedded Resource, 然後寫一個簡單的 function 在裡面, 其中值得注意的是 String1 和 String2 的前綴字 MyNamespace.MyType, 等一下會再遇到.
    image
  5. 為了讓等會兒的範例更清楚, 再補上一個 MyResource.zh-TW.resx, 這次內容用中文的:
    image
  6. 接下來的動作是一切的關鍵, 做錯的話等會兒就看不到效果了. 打開 Properties 底下的 AssemblyInfo.cs, 在 using 底下加入以下兩行:
    [assembly: WebResource("LocalizingScriptResources.MyScript.js", "text/javascript")]
    [assembly: ScriptResource("LocalizingScriptResources.MyScript.js", "LocalizingScriptResources.MyResource", "MyNamespace.MyType")]
    • 第一行的 WebResourceAttribute 是將 MyScript 嵌入 dll 中, 注意第一個參數的名字必須是 Namespace.DotSplittedFolderName.FileName, 因為範例的 MyScript.js 是放在根目錄, 所以名字是 LocalizingScriptResources.MyScript.js, 如果把檔案放在 \F1\F2\MyScript.js 的話, 那名字就必須改成 LocalizingScriptResources.F1.F2.MyScript.js, 目錄的分隔符號要換成 "."
    • 第二行的 ScripteResourceAttribute, 參數一就是和第一行相同的名字, 參數二是 Resource 檔的名字, 命名規則和第一個參數類似, 但是不包含語系的後綴字, 也不包含最後的 .resx 附檔名, 參數三則是要在 JavaScript 中使用名型別名稱, 也就是步驟 5 的 MyNamespace.MyType, 可以取自己想要的名字, 但兩邊要對應.
    • 在這兒先 Build 看看吧, 應該要成功的, 把不小心犯的錯找出來, 順便休息一下!
  7. 接下來準備實驗啦, 加入一個新的 WebSite Project, 並將 LocalizingScriptResources 加入為專案參考, 打開 Default.aspx, 加入一個 ScriptManager, 並在裡面加入一個 Script 參考, 然後再寫一個 pageLoad 方法去呼叫 MyScript.js 裡面的 function.
    <form id="form1" runat="server">
    <div>
        <asp:ScriptManager ID="ScriptManager1" runat="server">
            <Scripts>
                <asp:ScriptReference Assembly="LocalizingScriptResources" Name="LocalizingScriptResources.MyScript.js" />
            </Scripts>
        </asp:ScriptManager>
    </div>
    <script type="text/javascript">
    function pageLoad()
    {
        LocalizedMethod();
    }
    </script>
    </form>
  8. 接下來可以打開 Browser 看看結果, 如果想切換語系的話, 可以在 IE 的 網際網路選項 -> 語言 -> 語言喜好設定 裡調整語言的優先順序, 然後再次瀏覽網頁, 應該就可以了.
  9. 如果想強制切換語系檔的話, 可以直接修改 @Page 的 UICulture 屬性, 試試 en-US, zh-TW 或其他的 Culture name 體驗一下.
    <%@ Page UICulture="zh-TW" Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>

Fiddler 又不能攔到 localhost 了

剛把作業系統換成 Vista 的時候, 就曾經發生 Fiddler 不能攔到 localhost 的 Request 的問題, 後來在網路上找到的答案是說只要在 localhost 後面加個 "." 就可以了, 輕輕鬆鬆就解決了!

可是今天再度使用 Fiddler 的時候, 相同的技巧卻失效了, 畫面上出現的是 Exception Text: 無法連線,因為目標電腦拒絕連線。 ::1:64155, 有圖為證:

image

奇妙的是如果把 "localhost." 換成 "127.0.0.1." 就又可以了, 怎麼可能會有這種事情, 打開 cmd.exe 試著 ping localhost 看看, 果然發現了問題, 如圖, 回應的內容是 "回覆自 ::1: time<1ms":

image

要怎麼解決這個問題咧? 最快的治標方法是用記事本打開 C:\Windows\System32\drivers\etc 目錄底下的 hosts 檔案, 把其中一行 "::1 localhost" 前面加個 "#" 註解掉就行了!

2007-12-18

列舉子資料夾的方法(.NET)

簡單, 就 Directory.GetDirectories() 就好啦, 但是如果要列舉的對象有著為數眾多(比如說有好幾萬)的子資料夾或是檔案的話, 那可有得等了, 而且還要有充足的記憶體供它使用, 因為它的回傳值是 string[], 所以如果有類似的需求的話, 只能另想它法囉!

當下想到的就是 WIN32 API 的 FindFirstFile, FindNextFile 函式, 可是要在 .NET 環境中使用的話, 還是稍稍封裝一下比較好, 所以第一步當然是要準備那些 DllImport 的宣告, 和最煩人的 WIN32_FIND_DATA 資料結構囉, 自己參考文件照樣重新製作一個當然也是可以, 可是如果有現成的話該多好!

先用 Reflector 參考一下 Directory.GetDirectories 是怎麼寫的, 它既然要列舉資料夾, 應該也一定會用到那些 API 才對, 果然! 相關的宣告如下:

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr FindFirstFile(string fileName, [In, Out] WIN32_FIND_DATA data);

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool FindNextFile(IntPtr hndFindFile, [In, Out, MarshalAs(UnmanagedType.LPStruct)] WIN32_FIND_DATA lpFindFileData);

[DllImport("kernel32.dll")]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
private static extern bool FindClose(IntPtr handle);
[Serializable, StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto), BestFitMapping(false)]
private class WIN32_FIND_DATA
{
    internal int dwFileAttributes;
    internal int ftCreationTime_dwLowDateTime;
    internal int ftCreationTime_dwHighDateTime;
    internal int ftLastAccessTime_dwLowDateTime;
    internal int ftLastAccessTime_dwHighDateTime;
    internal int ftLastWriteTime_dwLowDateTime;
    internal int ftLastWriteTime_dwHighDateTime;
    internal int nFileSizeHigh;
    internal int nFileSizeLow;
    internal int dwReserved0;
    internal int dwReserved1;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
    internal string cFileName;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
    internal string cAlternateFileName;
}

接下來要就要自己實作一個回傳 IEnumerable 的方法, 每列舉一次只回傳一筆結果, 既可避免等待的問題, 又可以隨時停止, 如果在 .NET 1.x 的時代, 要實作一個 IEnumerable 比較麻煩, 但是 .NET 2.0 因為有 yield 這個新元素可以使用, 所以問題就簡化到一個不可思議的地步, 所以先實作一個內部使用的 internalGetFileDirectoryNames 的方法, 如下:

private const int FILE_ATTRIBUTE_DIRECTORY = 0x10;
private static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
private static IEnumerable internalGetFileDirectoryNames(string path, string searchPattern, bool includeFiles, bool includeDirs, SearchOption searchOption)
{
    WIN32_FIND_DATA data = new WIN32_FIND_DATA();
    IntPtr findHandle = FindFirstFile(Path.Combine(path, searchPattern), data);

    if (findHandle == INVALID_HANDLE_VALUE) yield break;

    try
    {
        List<string> dirs = new List<string>();
        do
        {
            bool isDirectory = (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
            if (data.cFileName != "." && data.cFileName != "..")
            {
                if (isDirectory && searchOption == SearchOption.AllDirectories) dirs.Add(data.cFileName);

                if ((isDirectory && includeDirs) || (!isDirectory && includeFiles))
                {
                    yield return Path.Combine(path, data.cFileName);
                }
            }
        }
        while (FindNextFile(findHandle, data));

        foreach (string dir in dirs)
        {
            foreach (string f in internalGetFileDirectoryNames(Path.Combine(path, dir), searchPattern, includeFiles, includeDirs, searchOption))
                yield return Path.Combine(path, f);
        }
    }
    finally
    {
        bool r = FindClose(findHandle);
        System.Diagnostics.Debug.Assert(r);
    }
}

最後, 模擬原生的 Directory.GetFiles, Directory.GetDirectories, Directory.GetFileSystemEntries 函式簽名, 自己 overload 一下就搞定啦, 以下列出最多屬性的函式宣告:

public static IEnumerable GetFiles(string path, string searchPattern, SearchOption searchOption)
{
    return internalGetFileDirectoryNames(path, searchPattern, true, false, searchOption);
}
public static IEnumerable GetDirectories(string path, string searchPattern, SearchOption searchOption)
{
    return internalGetFileDirectoryNames(path, searchPattern, false, true, searchOption);
}
public static IEnumerable GetFileSystemEntries(string path, string searchPattern, SearchOption searchOption)
{
    return internalGetFileDirectoryNames(path, searchPattern, true, true, searchOption);
}

完成啦! 完整的程式碼在這裡!

2007-12-12

導入 Team Foundation Server

在開發團隊中導入 TFS, 配合 Visual Studio Team Explorer, 除了要習慣那個不太好用, 功能又有點陽春的 Source Control Explorer 之外, 其實過程還順滿平順的(以前使用的 SVN Server 搭配 TortoiseSVN 雖然沒有一個良好的 Item Tracking 機制, 但在 Source Code Control 上還算滿好用的), 而且 TFS 還內建了整合性超高的 Item Tracking 功能, 對軟體開發來說, 實在是一大福音! 雖然有人說可以使用 Bug Tracking System 來達到類似的需求, 但因為維護成本和教育訓練等考量, 到最後還是選擇放棄, 只專心做好 Source Control.

在開發團隊順利導入 TFS 之後, 下一步就是擴展到其他的部門, 讓大家彼此間的溝通能夠更為透明, 而且方便追蹤, 可是如果要其他非 IT 部門使用 Visual Studio 似乎有點太過份, 所以一直以來都是使用 Team Plain 當做其他部門進入 TFS 的入口, 經過簡單的教育訓練之後, 發現接受度還滿不錯的, 終於可以把整個軟體開發生命週期, 從訪談, 產生需求, 風險管理, 工作項目建立, Bug 記錄, QoS 管理等等, 通通都在 TFS 中一起管理.

2007-11-30

Visual Studio 2008 在 Vista x64 上不能 Edit and Continue?

Visual Studio 在 x64 的系上不支援 Edit and Continue(E&C)? 真的嗎?

image

今天在 x64 Vista 上的 VS2008 要 debug 程式的時候, 一直被警告必須重新編譯程式, 原本以為是因為 lambda expression 或是 anonymous function 的關係, 後來寫了一個更簡單的類別測試了一下, 發現還是不行, 只好向 Google 求助!

原來是 64-bit CLR 不支援 E&C, 但是只要編譯時選擇 x86 平台的話, 就可以再啟動 E&C 的功能囉!!

怎麼設定呢? 在 Project 上點右鍵, Properties/Build, 把 Platform Target 設成 x86 就行啦!

image

2007-11-20

Visual Studio 2008 正式登場

經過漫長的等待, Microsoft 終於在 11/19 正式將 Visual Studio 2008 以及 .NET Framework 3.5 交付 RTM, 新增多達超過 250 個的功能, 包含連 Visual Studio Express 也同步登場, 有興趣的人趕快去 MSDN 下載吧!

消息來源: http://msdn2.microsoft.com/en-us/vstudio/default.aspx

2007-11-17

用 JavaScript 存取 Firefox 剪貼簿

Firefox 預設是不能用 JavaScript 存取系統剪貼簿(Clipboard)的, 如果想要開放這項功能, 要改 Fifefox 的設定才行。

  1. 先在網址列輸入 about:config。
  2. 然後找到 signed.applets.codebase_principal_support, 把它設為 true 就行了。
  3. 然後再把以下的 code 找個適當的地方放, 然後就可以呼叫 CopyToClipboard("your text....") 把字串複製到剪貼篿啦!

值得注意的是在每次呼叫的時候, Firefox 會彈出一個對話視窗詢問是否允許存取, 要按 "是" 才行!

secdialog

function CopyToClipboard(copytext)
{
	if (window.clipboardData)
	{
		window.clipboardData.setData('Text', copytext);
	}
	else if (window.netscape)
	{
		netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');

		var clip = Components.classes['@mozilla.org/widget/clipboard;1'].createInstance(Components.interfaces.nsIClipboard);
		if (!clip) return;

		var trans = Components.classes['@mozilla.org/widget/transferable;1'].createInstance(Components.interfaces.nsITransferable);
		if (!trans) return;

		var str = Components.classes['@mozilla.org/supports-string;1'].createInstance(Components.interfaces.nsISupportsString);
		str.data=copytext;

		trans.addDataFlavor('text/unicode');
		trans.setTransferData('text/unicode',str,copytext.length*2);

		var clipid=Components.interfaces.nsIClipboard;
		if (!clipid) return false;

		clip.setData(trans,null,clipid.kGlobalClipboard);
	}
	else
	{
		return false;
	}
	return false;

}

2007-11-13

整合家中的遙控器: SONY RM-VL600


隨著客廳的視聽設備一件一件的增加(電視, DVD, 擴大機, TIVO, XBOX360), 遙控器的數量也就跟著變多, 想要享受比較好的聲光效果, 就必須同時操控 3 隻以上的遙控器, 實在是很麻煩, 一直以來就希望能有一個解決方案來改善這樣的狀況(曾經想用 PDA 來取代遙控器, 但是想也知道, 手感及操控性就是差很多)。

曾經有朋友介紹一隻羅技的遙控器(Harmony 880), 上網查了一下, 功能超強, 還有顯示螢幕而且可程式化 但是價位有點高, 而且還有充電座, 感覺像無線電話一樣, 應該挺耗電的, 想想覺得不太適合, 所以就放棄了, 時間久了也就忘了這回事。

前幾天不小心看到網友在討論 SONY 的 RM-VL600, 看了之後覺得價格合理(在 Y拍 只要 NT $890 含運), 功能也很不錯(最重要的就是學習功能啦), 所以就敗了一隻回家, 實際使用之後, 覺得很滿意(以 890 的價格來說), 手感很好, 外觀也很有質感, 而且還提供了 4 組巨集鍵, 可以記住連續動作, 一次就可以把所有相關的電器一次打開, 不用自己一個一個來, 實在是太方便了, 所以從此以後客廳的電器就只要一隻遙控器就行囉~~~

相關參考: http://ying.homedns.org/wp/2007/09/268/

2007-11-09

Email 中的 html 附件在某些軟體中會直接顯示內容

相信大多數的程式設計師都寫過寄信的程式, 而些其中一定會有要夾帶附件的情形! 幾天前有個客戶提出了一個問題, 當然這個問題在我們這裡都不會發生(所有的程式都是這樣, 只有在你那兒會有問題, 在我這兒都是好的)!

問題的內容大概是說客戶在打開由系統寄出的 mail 時, 會看到一堆亂碼, 而且附件檔案不見了! 怎麼會這樣咧? 我們內部的測試人員都說沒有這樣的情形啊! 深入了解一下, 才知道原來客戶的郵件軟體是 Notes(又是 Notes), 而他們所看到的亂碼其實是一個格式為 html 的附件, 只不過在 Notes 中會把 html 附件的內容直接秀在畫面上, 然後那份 html 的編碼又和郵件內容的編碼不同, 然後就造成這樣的結果啦!!

既然知道了問題是怎麼發生的, 就來找解決的方法吧! 先用 Outlook 寄出同一份附件檔試看看, 咦~~怎麼附件乖乖的在他應該在的位置咧? 那就很明顯一定是郵件內有某些檔頭不一樣的關係, 把兩份郵件的原始碼稍稍的比較了一下, 解答出現了:

mailheader

所以解決的方法就是把 Attachment 的 ContentDisposition.DispositionType 設成 System.Net.Mime.DispositionTypeNames.Attachment 之後再加入到 MailMessage 中就可以啦!!

Attachment data = new Attachment(filename);
data.ContentDisposition.DispositionType = DispositionTypeNames.Attachment;

2007-10-08

VMWare ESX Server 彼此之間不能 scp 的問題

今天在整理 ESX 上面的虛擬機器, 想要在某台 esx1 上面用 scp 的方式把另一台 esx2 的檔案 copy 過來, 一直發生 Connection refused 的錯誤, 可是從我自己的 pc 不管是 scp 或是 ssh 到 esx1 或是 esx2 都沒有問題, 只好又向谷大哥求救, 才知道原來在 ESX Server 上有一個設定叫 sshClient 要先開啟, 才能夠讓 esx hosts 之間彼此互相連線, 如圖:

image

如果沒有 UI 的話, 也可以用指令 esxcfg-firewall -e sshClient 達到同樣的效果!

2007-10-07

.NET 類別庫的原始碼釋出

ScottGu 在他的 Blog 上說 .NET 的原始碼包含 BCL, ASP.NET, Windows Forms, ADO.NET, XML 和 WPF (接下來還有 WCF, Wordflow, LINQ) 將會和 .NET 3.5 以及 VS2008 一起釋出。

剛看到這個標題的時候本來沒什麼感覺, 因為 Reflector 就可以做到這件事了, 雖然有些程式碼編成 IL 之後會和原始程式有些出入, 但是已經可以看出 8, 9 成的邏輯了, 可是再往下繼續閱讀之後, 才知道原來不只是這樣!!

以前在使用 Delphi 開發程式的時候, 最令我愛不釋手的特色之一就是不管在設計時期或是執行時期都可以直接進入原始程式碼觀看使用到的類別庫的內容和註解 (雖然不是全部的類別, 但也足夠了)! 後來在使用 Eclipse 撰寫 Java 程式的時候, 只要把用到的 source code 下載回來, 也可以在 IDE 環境中做好相關的設定之後達到和 Delphi 一樣的效果! 有了這項功能, 除了可以了解那些類別的設計哲學之外, 更有助於釐清一些從外表看不出來 (像是 bug 之類) 的秘密!

本來想說這項功能應該是不會在 Microsoft 的產品中出現的, 沒想到 ScottGu 竟然宣布將會在 VS2008 加入這項功能, 並且會在需要的時候下載正確版本的原始程式碼, 不勞 Develper 動手, 的確符合 Microsoft 貼心的一貫作法, 真是令人期待!! 真相圖如下: (2 張就足以說明一切了!)

設定畫面

參考: Releasing the Source Code for the .NET Framework Libraries

2007-10-05

如何讓 TeamBuild 的 BuildLog.txt 顯示更多的資訊

相信如果有在使用 Team System 的人, 應該多少都知道可以建立 TeamBuild 讓建置的工作自動化, 但是也一定會發生一種令人沮喪的情形, 就是任何人 Get 到本機都能 Build, 可是 TeamBuild 就是不會過, 這都是因為 TeamBuild 的建置流程並不完全如我們所想像, 所以 BuildLog.txt 就成為找問題的重要線索了!

習慣看 Visual Studio Output 視窗的人(很多人都不看), 都應該知道在 Build 專案的時候, 可以在從它看到很多訊息, 雖然 Error List 視窗的結果比較美觀, 但是有時候它會保留著之前的錯誤, 就可能會誤導開發人員 Debug 的方向, 所以建議大家如果看不懂 Error List 裡面的訊息, 就找 Output 視窗吧!!

回到正題, 如果在 IDE 環境中, 想要讓 Output 視窗顯示更多更詳細的資訊, 可以從 [Tools]->[Options]->[Projects and Solutions]->[Build and Run]->[MSBuild project build output verbosity] 調整, 如下圖:

image

但是如果希望調整 Team Build 的 BuildLog 又該怎麼辦呢? 在 Source Control 上會有一個 TeamBuildTypes 的目錄, 裡面會有所有已建立的 Build, 每一個 Build 目錄中會有一個 TFSBuild.rsp 檔案, 這個檔案是讓你用來傳一些參數給 MSBuild.exe 程式的, 所以如果想要讓輸出的 BuildLog.txt 更豐富的話, 就先把它 Check Out 下來並加上一行 /v:diag 就可以了, 如下: (改好要記得 Check In 回去才會生效!)

# This is a response file for MSBuild
# Add custom MSBuild command line options in this file
/v:diag

附註: /v:diag 會產生非常非常多的 log 資訊, 如果覺得太多的話, 可以試著把 diag 換成其他的參數, 包括 q[uite], m[inimal], n[ormal], d[etailed] 和最詳細的 diag[nostic]

2007-10-04

Vista 連線網芳和 Samba 的解決方式

Vista 預設裝好之後, 網路共用部分的功能是被關閉的, 想要讓別人可以連到自己的電腦, 必須自己改變一些設才行:

1. 開始->網路->滑鼠右鍵->內容
vista01

2. 啟動[網路探索], [檔案分享權限設定], [以密碼保護的共用]
vista02

這樣子別人就可以看到自己了!

[Samba 篇]

連線一般的 Windows 分享都沒什麼問題, 可是如果要連線用 Samba 架的伺服器, 就會發生無法驗證的問題, 上網 Google 了一下, 找到這篇寫的很詳細!

http://www.builderau.com.au/blogs/codemonkeybusiness/viewblogpost.htm?p=339270746

簡單記一下步驟:
1. 在命令提示字元下輸入 secpol.msc 開啟[本機安全性原則]
2. 選到[本機原則]/[安全性選項], 將[網路安全性: LAN Manager 驗證層級]從原來的[只傳送 NTLMv2 回應]改為[傳送 LM 和 NTLM - 如有交涉,使用 NTMLv2 工作階段安全性]

這樣子應該就可以連到 Samba 伺服器了!! 真是麻煩的 Vista!!

後記: 原本以為從此就可以過著幸福快樂的日子了, 沒想到遇到了 Vista Home Basic 之後, 發現它沒有 secpol.msc 可以用, 真是@!#@$, 不得已只好再向谷先生請教, 終於找到解答, 但是要修改到機碼, 所以要小心點!

步驟如下:
1. 在命令提示字元下輸入 regedit
2. 找到 HKLM\SYSTEM\CurrentControlSet\Control\Lsa
3. 將 LmCompatibilityLevel 從 3 改為 1
搞定!!

註: LmCompatibilityLevel 數字的意義
0=Send LM & NTLM responses  (never uses NTLMv2)
1=Send LM & NTLM - use NTLMv2 session security if negotiated
2=Send NTLM response only, use NTLMv2 if server supports it.
3=Send NTLMv2 response only, if DC accept LM, NTLM and NTLMv2 auth, use NTLMv2 security if supported.
4=Send NTLMv2 response only, if DC refuse LM, accept NTLM or NTLMv2 auth, use NTLMv2 security if supported.
5=Send NTLMv2 response only, if DC,refuse LM & NTLM and only accept NTLMv2 auth, use NTLMv2 security if supported.

vista03

2007-10-03

XSL: 如何計算節點深度

又是一個常用的任務, 簡單, 但是會忘!

<xsl:value-of select="count(ancestor::node())" />

2007-10-02

每次建置 Setup Project 就會跳出 Installer 安裝畫面 - VS2003

今天把一個 VS2003 的程式拿出來做一些修改, 改完之後準備建置 Setup 程式的時候, 只要一 build 就會跳出一個 VS2003 的安裝畫面, 然後就會出現錯誤畫面, 安裝程序倒回, 再前進, 錯誤, 再倒回.....

可是只要把安裝取消, 就一切又順利進行下去, 雖然是無傷大雅, 只要按個取消就能 build 好, 可是好奇心驅使, 就又稍稍查了一下"事件檢視器", 嗯! 有一個警告, 把內容丟給 Google, 找到了!!

只要重新註冊 mergemod.dll 這個 com 元件就行啦!!

cd "C:\Program Files\Common Files\Microsoft Shared\MSI Tools\"
regsvr32 /u mergemod.dll
regsvr32 mergemod.dll

搞定!

2007-09-29

過時的 System.Net.WebProxy.GetDefaultProxy()

今天在把一個有用到 System.Net.WebProxy.GetDefaultProxy() 類別的程式從 .NET 1.1 升級到 .NET 2.0, 編譯器警告說這個方法已經過時, 訊息是:

This method has been deprecated. Please use the proxy selected for you by default. http://go.microsoft.com/fwlink/?linkid=14202

奇怪的是, 它並沒有像其他的警告訊息會告訢我們一個取代的方法, 怎麼辦呢? 趕快打開 Reflector 查一下, 原來該方法是呼叫一個未開放的建構子 internal WebProxy(bool enableAutoproxy) 來取得系統預設的 Proxy 設定! 嗯? 難道要用 Reflection 的方式去呼叫嗎? 那樣子就太遜了吧!!

馬上想到之前也有一個類似的過時屬性 GlobalProxySelection.Select, .NET 2.0 建議改成 WebRequest.DefaultProxy, 所以就轉向 WebRequest 去試著尋找答案, 果然找到一個 WebRequest.GetSystemWebProxy() 的方法, 看名字就覺得是它了, 但還是要再確認一下, 稍微用 Reflector 再追了一下, 果然看到 new WebProxy(true) 出現在 InternalGetSystemWebProxy() 方法中! 肯定是它了!

搞定!! (真是的, 既然要改變作法, 說明就該寫清楚一點嘛, 還要讓人自己找!)

2007-09-26

Server name 變更後, Reporting Service 會出問題!

今天在升級一台 SQL2005 到 SP2 的時候, 出現找不到 Reporting Service Instance 的錯誤, 仔細看了一下, 才發現原來是因為 server name 曾經改過(以前 SQL2000 也發生過類似的問題), 雖然 Database Engine 部分還是可以連得到, 可是 Reporting Service 就沒那麼聰明了, Google 了一下, 很快的找到了解決方法:

  1. 修改 sys.sysservers 的資料, 以符合目前的主機名稱 sp_dropserver 'old_server_name' sp_addserver 'new_server_name'
  2. 修改 rsreportserver.config 的 UrlRoot 讓檔案預設的位置在 %ProgramFiles%\Microsoft SQL Server\MSSQL.n\Reporting Services\ReportingServer 底下(MSSQL.n 的 n 會視各機器不同, 我的是 MSSQL.3)
  3. 開啟 程式集->[Microsoft SQL Server 2005]->[Configuration Tools]->[Reporting Services Configuration], 點選 Database Setup, 修改 Server Name 成新的名稱
  4. 重新啟動 SQL Server Reporting Services
  5. 再次開啟 Reporting Services Configuration, 點選 Encryption Keys, 先 Delete 舊的 Key, 再按 Change 重新建立一組新的 Key.
搞定!

2007-09-03

互動式 Office 2003 對 Office 2007 命令參照指南

對於 Office 2007 新的 Ribbon 介面雖然覺得還滿可愛的, 但是常常就是會有找不到功能的困擾, 今天不小心發現了 Microsoft 提供的一個說明網頁, 以互動式的方式教你怎麼找到以前在 Office 2003 的命令, 還挺有趣的, 竟然會有這樣子的教學方式, 應該好好學習學習!! Excel: http://office.microsoft.com/zh-tw/excel/HA101491511028.aspx Word: http://office.microsoft.com/zh-tw/word/HA100744321028.aspx PowerPoint: http://office.microsoft.com/zh-tw/powerpoint/HA101490761028.aspx

2007-08-18

Silverlight 1.0 和 1.1 的差別

Silverlight 1.0 有些什麼東西都還沒弄清楚, 1.1 又跟著冒出來, 兩者間的差異是什麼呢? 剛好看到官方網站上的簡介, 趕快記起來! http://silverlight.net/GetStarted/overview.aspx

2007-08-09

嫁給我好嗎?

今天看到黃品源在康熙來了節目上自彈自唱了一首並未發表的歌, 歌名好像叫做 嫁給我好嗎, 聽說他在婚禮上有唱這首歌, 真得很適合那種情境!! 因為覺得很好聽, 一時技癢就拿起吉他跟著抓了一下, 順便記錄下來! 不知道有沒有 mp3 可以抓得到??

詞/曲: 黃品源  D 調

D   #Ddim Em A          D
嫁給我    好嗎  我的心早已經屬於妳

D   #Ddim Em A          D
嫁給我    好嗎  今生今世妳是我的唯一

D   #Ddim Em A            D
嫁給你    好嗎  我要的不只這些甜言蜜語

D   #Ddim Em A            D
嫁給你    好嗎  妳是否永遠記得說過的話

Bm      #Fm   G    A   D
期待已久的緣分  即將要變成永恆

      G   A              D
編織著美麗的夢  是否能愛我到永遠

      Bm    #Fm   G    A   D
請相信我對妳的真誠  決定要伴妳一生

      Bm          G
別說是天長地久  只要真心愛我

      G      A        D
只要妳輕輕點個頭  我們就長相廝守

D   #Ddim Em A            D
嫁給我    好嗎  不會再讓妳孤單讓妳受傷

D   #Ddim Em A          D
嫁給我    好嗎  寂寞的心將會有一個家
----- #Ddim 怎麼按, 附張圖好了, 以免要用的時候突然忘記!!

2007-08-08

遠端桌面到 Vista Home Premium 版

Vista Home Premium 版本預設是不支援遠端桌面的, 雖說它可能有什麼商業上的考量, 但是對於習慣使用遠端桌面的人來說, 實在是太不方便了, 當然也可以裝個 vnc 之類的 server 來遠端搖控, 但是總覺得效能上還是差了一點, 最好是能把隱藏在 Home Premium 版內的功能重新打開來比較好. Google 一下, 果然已經有人提出解決的辦法了, 親自實驗之後證實是可以的, 而且步驟還超簡單, 只要 [下載] -> [解壓] -> [以 Administrator 的身份執行 命令提示字元] -> [執行 premium.bat 檔] 就搞定了!!

參考: http://portal.tonychan.org/Default.aspx?tabid=58&EntryID=123

C# 3.0 筆記: Automatic Properties, Object Initializers, Collection Initializers

1. Automatic Properties 2. Object Initializers 3. Collection Initializers 1. Automatic Properties

//=== BEFORE ===
public class Person {
    private string _name;
    private int _age;

    public string Name {
        get { return _name; }
        set { _name = value; }
    }

    public int Age {
        get { return _age; }
        set { _age = value; }
    }
}
//=== AFTER ===
public class Person {
    public string Name { get; set; }
    public int Age { get; set; }
}
2. Object Initializers
//=== BEFORE ===
Person p = new Person();
p.Name = "John";
p.Age = 30;
//=== AFTER ===
Person p = new Person { Name = "John", Age = 30 };
3. Collection Initializers
//=== Way 1 ===
List ps = new List();

ps.Add(new Person { Name = "John", Age = 30 });
ps.Add(new Person { Name = "Mary", Age = 25 });
//=== Way 2 ===
List ps = new List {
    new Person { Name = "John", Age = 30 },
    new Person { Name = "Mary", Age = 25 };

2007-08-04

支援 rdesktop -x 功能的 gnome-rdp

在 Ubuntu 的遠端連線工具裡, 預設的是 tsclient, 功能相當不錯, 但是在管理上稍有不足, 所以我都是使用 gnome-rdp 這個套件來管理常用的一些連線, 但是不管是原來的 tsclient 或是 gnome-rdp 都沒有開放設定 rdesktop 的 -x 參數, 可是我又希望連線時能夠看到遠端的桌面背景, 於是就自己下載 source 稍稍改了一下, 做了一個新的版本!! 修改的功能有:

  1. 新增 RDP5 Experience 選項(modem,broadband,lan), 配合 rdesktop 的 -x 選項, 使遠端連線時可顯示桌面背景.
  2. 關閉主視窗大小改變時, 會自動置中造成視窗跳動的問題.
使用方式: 下載 gnome-rdp.exe 替換掉原來在 /usr/lib/gnome-rdp/ 目錄底下的程式就可以了!
想自己動手做的話, 可以照著以下步驟進行:
$ apt-get source gnome-rdp
$ cd gnome-rdp-0.2.2
$ dpkg-buildpackage -rfakeroot -uc -b
這時候會先做一個小 patch (把原來的 xvncviewer 換成 xtightvncviewer), 再開始進行編譯程式, 然後會看到一個很笨的錯誤, 先不要理它, 這裡我們只是要產生一些 make file 的配置檔!(表示這個源碼之前沒有被編譯過, 否則應該不會有這種錯誤)
./OptionsDialog.cs(58,93): error CS0023: The `+' operator cannot be applied to operand of type `string'
如果編譯中出現缺少開發套件的話, 可以先執行
$ sudo apt-get build-dep gnome-rdp
$ sudo apt-get install fakeroot # 以非 root 身份進行編譯時所需的套件
這樣會安裝所有建置 gnome-rdp 所需要的套件庫, 和 fakeroot 套件
接下來下載 gnome-rdp-changedfiles.tgz, 解壓並覆蓋掉原來的檔案(包含上面那個錯誤的修正)!
$ cd ..
$ wget http://bigsan.chen.googlepages.com/gnome-rdp-changedfiles.tgz
$ tar zxvf gnome-rdp-changedfiles.tar.gz
$ cd gnome-rdp-0.2.2
$ dpkg-buildpackage -rfakeroot -uc -b
這時候會產生一個 ../gnome-rdp_0.2.2-0ubuntu2_i386.deb 檔案, 可以自行安裝囉! $ cd .. && dpkg -i gnome-rdp_0.2.2-0ubuntu2_i386.deb
附帶一提的是 gnome-rdp 的資料是用 Sqlite 來管理的, 因為有改到資料庫的結構, 所以如果原來有建立站台資料的話, 就必須先刪除 ~/.gnome-rdp.db, 然後再執行 gnome-rdp 的時候, 資料庫就會重新建立了! 如果不想讓原來的資料消失的話, 就得自行更改資料庫的結構及資料, 指令如下:
$ sqlite ~/.gnome-rdp.db # for sqlite version 2
$ sqlite3 ~/.gnome-rdp.db # for sqlite version 3
sqlite> .tables
#如果看到 session 和 version 兩張 table 的話, 表示沒問題, 否則就是 sqlite 版本不對
sqlite> ALTER TABLE session ADD COLUMN rdp5experience INTEGER;
sqlite> UPDATE session SET rdp5experience = 0;
sqlite> .quit

2007-08-02

Visual Studio 2008 Debugger Visualizer

看到一些很棒的 debugger visualizer, 以後一定會用到, 先記起來! WPF Tree Debugger Visualizer LINQ to SQL Debug Visualizer from ScottGu's Blog 相關文章: Create a Debugger Visualizer in 10 Lines of Code By Tomer Noy Useful add-ons (plugins) for Visual Studio 2005

2007-08-01

新版 Web Development Helper

這次發佈的 0.8.5.0 版, 修正了在 Vista 中的一個小問題, 而且還多加入一個 Script Class Browsing 工具(如下圖), 不過這個小工具僅支援遵循 Microsoft ASP.NET AJAX Pattern 所開發的 JavaScript, 雖然如此, 還是很不錯!! 參考: nikhilk.net

設定 IMEX=1 透過 OleDb 讀取 Excel 仍然出現 null 值的問題

之前在使用 OleDb 讀取 Excel 時, 發生有些欄位雖然有值, 但是讀出來卻是 Null 的問題, 上網查了一下, 說是在連線字串中加入 Extended Properties, 將 IMEX 設為 1, 就可以強迫 OleDb 的 driver 將內容當成文字讀取, 以避免發生型別錯誤而回傳 null. 如下

Provider=Microsoft.Jet.OLEDB.4.0;Data Source="C:\Data.xls";Extended Properties="Excel 8.0;HDR=Yes;IMEX=1;
但是後來發現有些資料可以成功, 有些不行, 但是如果把資料列的順序作一下改變的話(把非數字的資料放到比較前面的幾列), 就又可以順利讀取, 真是怪到極點, 於是再去問了一下 Google, 終於找到問題的源頭... 原來是 OleDb Driver 的問題, 在機碼 HKLM\Software\Microsoft\Jet\4.0\Engines\Excel 有一個 TypeGuessRows 值, 預設是 8, 表示會先讀取前 8 列來決定每一個欄位的型態, 所以如果前 8 列的資料都是數字, 到了第 9 列以後出現的文字資料都會變成 null, 真是聰明得令人哭笑不得..... 所以如果要解決這個問題, 只要把 TypeGuessRows 機碼值改成 0, 就可以解這個問題了!

2007-07-27

在 Ubuntu 中讀寫 NTFS 檔案系統

安裝 Driver 和管理工具:

sudo apt-get install ntfs-3g ntfs-config
掛載指令:
sudo mount -t ntfs-3g /dev/sda1 /media/disk1 -o locale=zh_TW.utf8,umask=0022,fmask=0133,dmask=0022
fstab 設定:
/dev/sda1 /media/disk1 ntfs-3g locale=zh_TW.UTF-8,umask=0022,fmask=0133,dmask=0022 0 0

2007-07-21

讓 Ubuntu 的 Firefox 也能瀏覽 tiff 檔

趕快安裝 mozilla tiff plugin 吧! 下載 mozilla-tiff-plugin-0.3_i386.deb 之後, double click 安裝或是用指令 dpkg -i mozilla-tiff-plugin-0.3_i386.deb 就可以啦~~~!

把 Firefox 變身成 IE7

先安裝 Vista-aero 佈景主題, 改變佈景主題之後雖然長得很像了, 可是我覺得上方的選單列很礙眼, 所以就再安裝一個 Hide menubar 的 extension, 順便再到 [編輯]->[偏好設定]->[分頁], 把 [總是顯示分頁工具列] 勾起來, 嗯!! 這樣子像多了!!

2007-07-19

在 vim 中編輯不同編碼的文件

今天用 gvim 開啟一個 big5 編碼的文字檔時, 畫面上呈現的全是亂碼, 雖然知道是編碼的問題, 可是也不知道該怎麼辦. 問了一下 google, 很快的就找到了解決方法! :e ++enc=big5 % :e 代表 edit, 表示要對檔案進行編輯的動作, 最後接的是檔名, % 表示目前的檔名 ++enc=xxx 代表以 xxx 編碼開啟檔案 詳細說明可以先進 vim 之後, 再輸入 :help :e 或是 :help multibyte

在 Ubuntu 上使用 Hamachi

什麼是 Hamachi, 簡單來說就是一個簡單使用又安全的 VPN 軟體, 想知道更多的話, 就上網 Google 一下吧! 回到主題, 首先到 LogMeIn 下載 Linux 版的程式, 目前的版本是 0.9.9.9-20, 檔名是 hamachi-0.9.9.9-20-lnx.tar.gz 下一步就是解開並安裝囉, 過程也很簡單

tar zxvf hamachi-0.9.9.9-20-lnx.tar.gz
cd zxvf hamachi-0.9.9.9-20-lnx
sudo make install

它會進行編譯, 然後安裝兩個檔案和一個 symlink 到系統中, 如下:

/usr/bin/hamachi
/usr/bin/hamachi-init -> /usr/bin/hamachi
/sbin/tuncfg

接下來要先建立一組金鑰
hamachi-init # 這會在自己的家目錄建立一個 .hamachi 的目錄和加密用的金鑰, 只在第一次執行就好了. 接下來執行以下指令
sudo /sbin/tuncfg # 這是負責幫 hamachi 建立虛擬網卡用的, 它會在需要的時候自行建立.
hamachi start
hamachi login
hamachi join # 是你要加入的網路名稱
hamachi go-online

以後要進行連線的時候就用以下的指令:
sudo /sbin/tuncfg
hamachi start
hamachi login
hamachi go-online
搞定, 接下來就可以建立自己專用的虛擬網路囉!!

ps: 如果覺得命令列用起來不爽的話, 可以下載 gHamachi 來用, 有 GTK1.2 和 GTK2 的版本, 如果你有用 xgl, compiz 或 beryl 的話, 可以下載最新的 0.8.1 beta 版喔!

2007-07-18

Howto: mount smbfs

基本用法: mount -t smbfs -o username=DOMAIN\\Username,password=XXX,iocharset=utf8,codepage=cp950,uid=1000,gid=1000 //winserver/sharefolder /mnt/localfolder

這樣子會在命令列顯示出密碼, 不小心會被別人 ps 看到. 如果想要隱藏密碼的話, 可以省略密碼選項, 這樣就會提示輸入密碼了. 如果又想直接掛載, 又不想輸入密碼, 也不想被別人不小心看到, 那就自己建立一個密碼檔, 假設檔名叫做 smbfs_passwd, 格式如下:

username = <value>
password = <value>

 然後把命令列上的 username=XXX,password=XXX 改成 credentials=smbfs_passwd 就可以了, 像底下這樣: mount -t smbfs -o credentials=smbfs_passwd,iocharset=utf8,codepage=cp950,uid=1000,gid=1000 //winserver/sharefolder /mnt/localfolder

 如果希望開機自動掛載的話,就在 /etc/fstab 下加入下面這行
//winserver/sharefolder /mnt/localfolder smbfs auto,credentials=passwdfile,iocharset=utf8,codepage=cp950,uid=1000,gid=1000 0 0

 上面的設定要直接寫成一行, 其中的 iocharset,codepage,uid,gid 依需要修改就可以了!!

2007-07-17

在 Ubuntu 上安裝 Screenlets

  1. 新增套件庫 echo deb http://hendrik.kaju.pri.ee/ubuntu feisty screenlets | sudo tee -a /etc/apt/sources.list
  2. 新增 key 並更新套件列表 wget http://hendrik.kaju.pri.ee/ubuntu/F854AFD7.gpg -O- | sudo apt-key add - && sudo apt-get update
  3. 安裝 screenlets sudo apt-get install screenlets
  4. 執行 screenlets-tray & 這時會在右上的工具列中會出現一個圖示, 按右鍵叫出選單, 點 settings, 然後新增自己喜歡的小工具到桌面上吧!

讓 acroread 可以看中文文件

  1. 先到 http://www.adobe.com/products/acrobat/acrrasianfontpack.html 下載中文字型套件 (我下載的是 FontPack708_cht_i386-linux.tar.gz)
  2. tar zxvf FontPack708_cht_i386-linux.tar.gz
  3. cd CHTKIT ; ./INSTALL (記得問到原 acroread 安裝路徑時, 要指到對的位置去, 預設是 /usr/lib/Adobe/Acrobat7.0)
搞定!

ps: 如果想要在 Firefox 內使用 acroread 開啟 pdf 的話, 再多裝一個 plugin 就行了, sudo apt-get install mozilla-acroread.
ps2: 如果想要讓右鍵功能表出現 Adobe Reader 或是讓 pdf 預設用 Adobe Reader 開啟的話, 可以參考 自定文件開啟時右鍵選單的程式列表和預設開啟的程式

2007-07-16

在 Ubuntu 7.04 使用 HUAWEI E220 無線 3G 上網

整理自 Ubuntu 正體中文站 勝仔 兄的大作!!

在開始之前, 要先確定已經把 sim 卡 PIN 驗證關掉. 可以在 E220 內附的 Windows 軟體中設定.

1. 連至 https://forge.vodafonebetavine.net/frs/?group_id=12 下載驅動程式 vodafone-mobile-connect-card-driver-for-linux_0.9.7.3_feisty_all.deb

2. sudo dpkg -i vodafone-mobile-connect-card-driver-for-linux_0.9.7.3_feisty_all.deb

3. 安裝好之後, 會在 /etc/udev/rules.d 底下多出一個 99-huawei-e220.rules, 裡面會指定啟用裝置時會先執行 /usr/sbin/huaweiAktBbo, 有了這個之後, 即使在開機時沒有先把 E220 插著, 之後想用時再插上也可以順利使用. (根據實驗結果, 在安裝 vodafone 之前, 如果在開機後才插入 E220, ls /dev/ttyUSB* 只會顯示一個 USB0, 如果開機時有先把 E220 接著的話, 就會有三個檔案, 如果只有一個的話, 就會沒辦法連上線)

4. 重新開機, 讓剛剛裝上的那兩個檔案生效

5. 登入後, 在[應用程式]的[網際網路]中有一個 Vodafone Mobile Connect Card driver for Linux, 執行它, 準備做最後設定.

6. 一開始會先跳出一個視窗告訴你它偵測出的 3G 網卡, 直接按確定, 就會進入主畫面, 然後開啟 [Tools]->[偏好設定] 視窗, 將 APN host 改成 internet, 其他的設定可以不用改, 不過我覺得內定的那兩個 dns 反應有點慢, 所以把它給換成 168.95.1.1 和 168.95.192.1, 回應時間從 300 多 ms 降到 30 多 ms, 快了將近 10 倍唷.

7. 大功告成了, 直接按下 Connect 享受 3G 上網的樂趣吧!

ps: 我有時候會卡在 Authenticating 的畫面就不動了, 原因不明! 這個時候我就把程式關掉, 然後直接用原來設好的 gnome-ppp 上網, 用 gnome-ppp 有兩個好處, 一個是起始速度超快, 另一個是可以最小化到右上方的工具列中. 而且因為有 vodafone 驅動程式的加持, 也不會發生以前結束程式就不能重連的問題囉!

參考: How to: 3G modem on Ubuntu Feisty, Ubuntu 正體中文站 勝仔

2007-07-12

在 Ubuntu 安裝 vmware-server

老樣子, 在 Ubuntu 安裝軟體就是這麼簡單!

  1. sudo sh -c 'echo deb http://archive.canonical.com/ubuntu feisty-commercial main >> /etc/apt/sources.list'
  2. sudo apt-get update
  3. sudo apt-get install vmware-server vmware-server-kernel-modules vmware-tools-kernel-modules

快速在 Ubuntu 安裝 Google Desktop

  1. 加入套件庫 sudo sh -c "echo 'deb http://dl.google.com/linux/deb/ stable non-free' >> /etc/apt/sources.list"
  2. 加入 key 並更新套件列表 wget https://dl-ssl.google.com/linux/linux_signing_key.pub -O- | sudo apt-key add - && sudo apt-get update
  3. 安裝套件 sudo apt-get install google-desktop-linux

在 x31 上裝 Ubuntu, 啟用 compiz 之後, 最大化視窗標題列會變成空白

修改 xorg.conf 在 Section "Device" 中加入一行 Option "AGPSize" "32" 即可

如何在 Ubuntu 中啟用 X31 的小紅點

修改 xorg.conf, 在 mouse 的 Section "InputDevice" 區段加入以下內容:

Option "Emulate3Buttons" "false"
Option "EmulateWheel" "yes"
Option "EmulateWheelButton" "2"

再 Ctrl-Alt-Backspace 重啟或是登出再登入就可以了

自定文件開啟時右鍵選單的程式列表和預設開啟的程式

上次自訂 gnome 滑鼠右鍵的選單只寫一半, 現在再補充另一半, 第一部分是右鍵選單的程式列表, 第二部分是設定預設的開啟程式:
1. 右鍵選單開啟程式列表定義 系統的定義在 /usr/share/applications/mimeinfo.cache 使用者的定義在 ~/.local/share/applications/mimeinfo.cache

檔案格式
[MIME Cache] # 第一行內容是固定的 application/pdf=evince.desktop;AdobeReader.desktop;xpdf.desktop; # 第二行開始長成這樣

左邊淺黃底色的部分是文件的 ContentType; 右邊粉紅底色的部分是開啟程式列表(*.desktop), 以分號(;)隔開.

2.設定預設的開啟程式 系統的定義在 /usr/share/applications/defaults.list 使用者的定義在 ~/.local/share/applications/defaults.list

檔案格式
[Default Applications] # 第一行內容是固定的 application/pdf=evince.desktop # 第二行開始長成這樣


左邊淺黃底色的部分是文件的 Content-Type 右邊粉紅底色的部分是預設開啟程式(*.desktop)

為了避免下次因為軟體更新或是重灌系統, 不小心把設定弄不見, 最好是設定在自己的家目錄, 定期備份, 才不會讓好不容易調整好的設定通通得要重來囉!

2007-07-07

開啟 compiz 之後, 遠端桌面不會更新了

由於新版的 X server 支援了 XDAMAGE extension 的功能, 原意是讓視窗重繪的區域變少, 用以提升效能, 但是啟用了 compiz 之後, 卻將這個通知的功能關閉了, 導致在遠端操控時視窗因此而不進行重繪, 可是滑鼠和鍵盤的事件都有傳送到主機喔! 可以試看看用隔壁的電腦 vnc 到主機然後看看滑鼠有沒有動就知道了!

解決的方法就是關閉 XDAMAGE 功能, 但是 gnome 預設的 vino-server 沒有選項可以將它關閉, 所以只好換成 x11vnc 來取代囉!!

1. 安裝 x11vnc sudo apt-get install x11vnc
2. 產生 vnc 的密碼檔 x11vnc -storepasswd, 這會把密碼存在 ~/.vnc/passwd 裡面
3. 執行 x11vnc x11vnc -forever -shared -noxdamage -rfbauth ~/.vnc/passwd 這樣會讓網路 loading 變重, 所以只適合用在 LAN 的環境, 否則就要有夠大的頻寬才行囉!!

覺得 ok 的話, 再把 3. 放到 "作業階段" 吧!

安裝 compiz fusion

  1. 加入套件庫 deb http://download.tuxfamily.org/3v1deb/ feisty eyecandy
  2. 加入 key 並更新套件列表 wget http://download.tuxfamily.org/3v1deb/DD800CD9.gpg -O- | sudo apt-key add - && sudo apt-get update
  3. 安裝套件 sudo apt-get install compiz compiz-gnome sudo apt-get install compizconfig-settings-manager sudo apt-get install compiz-fusion-*
  4. 執行 compiz --replace & 就可以看到效果啦, 如果想搭配 emerald 的話, 可以換成 compiz --replace -c emerald &
  5. 如果測試沒問題, 就把指令加入到 "偏好設定" 的 "作業階段" 裡, 這樣就可以一進視窗就啟用桌面特效囉!

在 ubuntu 內撥放 rmvb 等多媒體檔案

想直接使用原始網站提供的 tgz 的話可以直接去 mplayer 的網站下載 Linux 的 codecs, 解壓縮之後放到 /usr/lib/win32 底下應該就可以了, 本來我也是這麼做, 可是覺得這樣就不能透過 apt 來管理了, 所以就又找了另一個方式來完成!

For Ubuntu 7.04 "Feisty Fawn"

  1. 新增 "deb http://packages.medibuntu.org/ feisty free non-free" 至 /etc/apt/sources.list 可以用指令: echo "deb http://packages.medibuntu.org/ feisty free non-free" | sudo tee -a /etc/apt/sources.list 或是直接開啟 Synaptic 套件管理程式加入套件庫 deb http://packages.medibuntu.org/ feisty free non-free
  2. 加入 key 並更新套件列表 wget -q http://packages.medibuntu.org/medibuntu-key.gpg -O- | sudo apt-key add - && sudo apt-get update
  3. sudo apt-get install w32codecs 接下來應該就可以順利的播放各類的影片囉!!
參考: MediBuntu

關閉 mpalyer, tsclient 在 compiz 背景透明的功能

  • 開啟 系統->偏好設定->CompizConfig Settings Manager
  • 切換到 General->General Options->Opacity Settings 頁籤
  • 在 Window opacities->Opacity windows 裡面, 把黃底紅字的部分拿掉就可以了 


((type=Unknown | Menu | PopupMenu | DropdownMenu | Tooltip | Notification | Combo | Dnd | name=sun-awt-X11-XWindowPeer) | (type=Normal & override_redirect=1)) & !(name=sun-awt-X11-XFramePeer | name=sun-awt-X11-XDialogPeer)

自訂 gnome 滑鼠右鍵的選單

在 /usr/share/applications/mimeinfo.cache 和 ~/.local/share/applications/mimeinfo.cache 中會記錄每一種的 mime type 所對應到的 *.desktop 檔, 而每一個 .desktop 檔會記載相關應用程式的位置, 所以如果想自己自訂右鍵選單的話, 參考一下這兩個檔案應該就能了解了!

2007-07-02

有趣的廣告, 這麼努力是為了....

2007-06-13

20070606 AjaxControlToolkit 更新內容

其中看起來比較吸引我的是 Script Combining 和 Dynamic Context 這兩個新特色, 等不及要試看看了!!

原文: http://blogs.msdn.com/sburke/archive/2007/06/07/updated-toolkit-release-now-available.aspx

Using LINQ to SQL

又看到超棒的文章, 不得不趕快記下來, 以免以後找不到!! Using LINQ to SQL (Part 1) LINQ to SQL (Part 2 - Defining our Data Model Classes)

令人感動的聲音!!

同事寄的一段影片, 很讓人感動!!

2007-06-02

令人驚艷的 Microsoft Surface

今天同事介紹了一段影片給我看, 讓我看了之後感到很訝異, 幾年前 Tom Cruise 在電影 Minority Report 中那段用手套和系統互動的模式似乎已經要成真了! 這個由 Microsoft 發展的 Microsoft Surface 系統, 利用隱藏在桌子底下的攝影機來感應桌子表面的物體, 並利用無線功能和該物體進行互動, 強調 Multi User, Multi Input, Multi Touch 等概念, 令人看了之後超想體驗一下!! 看看影片過過乾癮吧!

Symbolic link in VISTA and XP

今天在編譯某個 Library 專案時, 有一個參考到的元件因為我的電腦換了新的版本, 以至於參考的路徑沒辦法找到參考檔, 解決的辦法很簡單, 就是建一個 Symbolic link 讓路徑長回來就行了!

剛好我的 OS 是 VISTA, 有多了一個叫 mklink 的指令, 用法就如熟悉的 ln 指令一樣, 感覺還滿親切的, 於是就一切 ok, 搞定!

咦, 如果不是 VISTA 怎麼辦咧? 剛好把以前看到的文章再補上來, 順便又找了一下如何利用程式的方式來操控 NTFS 檔案系統中的 Junction Points, 如下:

Windows Server 2003 Resource Kit Tools: 先下載這個並安裝!
Manipulating NTFS Junction Points in .Net: 你是程序員嗎? 試試這個吧!
NTFS Link Shellextension: 懶人專用工具, 還有相關名詞(SymLink, HardLink, Junction)解釋的網站!

奇怪的 Bitcomet add-on

不知道從什麼時候開始, 我用 IE7 瀏覽 Google Reader 時, 在 manage subscription 的畫面點一下 tags 頁, 會先看到該頁的內容, 然後又跳回到瀏覽內容的畫面, 本來以為是 IE7 出了問題, 可是在另一台電腦又一切正常, 所以馬上就覺得一定是 add-on 的問題! 後來用 without addon 模式打開 IE7 重新試了一次, 果然一切恢復正常, 於是就開始針對可疑的對象進行檢查, 逐一的將 addon 給 disable, 然後重開 IE, 經由二分法切割幾次之後, 終於找出元凶, 原來是 Bitcomet addon 出了問題, 把它給 disable, 其他的回復原狀, 之後一切正常, 搞定!

2007-05-23

Script# 支援了 ASP.NET AJAX

前一陣子開始了一個新的專案, 用了很多的 AJAX 技術, 為了要簡化開發過程, 所以想要做一些 AJAX Control 出來用, 可以在撰寫的過程中發現其實有很多的地方是很惱人的, 特別是在製作 Extender 的時候, 又是 C# 又是 JavaScript, 兩邊都要同時 Debug 超累人的, 而且有很多 code 其實是重覆的, 尤其是在 properties 的定義方面更是如此, 實在是讓人有點挫折, 產能因此受到限制! 那時候突然想到之前在找 Web Development Helper 的時候, 在該作者的網站上有看到一個叫的 Script# 東西, 好像可以拿來用, 所以當下就馬上 Download 了它的 package 和 manual, 看了之後覺得很棒, 和我期待中的東西很像, 但是~~~~~, 美中不足的是它使用自己的一套 Library, 和 ASP.NET AJAX 的不一樣, 這就讓我有點退縮, 因為像這種技術其實在開發上的難度有點高, 如果再引進兩種不同的技術進到團隊中, 可能會造成困擾, 所以只好自己留著, 看看以後有沒有機會使用, 殘念! 今天在看 Nikhilk 的 RSS 時候, 看到 Script# 又更新了, 而且還說它支援了 ASP.NET AJAX, 讓我又看到了一絲希望, 等會兒馬上去下載看看.....

2007-05-17

hideFocus: 消除討厭的虛線外框

IE 有一個 hideFocus 屬性可以設定 ex: Link 在 Firefox 的話, 就要用 CSS 來逹成 ex: a:focus { -moz-outline-style: none; }

2007-05-15

更改 TFS email 通知的 FromAddress

安裝 TFS 的時候, 一時沒看清楚把 email 通知的 FromAddress 設錯了, 雖然對系統不會有什麼影響, 可是看起來就是很怪, 所以就找了一下設定的地方, 預設在 C:\Program Files\Microsoft Visual Studio 2005 Team Foundation Server\Web Services\Services\web.config, 改一下 appSettings 就行啦!

2007-05-14

tivo 密技

  1. 快轉無綠bar: select + play + select + pause + select
  2. 三十秒快轉: select + play + select + 3 + 0 + select
  3. 如何看到容量還剩於多少? 服務訊息及系統設定>設備資訊>系統資訊> 在此畫面底下按 2下綠色大拇指+4+1+1 就可以看到有二個選項
    "可用錄影空間:45%"
    "最長時間: 0個小時16分鐘42秒"
    這二個可以參考,還不錯用。

2007-04-25

停用 Vista UAC 時, 右鍵的選單找不到 Edit With UltraEdit

又是另一個改 Registry 的解法!!

---begin cut---
[HKEY_CLASSES_ROOT\*\shell\UltraEdit]
@="Edit with UltraEdit"

[HKEY_CLASSES_ROOT\*\shell\UltraEdit\command]
@="\"C:\\Program Files\\UltraEdit\\uedit32.exe\" %1"

---end cut---
路徑可能會不太一樣, 要記得改!

web dev helper vista fix for non UAC

Web Development Helper 裝在 Vista 時, 如果 UAC 被 disable, 會無法使用!! 苦惱了很久, 今天不小心看到解決方法! 改改 Registry 就可以了!!

---begin cut---
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\Software\Classes\CLSID\{0AD401E4-2D78-45B1-B875-07B0F9ED3937}]
@="Web Development Helper"

[HKEY_LOCAL_MACHINE\Software\Classes\CLSID\{0AD401E4-2D78-45B1-B875-07B0F9ED3937}\Implemented Categories]

[HKEY_LOCAL_MACHINE\Software\Classes\CLSID\{0AD401E4-2D78-45B1-B875-07B0F9ED3937}\Implemented Categories\{00021494-0000-0000-C000-000000000046}]
@=""

[HKEY_LOCAL_MACHINE\Software\Classes\CLSID\{0AD401E4-2D78-45B1-B875-07B0F9ED3937}\InprocServer32]
@="C:\\Program Files\\nStuff\\Web Development Helper\\WebDevHelper.dll"
"ThreadingModel"="Apartment"

[HKEY_LOCAL_MACHINE\Software\Classes\CLSID\{0AD401E5-2D78-45B1-B875-07B0F9ED3937}]
@="Web Development Helper"

[HKEY_LOCAL_MACHINE\Software\Classes\CLSID\{0AD401E5-2D78-45B1-B875-07B0F9ED3937}\InprocServer32]
@="C:\\Program Files\\nStuff\\Web Development Helper\\WebDevHelper.dll"
"ThreadingModel"="Apartment"
---end cut---

2007-04-24

用 JavaScript 在網頁上畫向量圖

今天在 Google 上搜尋可以在網頁上繪製向量圖形的 Solution 時, 本來焦點是放在 VML 和 SVG 上的, 後來不小心發現一個提供以 JavaScript 繪製簡單向量圖形 Library 的網站, 除了該 Library 之外, 它還提供了 Drag'nDrop, Tooltips, RotateImage 的 Library.

Vectorgraphics 速度雖然被嫌說很慢, 但應用在簡單的 Application 還滿不錯的!
Drag'nDrop 除了字面上的功能外, 還提供按住 Shift 放大縮小的功能, 很有趣!
Tooltips 的功能就比較普通了, 和一般其他的 Library 差不多!
RotateImage 的實作方式很神奇, 沒有用到任何的 filter, 是將原圖重製成多份後, 只切出所需的點, 重新組合而成的, 所以在效能及資源上可能會有點耗!!

2007-04-21

Orcas Beta1 出來了

昨天上 MSDN 網站上, 看到 Orcas 已經出 Beta1, 終於脫離 CTP 了, 下載中....

任天堂PS3

超好笑的KUSO文

2007-04-20

如何讓Browser的捲動軸消失

IE7 的話, 在 css 中設定 html { overflow: hidden } 就可以讓水平及垂直的捲軸都不要出來!

Microsoft 提供的 .NET 3.0 免費線上課程

Collection 5134: Developing Rich Experiences with Microsoft® .NET Framework 3.0 and Visual Studio® 2005 Topics covered within the collection include: Windows Presentation Foundation Windows Workflow Foundation Windows Communication Foundation

Silverlight 發表?

什麼是 Silverlight? 原來是 WPF/E 的產品正式名稱, 是微軟在 2007/04/16 於 Las Vegas 所正式發表的!

2007-02-08

有些.CHM文件在VISTA上無法檢視

在檔案的內容頁, 有一個 Unblock 按鈕, 按一下解除鎖定後就可以打開了!

MS05-026:HTML 說明的弱點可能會導致遠端程式碼執行

MS05-026:HTML 說明的弱點可能會導致遠端程式碼執行