2011年7月22日 星期五

[Visual Studio] 無法找到AL.exe (錯誤訊息MSB3084及MSB3086)

使用Visual studio 2010 express測試javascript file多語言,
在加入另一語系的Resources.OO.resx後, 出現以下的錯誤訊息:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(2342,9): warning MSB3084: 工作嘗試在以下兩個位置尋找 "AL.exe"。1) 在根據 SdkToolsPath 而產生的 "C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\NETFX 4.0 Tools\" (處理器專屬目錄) 底下 2) 在 SDKToolsPath 屬性所指定之 "C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\NETFX 4.0 Tools\" 底下的 x86 專屬目錄。您可以執行下列其中一項來解決這個問題:  1) 將 "SDKToolsPath" 屬性設為 Microsoft Windows SDK 的位置。

C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(2342,9): error MSB3086:
工作無法使用 SdkToolsPath "C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\NETFX 4.0 Tools\"
或登錄機碼 "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.0A" 來尋找 "AL.exe"。請確認已設定 SdkToolsPath、工具存在於 SdkToolsPath 底下的正確處理器專屬位置,以及已安裝 Microsoft Windows SDK。





失敗了很多次才解決此問題,以下是嚐試過的方法(失敗範例):
- 將Resources.OO.resx更名為Resources.OO-00.resx。
http://kgrhash.wordpress.com/2010/12/17/fix-task-could-not-find-al-exe-using-the-sdktoolspath/

- 尋找AL.exe(在C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin底下),將它複製到
C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin。

- 修改註冊表,HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.0A的InstallationFolder="C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\"。

- 安裝完整版的.Net Framework 4.0,http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=0a391abd-25c1-4fc0-
919f-b21f31ab88b7。

以上皆是失敗的示範 (頭大)。



最後找到的解法:
1. 安裝SDK for Windows 7 and .NET Framework 4,
http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=8279

2. 修改註冊表:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\4.0底下有3處的值以"v7.1"取代"v7.0A"的部分,
FrameworkSDKRoot=$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.1@InstallationFolder)
SDK35ToolsPath=$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.1\WinSDK-NetFx35Tools-x86@InstallationFolder)
SDK40ToolsPath=$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.1\WinSDK-NetFx40Tools-x86@InstallationFolder)

之後便能在加入Resources.OO.resx時,順利建置。

2011年7月7日 星期四

C# 將圖檔/Imaget轉換為byte array

以下是2種方式的測試結果,
一是使用FileStream讀入圖檔,
另一是使用System.Drawing.Image讀入圖檔。
           
        // 先將圖檔讀到FileStream, 再轉換為byte array。
        private static void ToBinaryByFileStream(string imageFile)
        {
            FileStream fs = new FileStream(imageFile, FileMode.Open);
            byte[] buffer = new byte[fs.Length];
            fs.Read(buffer, 0, buffer.Length);
            fs.Close();
        }

        // 先將圖檔讀到Image object, 再轉換為byte array。
        private static void ToBinaryByImageObj(string imageFile)
        {
            System.Drawing.Image image = System.Drawing.Image.FromFile(imageFile);
            MemoryStream mr = new MemoryStream();
            image.Save(mr, System.Drawing.Imaging.ImageFormat.Png);
            byte[] binaryImage = mr.ToArray();
            mr.Dispose();
            image.Dispose();
        }

// 測試method。 
public static void ConvertImageToBinary()
        {
            Console.WriteLine("=== Convert the image file to the binary object. ===");

            string imageFolder = @"D:\Images";
            // 測試的image數量。
            int sampleCount = 100;

            string[] imagePaths = Directory.GetFiles(imageFolder, "*.png");
            if (0 == imagePaths.Length)
            {
                Console.WriteLine("No image found.");
                return;
            }

            Stopwatch sw = new Stopwatch();

            sw.Reset();
            sw.Start();
            for (int i = 0; i < sampleCount; i++)
            {
                ToBinaryByFileStream(imagePaths[i]);
            }
            sw.Stop();
            Console.WriteLine("By FileStream: {0} ms.",
                sw.ElapsedMilliseconds);

            sw.Reset();
            sw.Start();
            for (int i = 0; i < sampleCount; i++)
            {
                ToBinaryByImageObj(imagePaths[i]);
            }
            sw.Stop();
            Console.WriteLine("By System.Drawing.Image: {0} ms.",
                sw.ElapsedMilliseconds);
        }


測試100張圖檔的結果

Unit: ms

By FileStream
152
By System.Drawing.Image
2692


Image object會讀取圖檔的相關資訊,
相對地,FileStream只作資料的搬移,所以效能上會快很多。

在Excel中 將秒數轉換成時分秒

使用Excel記錄測試數據時,當這些數據皆是以秒數為單位時,
換算成時分秒後會比較清楚感受到時間的經過,
因此寫個巨集來轉換這些數據。

1. 開啟Excel
2. 按下Alt + F11 (或 工具 -> 巨集 -> Visual Basic 編輯器)
3. 開啟Visual Basic編輯器後,在工具列選擇 插入 -> 模組 ,來新增一個模組。
4. 輸入以下的程式碼:
   Function ConvertToTimespan(Seconds) As Variant
        '取得時分秒的數值
        HourDigit = Int(Seconds / 3600)
        MinuteDigit = Int((Seconds - HourDigit * 3600) / 60)
        SecondDigit = Seconds - HourDigit * 3600 - MinuteDigit * 60
       
        '顯示格式為: "10h 0m 32s"
        '當數值存在才顯示,例輸入秒數換算後為0時14分,則結果會是"14m 0s"。
        result = ""
        If (HourDigit > 0) Then
            result = result & HourDigit & "h "
        End If
           
        If (MinuteDigit <= 0) Then
            If (HourDigit > 0) Then result = result & MinuteDigit & "m "
        Else
            result = result & MinuteDigit & "m "
        End If
       
        result = result & SecondDigit & "s "       
        ConvertToTimespan = result
   End Function

5. 關閉Visual Basic 編輯器回到Excel。
    使用方式與一般函數相同(eg: SUM),
    在Excel的儲存格內輸入"=ConvertToTimespan(A1)"。

結果:

46
850
4000
46s
14m 10s
1h 6m 40s


   

2011年7月4日 星期一

.Net 語音應用程式

在Win7環境下開發語音應用程式:SAPI 已包含在win7內,不用另外安裝。
執行畫面:


加入Reference:
System.Speech.Synthesis:文字語音轉換器
Microsoft.VisualBasic:繁簡體轉換


    public partial class Form1 : Form
    {
        SpeechSynthesizer m_Speaker; // 文字語音轉換器。 
        public Form1()
        {
            InitializeComponent();
            m_Speaker = new SpeechSynthesizer();
        }

        // 朗讀英文句子。
        private void buttonReadEng_Click(object sender, EventArgs e)
        {
            // 設定語音為英文。
            m_Speaker.SelectVoice("Microsoft Anna"); 
            m_Speaker.SpeakAsync(this.buttonReadEng.Text);
        }

        // 朗讀中文句子。
        private void buttonReadCht_Click(object sender, EventArgs e)
        {
            // 中文語音部分,系統預設為簡體中文。
            m_Speaker.SelectVoice("Microsoft Simplified Chinese");
            // 將原本繁體文字轉為簡體,SpeechSynthesizer才能辨識。
            // 輸入文字(繁體),轉換類型,區域設定ID(zh-cn)。
            string simCht = Strings.StrConv(
                buttonReadCht.Text, VbStrConv.SimplifiedChinese, 2052); 
            m_Speaker.SpeakAsync(simCht);
        }
    }


參考:
SAPI介紹:http://www.cnblogs.com/TravelingLight/archive/2010/12/09/1901300.html
在XP的環境下:http://www.chncms.com/2010/12/2/DOTNETVOICESPEACH.html
Local ID:http://msdn.microsoft.com/en-us/library/0h88fahh.aspx