2009/11/07

Hot to Run as Administrator in Windows 7

一般而言,我們很習慣在啟動的「搜尋程式及檔案」的對話框來代替command line window,用來執行程式。
例如:直接輸入 explorer,執行IE or 檔案總管;或是 notepad c:\windows\system32\drivers\etc\hosts 直接用notepad 開啟檔案進行編修。
自從UAC出現後,這個功能常常會困擾我的是…部份這樣的動作,卻是需要administrator的權限,也就是它需要 Run As Administrator的功能。

後來,才發現…其實只要在對話框中輸入完指令:
notepad c:\windows\system32\drivers\etc\hosts
不要按enter,改用ctrl + shit + enter,就會自動切換到administrator的權限

2009/10/20

如何將SQL Server 2005中資料表的大量資料匯出

其實可以利用SQL Server 2005所提供的Utility - BCP,將資料庫中的大量資料匯出。
bcp公用程式會在Microsoft SQL Server和使用者指定格式的資料檔案之間大量複製資料。而當你在伺服器上安裝Microsoft SQL Server工具的同時,也會安裝bcp用戶端,另外只有同時安裝SQL Server 工具和SQL Native Client時,才能支援XML格式檔案。

bcp [tablename] out [filename.txt] -c -T


2009/10/18

如何在繁體中文的作業系統中,不用安裝Multi-Language Pack也能執行簡體中文、日文的軟體?

請參考這份文章
http://toget.pchome.com.tw/intro/utility_other/23153.html
http://www.metro.com.tw/archiver/tid-3184.html

2009/07/23

一套可以產生資料庫文件的工具 - SqlSpec

Elsasoft Sqlspec

最近由微軟MVP的Private News Group中,看到一套可以產生資料庫文件的工具,非常興奮。因為我想找這種工具,已經很久了!!我的需求很單純,只是想要可以選擇性的產生資料庫各種物件說明,一直找不到很好用的工具,後來我乾脆自己寫了一個工具程式給公司用,看到這套工具軟體後,就急忙下載下來玩玩看。

首先,這套工具程式並不需要額外安裝,開啟後就可以直接執行了!!整個畫面如下:
image

image
由上面兩個畫面,我們可以發現到它支援蠻多種的資料庫喔…

image 
可以動態選擇產生資料庫中哪些物件的說明

image 
上面是軟體的設定畫面

這套軟體真的很簡單操作 - 非常的直覺。那…就直接按照直覺操作囉。

  1. 首先,先指定資料庫
    image
  2. 接下來,指定資料庫物件。一般而言,我們產生給客戶用的TableLayout,大概只會含兩個:Table & View。

    image
  3. 直接按下「Go」按鈕,產生文件。我們來看看產生出來的文件長相:
    image
    image
    image

測試的結果而言,這套軟體我個人的感覺是既輕巧又可以解決我的問題,真的是一個很好用的工具程式。而且可以同時產生各種資料庫的資料庫文件,真的是蠻不錯。

2009/07/21

MS Office Viewer (free)

  • Visio 2007 Viewer
  • Powerpoint viewer 2007
  • Word Viewer
  • 即使沒有安裝 Word,也可以檢視、列印和複製 Word 文件。此下載取代了 Word Viewer 2003 和先前所有的 Word Viewer 版本。
    Word Viewer 搭配 Microsoft Office Word、Excel 及 PowerPoint 2007 檔案格式相容性套件使用,可以讓您開啟以下列格式儲存的 Word 文件:

    • Word 文件 (*.docx)
    • Word 啟用巨集的文件 (*.docm)
    • RTF 格式 (.rtf)
    • 文字檔案 (.txt)
    • 網頁格式 (.htm, .html, .mht, .mhtml)
    • WordPerfect 5.x (.wpd)
    • WordPerfect 6.x (.doc, .wpd)
    • Works 6.0 (.wps)
    • Works 7.0 (.wps)
    • XML (.xml)

    您可以使用 Word Viewer 和相容性套件來檢視和列印文件內容,以及將文件內容複製到另一個程式。不過,您無法編輯已開啟的文件、儲存文件或建立新文件。此下載取代了 Word Viewer 2003 和先前所有的 Word Viewer 版本。
    注意:如果您同意接受 Word Viewer 的其他授權條款,您可以獨立散佈這個檢視工具,而不需配合以 Microsoft Office 建立的文件。
  • Excel Viewer
    即使您沒有安裝 Excel,也可以使用 Excel Viewer 開啟、檢視,和列印 Excel 活頁簿。 您也可以將 Excel Viewer 中的資料複製到其他程式中。不過,您無法編輯資料、儲存活頁簿,或是建立新活頁簿。此下載取代了 Excel Viewer 97 和先前所有的 Excel Viewer 版本。(可觀看Excel 2007的檔案)

2009/07/08

window control如何binding自訂類別中的屬性?

在.net 2.0中,它提供了一個類別:binding class,用來binding控制項與類別之間的值。一般的寫法:

   1:  ClassA a = new ClassA();


   2:  Binding bind_ClassA = new Binding("Text",a,"p1",DataSourceUpdateMode.OnValidation, string.Empty);


   3:  ultraTextEditor1.DataBindings.Add(bind_ClassA);




上述的程式碼,它的效果只會發生在一種情況 - 當使用者變更ultraTextEditor1中的值時,會同步更新至 a物件的p1屬性上。但是,當a.p1的值改變時,它是不會同步至ultraTextEditor1 控制項上的。



那我們要如何達到,當a.p1屬性變更時同步更新在畫面上的ultraTextEditor1上呢?

首先,ClassA必須實作INotifyProperptyChanged介面,使得a.p1值改變時會發出一個propertychanged 事件,當畫面的程式碼收到這個事件時,再將改變後的值同步至ultraTextEditor1上。詳細程式碼,如下:



ClassA.cs



using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;

namespace Binding自訂屬性
{
public class ClassA : INotifyPropertyChanged
{
private string m_p1;

[Browsable(true)]
[Bindable(BindableSupport.Yes, BindingDirection.TwoWay)]
[Category("自訂屬性")]
public string p1
{
get { return m_p1; }
set
{
if (m_p1 != value)
{
m_p1 = value;
NotifyPropertyChanged("p1");
}
}
}

#region INotifyPropertyChanged Members

public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}

#endregion
}
}




Form1.cs



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

namespace Binding自訂屬性
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

ClassA a = new ClassA();
Binding bind_ClassA = null;

private void Form1_Load(object sender, EventArgs e)
{
a.PropertyChanged += new PropertyChangedEventHandler(a_PropertyChanged);
bind_ClassA = new Binding("Text",a,"p1",false, DataSourceUpdateMode.OnValidation,string.Empty);
ultraTextEditor1.DataBindings.Add(bind_ClassA);
bind_ClassA.ControlUpdateMode = ControlUpdateMode.OnPropertyChanged;
a.p1 = "ccc";

}

void a_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
bind_ClassA.ReadValue();
}

private void ultraButton1_Click(object sender, EventArgs e)
{
//bind_ClassA.BindingManagerBase.SuspendBinding();
a.p1 = System.DateTime.Now.ToLongTimeString();
//bind_ClassA.BindingManagerBase.ResumeBinding();
//bind_ClassA.ReadValue();

}

private void ultraButton2_Click(object sender, EventArgs e)
{
MessageBox.Show("p1 = " + a.p1);
MessageBox.Show("TextBox.Value = " + ultraTextEditor1.Value.ToString());
MessageBox.Show("TextBox.Text = " + ultraTextEditor1.Text.ToString());
}
}
}

DataSet.RemotingFormat屬性可以改善效能

在.NET 2.0建製N-Tier的系統時,一般的作法都是傳遞DataSet。然而,DataSet本身是一個怪獸級的Framework,再經由序列化變成XML時,傳遞的Size都是非常恐佈的,也讓系統本身的效能不彰。
在微軟的建議中,我們可以改變DataSet預設的序列化格式,讓序列化的資料不是XML而是以Binary的格式進行傳遞,這樣可以改善部份的效能。
那究竟改善多少呢?可以由下列兩篇文章看出一些端堄:

http://www.codeproject.com/KB/database/CompressedDataSets.aspx?display=PrintAll&fid=188889&df=90&mpp=25&noise=3&sort=Position&view=Quick&select=1825203
http://bethmassi.blogspot.com/2006/01/binary-serialization-of-datasets-in.html

清空SQL Server的快取

一般而言,不會有需要清除SQL Server Cache的問題。但是,在某些時刻它卻是一個必需的指令,例如:在測試performance時,需要前後狀況的比較。或是,在某些狀況下cache無法反應最新的資料狀況時,我們都會需要清除cache的動作,指令如下:
DBCC FREEPROCCACHE
會清空Procedure的最佳化的計劃,重新執行重新產生新的執行計劃

DBCC DROPCLEANBUFFERS
會清空儲存在快取中的資料,而不需要重新啟動SQL Server

2009/05/11

產生SQL Server 2005/2008 資料庫物件的文件(CHM)

之前為了產生資料庫物件的相關文件,費時費力。後來,使用Case Studio產生資料庫文件。到後來的Toad for SQL Server  / Toad Database Modeler。這些工具都有幾個問題,客製化不容易,文件也不甚美觀,只能產生RTF檔。

最近,在CodeProject發現了一個好東西:SQLDoc Sharp

它可以直接連結資料庫,並產生相關檔案及原始碼(包含Table, Trigger, Stored Procedure, UserDefineTypes及View…),並且直接產生成CHM檔,方便歸檔也方便搜尋。最棒的是,還附上Source Code(當然不用錢,也是另外一個好處)。

這個原始碼專案,我稍微看過,我把我的心得稍微歸類一下:

  • 這個原始碼專案,必須用Visual Studio 2008才能開啟。
  • 這個專案產生的執行檔,必須先安裝HTML Help workshop。並且必須安裝在預設目錄(C:\Program Files\HTML help workshop)
  • 執行檔所在的執行環境,必須事先安裝 SQL Server 2008 / SQL Server 2008 Express。因為專案中有參考到SQL Server 2008的部份元件。
    • 若無法在執行的該台電腦上安裝SQL Server 2008 (或Express Edition)。那請參考  Microsoft SQL Server 2008 Feature Pack(2008 年 8 月)。安裝其中的兩項元件:
      • Microsoft SQL Server 2008 管理物件
        SQL Server 管理物件 (SMO) 是一種 .NET Framework 物件模型,可讓軟體開發人員建立用戶端應用程式來管理 SQL Server 物件與服務。這個物件模型將適用於 SQL Server 2000、SQL Server 2005 與 SQL Server 2008。
      • Microsoft SQL Server 系統 CLR 類型
        SQL Server 系統 CLR 類型封裝包含一些元件,可實作 SQL Server 2008 中的新 geometry、geography 和 hierarchyid 類型。這個元件可以與伺服器分開安裝,以便讓用戶端應用程式在伺服器外部使用這些類型。
        注意:本元件也需要 Windows Installer 4.5。
        (
        http://www.microsoft.com/downloads/details.aspx?familyid=5A58B56F-60B6-4412-95B9-54D056D6F9F4&displaylang=en)

Microsoft SQL Server 2008 Feature Pack,2008 年 8 月

這是一項獨立安裝封裝集合,這些封裝可以增加 SQL Server 2008 的額外價值。

每項封裝都會指出它所適用的對象,如下所示:

    客戶:想要安裝這項封裝來增加授權功能 (例如:互通性) 的個人。
    夥伴:ISV 可能想要將這個封裝當做可轉散發元件來轉送,以做為其應用程式的一部分。
    開發人員:程式設計人員可能想要安裝這項封裝來支援應用程式開發。

注意:若要另存一份授權條款,在接受條款之前,請先將條款複製並貼至文字處理程式中,再列印或儲存至您偏好的目錄即可。

  • Microsoft SQL Server 2008 Analysis Services 10.0 OLE DB 提供者
  • Microsoft SQL Server 2005 回溯相容性元件
  • Microsoft SQL Server 2008 命令列公用程式
  • SQL Server Compact 3.5 SP1
  • 適用於 Microsoft Office 2007 的 Microsoft SQL Server 2008 資料採礦增益集
  • Microsoft Core XML Services (MSXML) 6.0
  • Microsoft SQL Server 2005 JDBC 驅動程式 1.2
  • Microsoft SQL Server 2008 管理物件
  • Microsoft OLEDB Provider for DB2
  • SQL Server 遠端 Blob 存放區
  • Microsoft SQL Server 2008 Native Client
  • Microsoft SQL Server 2008 原則
  • 適用於 Microsoft SharePoint 技術的 Microsoft SQL Server 2008 Reporting Services 增益集
  • Microsoft SQL Server 系統 CLR 類型
  • Microsoft Sync Framework
  • Microsoft SQL Server 2008 Upgrade Advisor

詳細下載及說明網址:Microsoft SQL Server 2008 Feature Pack,2008 年 8 月

2009/01/10

在ASP.NET 2.0中如何處理UI 繼承的問題?

我想設計一個有繼承功能的WebForm,類似Window Form的作法。但是,ASP.NET的WebForm,其實是無法作可視化的Web UI繼承,所以只有Code-Behind的程式碼是可以繼承的。

概念如下:
image

所以,我們先在網站專案中新增一個Web頁面:Base_swWebForm.aspx。再增加一張網頁:TestPage.aspx。
由上圖的結構,我們可以知道BaseForm是Base_swWebForm.aspx。故在Base_swWebForm.aspx.cs中撰寫相關程式碼。而TestPage.aspx.cs 則是撰擇繼承Base_swWebForm.aspx,再進行進一步的程式碼撰寫。

程式碼如下:

WebForm Code-behind 的程式碼:
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class Base_swWebForm : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
ScriptManager.RegisterClientScriptInclude(this, this.GetType(), "common", "../Scripts/common.js");
}

/// <summary>
///
取得客戶端真實IP Address
/// </summary>
/// <returns></returns>
protected string GetClientIP()
{
string ip = null;
if (string.IsNullOrEmpty(Request.ServerVariables["HTTP_X_FORWARDED_FOR"]) || Request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToUpper().IndexOf("UNKNOWN") > 0)
{
ip = Request.ServerVariables["REMOTE_ADDR"];
}
else if (Request.ServerVariables["HTTP_X_FORWARDED_FOR"].IndexOf(",") > 0)
{
ip = Request.ServerVariables["HTTP_X_FORWARDED_FOR"].Substring(1, Request.ServerVariables["HTTP_X_FORWARDED_FOR"].IndexOf(",") - 1);
}
else if (Request.ServerVariables["HTTP_X_FORWARDED_FOR"].IndexOf(";") > 0)
{
ip = Request.ServerVariables["HTTP_X_FORWARDED_FOR"].Substring(1, Request.ServerVariables["HTTP_X_FORWARDED_FOR"].IndexOf(";") - 1);
}
else
{
ip = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
}

//return ip.Replace(' ', string.Empty).ToString();
return ip.Trim().ToString();
}

/// <summary>
///
顯示MessageBox
/// </summary>
/// <param name="msg">
訊息</param>
protected void ShowMessage(string msg)
{
this.Response.Write("<Script language='JavaScript'>\nwindow.alert('" + msg + "');\n</Script>");
}
}
在Base_swWebForm.aspx.cs的程式碼做了三件事:
1. 註冊網頁上會用到的共用Script File。
2. 提供取得Client IP的Method:GetClientIP();
3. 提供類似MessageBox.Show的功能:ShowMessage(msg);



WebForm Code-behind 的程式碼:



using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Threading;
using System.IO;

public partial class Base_TestPage : Base_swWebForm //System.Web.UI.Page Base_TestPage
{
protected void Button2_Click(object sender, EventArgs e)
{
ShowMessage(GetClientIP());
}

}
TestPage.aspx.cs,則因為是測試網頁,所以程式碼很簡單,只有一個Button2而已。而在Button2_Click時,呼叫Base_swWebForm上原有提供的methods,用來確定繼承是成功的。


此時,你會發現程式是錯誤的。因為沒有辦法繼承Base_swWebForm。你必須將Base_swWebForm.aspx.cs這個檔案移動到Web專案的App_Code的目錄下,而原有的Base_swWebForm.aspx這個檔案,因為ASP.NET 2.0 原本就達到頁面可視繼承,就直接刪除吧!!
此時,你會發現程式碼就會正確,也達到Code-behind的繼承,而每個繼承的頁面再也不必寫, Include common.js及GetClientIP(), ShowMessage 這些功能。

當TextBox Control 放入AJAX 的UpdatePanel後,無法正常觸發TextChanged事件?

因為 ASP.NET 2.0 既有的 Vlidators 有實作用戶端程式碼,會與 ASP.NET AJAX 的 UpdatePanel 不相容,微軟已經計劃會透過 Windows Update / Microsoft Updaet 更新 System.Web。

目前的解法:
1. 請下載 新版的 Validators(http://blogs.msdn.com/mattgi/attachment/1516974.ashx)
2. 解開壓縮檔,將 Validators.dll 複製到網頁應用程式的 bin 資料夾中
3. 開啟 Web.config,在 <system.web> 區段下的 <pages> 標籤中,加入如下的 <tagMapping> 設定:

<pages>
<
tagMapping>
<!--
ASP.NET & UpdatePanel搭配後發現原本的ASP.NET Validator有bug
故需更新Bin\Validator.dll元件,用來取代原始的ASP.NET的Validator.dll
請參考:
http://forums.microsoft.com/MSDN-CHT/ShowPost.aspx?PostID=1529953&SiteID=14&pageid=0
-->
<
add tagType="System.Web.UI.WebControls.CompareValidator" mappedTagType="Sample.Web.UI.Compatibility.CompareValidator, Validators, Version=1.0.0.0"/>
<
add tagType="System.Web.UI.WebControls.CustomValidator" mappedTagType="Sample.Web.UI.Compatibility.CustomValidator, Validators, Version=1.0.0.0"/>
<
add tagType="System.Web.UI.WebControls.RangeValidator" mappedTagType="Sample.Web.UI.Compatibility.RangeValidator, Validators, Version=1.0.0.0"/>
<
add tagType="System.Web.UI.WebControls.RegularExpressionValidator" mappedTagType="Sample.Web.UI.Compatibility.RegularExpressionValidator, Validators, Version=1.0.0.0"/>
<
add tagType="System.Web.UI.WebControls.RequiredFieldValidator" mappedTagType="Sample.Web.UI.Compatibility.RequiredFieldValidator, Validators, Version=1.0.0.0"/>
<
add tagType="System.Web.UI.WebControls.ValidationSummary" mappedTagType="Sample.Web.UI.Compatibility.ValidationSummary, Validators, Version=1.0.0.0"/>
</
tagMapping>
</
pages>

在ASP.NET上如何取得真實的IP?

在ASP.NET上,通常會使用
Request.ServerVariables["REMOTE_ADDR"];
來取得用戶端的IP。

但是有可能會遇到一個問題,當用戶端是透過代理伺服器連入時,則IP會變成是代理伺服器的,而並非是真正的用戶端IP。所以,我們必須使用另外的方式取得用戶端的IP
Request.ServerVariables["HTTP_X_FORWARDED_FOR"];

完整的程式碼如下:

/// <summary>
///
取得客戶端真實IP Address
/// </summary>
/// <returns></returns>
protected string GetClientIP()
{
string ip = null;
if (Request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString()==string.Empty || Request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToUpper().IndexOf("UNKNOWN") > 0)
{
ip = Request.ServerVariables["REMOTE_ADDR"];
}
else if (Request.ServerVariables["HTTP_X_FORWARDED_FOR"].IndexOf(",") > 0)
{
ip = Request.ServerVariables["HTTP_X_FORWARDED_FOR"].Substring(1, Request.ServerVariables["HTTP_X_FORWARDED_FOR"].IndexOf(",") - 1);
}
else if (Request.ServerVariables["HTTP_X_FORWARDED_FOR"].IndexOf(";") > 0)
{
ip = Request.ServerVariables["HTTP_X_FORWARDED_FOR"].Substring(1, Request.ServerVariables["HTTP_X_FORWARDED_FOR"].IndexOf(";") - 1);
}
else
{
ip = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
}

return ip.Replace(' ', string.Empty);
}

回覆:自訂控制項的問題…

提問者 的標籤:

您好,看了您的Blog,覺得您應該是資深的,很熟悉C#的專業程式開發者
小弟最近在開發程式時,有需要建立控制項的需求,然而不知道這樣的作法是否正確
我先建立專案-「Windows Form控制項程式庫」,然後在UserControl上面放置我想要用的元件,
可能放了PictureBox或是TextBox與Button
因為只是簡單的測試,所以隨便定了兩個 Set Method就好了
然後把名稱改為MyTestCtrl,編譯,會在bin目錄下產生一個dll
接下來開另外一個專案MyWork,在工具列的地方以滑鼠右鍵開Menu,「選擇項目」
然後在Tab「.NET Framework元件」內點選「瀏覽」按鈕,選到剛剛那個Project內所編譯出來的dll檔
我的工具箱就會多一個圖示,是MyTestCtrl,可以像一般的控制項一般拉來用了
請問:
1.我這樣的開發方式,是正確的嗎?

一般的開發方式會是新增一個方案,其中包含了兩個專案:開發自訂控制項專案 + 測試自訂控制項的專案。而在測試自訂控制項的專案中,用專案參考的方式把開發專案包含進來,你的專案便可以一面開發、一面進行測試。
所謂專案參考,是在Solution Explorer中先點選「測試開發專案」的Reference目錄,按下滑鼠右鍵,選擇「Add Reference」。在出現的Reference Diagram上把Tab切到「專案」這個Tab,把「開發自訂控制項」的專案加入即可。


2.這樣我的MyWork專案在編譯出給人家用時,都要把MyTestCtrl.dll一併發佈,不然用起來會有問題,那如果我有很多這樣的自訂控制項,不就要一堆dll跟軟體放在同一目錄下才行囉?

不一定要放在同一個目錄。因為別人的使用方式會用「Dll」參考,其步驟就是你原本使用的方式。而這種Dll Reference的方式,你可以在加入參考後,在Solution Explorer中該專案的Reference Folder中發現加入Reference的Dll資訊,如下圖所示:
image
接下來切換到Properties視窗,裏面有一個很重要的屬性:Copy Local
image
一般而言,Dll Reference 預設是True,而GAC Reference則會是False。這個屬性會決定是不是將Dll複製到該專案的目錄下,你可以自行決定作法。而我的作法會把Release出來給PR用的Dll,都統一放置在一個固定的開發目錄,而不希望在放在每個專案下,因為第一:每一個專案的Reference 都是一次複製,而散落在每個專案時,也不好管理他們究竟Reference的是我發出來的哪一個版本。


3.做出來的自訂控制項,在工具箱內不會像一般的控制項有自己的圖示耶,都長的一個樣,齒輪,這個要怎麼更改呢?呢?

至於工具箱圖形這件事,我並沒有實作過!!但是,就我印象中在VS2005上似乎是有一點問題。我找了一些資料,你可以實作看看,看起來是可行的
如何为自定义的控件在工具箱中自定义个性化的图标?


還有如果我的控制項,我有個TestValue成員,int,我希望可以在屬性視窗修改,而不是只能在Code修改,該怎麼作呢?

自訂控制項的屬性預設都會出現在Properties視窗中,如下圖所示:
image 
你也可以用進階一點的方式,在該屬性用設定meta-data的方式來處理

[Browsable(true)]
[Description("個人登入資訊")]
[Category("自訂控制項之自訂屬性群")]
public UserInfo PersonalData
{
get { return this.m_userinfo; }
set
{
this.m_userinfo = value;

if (bindUserInfo != null)
bindUserInfo.ResetBindings(false);
}
}



結果,你就會發現屬性會被歸類在「自訂控制項之自訂屬性群」且會有加上描述:

image

2009/01/05

遇到 Windows Update 或 Microsoft Update 無法更新時該怎麼辦 ?

Windows Update 與 Microsoft Update 是 Microsoft 提供使用者線上更新程式的管道,可以自動連線到 Microsoft 網站以隨時下載最新的更新程式,但是有時候也會因為許多客觀因素而導致更新無法順利完成,例如網際網路頻寬不穩定、有其他軟體或應用程式佔用網路頻寬 (例如防毒軟體正在更新或下載病毒碼),或是網際網路設備 (例如網路卡、交換器) 發生故障等等,都有可能導致 Windows Update 或 Microsoft Office 無法更新或更新失敗等問題。如果網際網路連線頻寬不穩定的問題已經解決,且網路設備故障的問題也已經排除或設備已經更換,但依舊還是發生 Windows Update 或 Microsoft Update 無法正常運作的狀況,就表示先前更新程式的過程被中斷,導致自動更新程式無法正常運作。

詳細解決方法,請至 微軟技術支援服務(961054) 網站

安裝 Windows XP Service Pack 3 後,無法啟動 Outlook Express

Windows XP Service Pack 3 (SP3) 是 Microsoft 針對 Windows XP 作業系統推出的最新修補程式,不但可以改善作業系統的執行效率 (例如 MMC 3.0、WPA2 等),還提供許多新功能 (例如 NAP、Windows 產品啟用等),所以一推出後,立即成為最熱門的下載軟體。但是,有些使用者因為電腦中安裝許多各種不同的應用程式與軟體,因此在安裝 Windows XP SP3 之後,可能會遇到無法啟動 Outlook Express 的問題…

詳細解決方法,請至 微軟技術支援服務(960640) 網站

2008/12/22

.NET 應用系統全球化(三)

假設各位的系統,已經利用上一篇提到的CultureInfo搭配程式碼,處理字串、數字、日期…,讓系統符合國際化(也就是說,不會因為不同文化特性需要進行系統的修改及客製化)。此時,我們來了解一下,當地化該怎麼處理?基本上有兩種作法:

其一:

稍微對於.NET及Visual Studio有了解的人,都知道.NET內建支援多國語系(這也就是我說的當地化的部份)。該怎麼做呢?開啟專案後,在每一個window form 畫面的Properties Box裏,你可以看到兩個屬性:Language / Localizable。
image

當 Localizable = True時,你便可以指定 Language = 哪一個語系。此時,你便可以針對畫面進行不同語系的客製化。如下圖所示,重新指定畫面上的字,詳細作法,我想網路上都可以找得到,不再贅述。

其二:
第一種作法是標準作法,但是並不適合真正實作在當地化的流程裏。試想,你或你的公司可能把整份原始碼送去某一個國家,例如:系統要做英文版,你會把你的原始碼拿到美國,然後請當地的公司幫你進行字彙的翻譯嗎?這是會有被複製及抄襲的風險的。所以,我們要用另一種作法,使用Microsoft .NET Framework SDK提供的工具:WinRes.exe (Windows Resources Localization Editor)。
首先,為了讓系統將畫面資料儲存在另外的Resources File,必須將系統內的每一個畫面(WinForm)的Localization屬性設成True。與第一種作法不同的是我們不需要在針對每一種需要的語系分別進行畫面重新編輯的動作(因為這個動作是要讓當地的軟體公司進行字彙翻譯)。接下來,我們只要Compiler程式就行了。

這個時候,你可以觀察 obj\Debug 目錄的檔案,會與一般不同。每個畫面都會多出一個檔案( *.resources)。
image 
這就是Visual Studio 因為你將Localization設定成True。所以,將畫面資訊儲存在這個檔案中。接下來的動作,你要將它預設是當地化時,在當地的公司要進行的動作。當你的系統Release之後,將需要當地化的畫面,它的Resources File (*.resources),交付給他們,請他們利用WinRes.exe進行翻譯。

操作方式如下:

  • 開啟Visual Studio 2005 Command  Prompt,並輸入
    WinRes.exe <Resources File Name>,按下Enter。開啟Windows Resources Localization Editor。
    image
  • 此時,可以針對畫面進行字彙的翻譯,甚至欄位的大小也可以進行調整。因為在不同的語系中,字型的大小可能會讓你的欄位擺放及長度都會所有不同的。
  • 完成後,按下File->Save / SaveAs,你將可以指定要儲存成是某一種語系的資源檔(Resources File)。例如:你要把系統英文化,所以將畫面上的字都改成英文,此時你便可以撰擇儲存成英文系的資源檔。至於每一種英文系有什麼不同,請參考.NET 應用系統全球化(二)
    image
  • 當對方將翻譯好的Resources File回傳給你時,你將會收到該語系的resources files。例如:英文系,你可能收到的是
    MultiLangSample1.frmMain.en-US.resourcs。
    這個檔案直接放入系統內,系統就會變成支援該語系嗎?當然不可能,因為resources files,只是一個二進位碼的資源檔,此時仍然不是系統會執行的檔案( *.dll)。它仍然需要轉換成dll,並link至你的系統上。
    參考一下,最後的結果:
    image
    就我這個範例而言,每個語系的目錄下都會存在一個MultiLangSample1.resources.dll的檔案。
  • 此時,我們要利用Microsoft .NET Framework SDK中的另一個工具:al.exe (Assembly Link Tools)。
  • 開啟Visual Studio 2005 Command Prompt,並輸入
    al.exe /out:<語系名稱>\MultiLangSample1.resources.dll /culture:<語系名稱> /embedresource:MultiLangSample1.frmMain.<語系名稱>.resources
    image

恭喜你,你的系統這個時候就多了一個語系是英文語系。你可以開始進行測試了。

2008/12/13

.NET 應用系統全球化(二)

在了解全球化的基本步驟後,我們來了解.NET在全球化上最重要的一個物件CultureInfo。
CultureInfo,是.NET用來提供特定文化特性(Culture)的相關資訊。這個物件裏包含的資訊有文化特性、書寫系統、使用的行事曆以及如何格式日期和排序字串。我們可以針對DateTimeFormatInfo、NumberFormatInfo、CompareInfo和TextInfo的特定文化特性執行個體進行存取,這些物件裏包含特定文化特性作業所需的資訊,例如:大小寫的設定、日期和數字的格式化以及字串的比較,對於.NET應用系統國際化而言是很重要的資訊。

我們先來了解CultureInfo的命名原則,例如:en-US。前兩碼小寫英文字母代表的是英文語言,而後兩碼大寫的英文字母代表的是國別或是區域別。所以由此可知en-US,代表的是在美國地區的英文,換而言之,當然也有en-CA(加拿大地區的英文),en-AU(澳洲地區的英文)…等等。
故CultureInfo是有階層性的,以下圖可以清楚的表示:
image
這樣做的好處是什麼呢?你可以針對所有英文語系的國家或是其它語系的國別,分別建立屬於該語系的資源,若單一國家還有不同的資源,你可以再往下一層建立專案該語系的國家專屬的資源,這樣在當地化時就可以大量減少客製化的問題。例如,我們可以針對英文語系的國家(en)建立英文版本,若美國與澳洲在某些詞句上有不同的詞彙或說法,我們再分別在en-US及en-CA的版本,分別建立不同的資源即可。

也許,你會覺得很奇怪,為什麼我不以中文為例呢?因為在這樣的rule中,中文在命名原則中是屬於特例,怎麼說?因為中文的語系命名,並不Follow這樣的原則(前兩碼小寫英文字母),而分別是zh-CHT(繁體中文)/zh-CHS(簡體中文)。所以,中文的語系結構就比較特殊,如下圖所示:
image 
所以,針對簡體中文,在建立資源檔時,我們就可以直接指定zh-CHS,基本上你就可以擁有zh-HK(香港特別行政區)/zh-MO(澳門特別行政區)/zh-CN(中國)/zh-SG(新加坡),四個國家的版本。

解釋完CultureInfo的階層概念後,我們再來說明CultureInfo的種類。CultureInfo的種類,基本上分成三種:

  1. 中性文化特性:所謂中性語系,其實指的是各位在上面所了解到的階層結構中的第一層,也就是所謂的語系的部份,例如:en、zh-CHT、zh-CHS…等等。因為並不會指定到國別,所以它也無法代表作業系統上的Culture(文化特性),所以它稱之為中性語系,也因此它在程式裏也無法直接指定給Application.CultureInfo或是Thread.CurrentThread.CurrentCulture / Thread.CurrentThread.CurrentUiCulture。
  2. 特定文化特性:指的是階層結構中的最後一層,因為會指定語系及國別,其實代表的就是作業系統中的文化特性。是我們在程式中會使用到的部份。
  3. 不變文化特性:不區分文化特性。我們可以使用(“”)空字串的名稱或是直接在CultureInfo.InvariantCulture擷取出不因文化特性而異的執行個體。它包含的資訊,與英語相關,但是並不會因為任何的調整而改變它包含的任何資訊。所以,當你的全球化系統內部需要一致性的資料,不能也不會因為任何語系改變時,請使用這個文化特性的格式資訊,進行程式及資料處理。

說到這裏,我想大家對於這個物件應該有進一步的認識了。

.NET 應用系統全球化(一)

使用 Microsoft .NET Framework,如何開發一個全球化的系統呢?首先,筆者先來說明一下,如何將一個應用系統全球化。
所謂全球化,一般而言分成二大部份。一是國際化,接下來才會進行當地化。

一般而言,全球化是一個目標!!而在過程中系統需先進行國際化(支援多國語系,包含畫面,程式及資料)。當系統已升級至全球化了,接下來才會考慮究竟針對哪幾個國家進行當地化的動作。

  • 國際化
    首先,必須讓原本的系統能接受全球化後,可能輸入或輸出的資料。這麼說好了,系統本身必須跟整個語系脫離(在.NET中,指的便是CultureInfo這個物件)。語系會影響系統的字串,日期,數字,貨幣…等格式。這些都必須改寫成活的,因為不同的語系,字串的比對、排序,日期的格式,數字的格式,貨幣的小數點位數都可能會不同。在之後說明到CultureInfo這個物件時,筆者再詳細一點說明。
  • 當地化
    當你的應用系統完成了國際化的調整後,接下來就端看你想要對哪個語系進行當地化了。最基礎的當地化,就是畫面及訊息都必須改成當地的字型編碼。Microsoft .NET提供了多種的方式進行,你甚至可以在Visual Studio中很簡單的完成這項工作。但是,當你利用Visual Studio進行當地化時,你必須要有完整的程式碼(方案)才可以進行。若你需要在當地找外包,進行當地化時此種作法就會有問題的,因為你不可能直接把完整程式碼全部交給當地的外包。而在Microsoft .NET 中我們也可以使用另外的作法達到你的目的。

2008/12/10

整合 Windows Vista 和 Office 2007 的基礎學習園地

微軟為了讓一般使用者更加了解 Windows Vista 和 Office 2007 的使用方法而特別建製的一個技術園地
它特別彙整來自在技術支援網站上的Windows Online, Office Online 以及 TechNet 網站上有用的 how-to 文章,線上學習視訊和網路廣播等相關資訊,是一個不錯的網站

整合Windows Vista和Office 2007的基礎學習園地

cmd.exe下的指令說明

gpedit.msc-----本機群組原則
nslookup-------IP位址偵測器
explorer-------開啟檔案總管
logoff---------登出指令
tsshutdn-------60秒倒計時關機指令
lusrmgr.msc----本機使用者及群組
notepad--------開啟記事本
cleanmgr-------磁碟清理
net start messenger----開始net send 服務
compmgmt.msc---電腦管理
net stop messenger-----停止net send 服務
dvdplay--------呼叫Microsoft Media Player
charmap--------啟動字元對應表
calc-----------啟動計算機
dfrg.msc-------磁碟重組工具
chkdsk.exe-----Chkdsk磁牒檢查
devmgmt.msc--- 裝置管理員
srononce -p ----15秒關機
dxdiag---------檢查DirectX資訊
regedt32-------註冊表編輯器
rsop.msc-------群組原則結果集
mem.exe--------顯示記憶體使用情況
regedit.exe----註冊表
perfmon.msc----電腦效能監測程序
winver---------檢查Windows版本
sfc /scannow-----掃瞄錯誤並復原
taskmgr-----工作管理器(2000/xp/2003)
eventvwr.msc------------事件檢視器
secpol.msc----------------本機安全性設定
rsop.msc------------------原則的結果集
ntbackup----------------啟動製作備份還原嚮導
mstsc-----------遠端桌面
winver---------檢查Windows版本
wmimgmt.msc----開啟windows管理體系結構(WMI)
wupdmgr--------windows更新程序
wscript--------windows指令碼宿主設定
write----------呼叫WordPad
winmsd---------系統資訊
mem.exe--------顯示記憶體使用情況
mspaint--------小畫家
magnify--------放大鏡
mmc------------MMC
mobsync--------同步指令
dxdiag---------檢查DirectX資訊
devmgmt.msc--- 裝置管理員
diskmgmt.msc---磁牒管理實用程序
dcomcnfg-------開啟系統元件服務
ddeshare-------開啟DDE共享設定
dvdplay--------DVD播放器
notepad--------開啟記事本
nslookup-------網路管理的工具嚮導
ntbackup-------系統製作備份和還原
ntmsmgr.msc----移動存儲管理器
ntmsoprq.msc---移動存儲管理員操作請求
netstat -an----(TC)指令檢查連接
Usyncapp--------新增一個公文包
sysedit--------系統配置編輯器
sigverif-------文件簽名驗證程序
psndrec32-------錄音機
shrpubw--------新增共用資料夾
secpol.msc-----本機安全原則
services.msc---本機服務設定
Sndvol32-------音量控制程序
sfc.exe--------系統檔案檢查器
sfc /scannow---windows文件保護
tsshutdn-------60秒倒計時關機指令
taskmgr--------工作管理器
eventvwr-------事件檢視器
eudcedit-------造字程序
explorer-------開啟檔案總管
lpackager-------對像包裝程序
perfmon.msc----電腦效能監測程序l
progman--------程序管理器
regedit.exe----註冊表
rsop.msc-------群組原則結果集
rononce -p ----15秒關機
regsvr32 /u *.dll----反註冊dll元件
regsvr32 /u zipfldr.dll------取消ZIP支持
cmd.exe--------CMD命令提示字元
chkdsk.exe-----Chkdsk磁牒檢查
certmgr.msc----證書管理實用程序
calc-----------啟動計算器
charmap--------啟動字元對應表
cliconfg-------SQL SERVER 客戶端網路實用程序
Clipbrd--------剪貼板檢視器
conf-----------啟動netmeeting
compmgmt.msc---電腦管理
ciadv.msc------索引服務程序
osk------------開啟螢幕小鍵盤
odbcad32-------ODBC資料來源管理器
lusrmgr.msc----本機使用者及群組
iexpress-------木馬元件服務工具
fsmgmt.msc-----共用資料夾管理器
utilman--------協助工具管理器

2008/11/15

Visual Studio 2010 CTP 已經開放下載囉

這兩天在微軟的download site上發現微軟已經開放免費下載 Visual Studio 2010 & .NET Framework 4.0 Preview CTP囉

Microsoft Pre-release Software Visual Studio 2010 and .NET Framework 4.0 Community Technology Preview (CTP)

2008/11/07

Excel Driver Error : 系統資源滿載

I tried to use all the 3 connection strings that you specified in your sample and had no problems retrieving and displaying data from excel file (Excel 2003)

To try my sample create a new excel file and put these values in

Col1  Col2
1        Hello
2        Test

Create test.asp and paste the following code. Open IE and call /test.asp">http://<machinename>/test.asp

<% OPTION EXPLICIT %>
<%
On Error Resume Next
Dim rs
Dim cn
Dim j

'Instantiate Objects
Set cn = Server.CreateObject("ADODB.Connection")
Set rs = Server.CreateObject("ADODB.Recordset")

'Open connection

'cn.Open "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=C:\testbook.xls; Extended Properties=""Excel 8.0;HDR=Yes;"" "

'cn.Open "DBQ=C:\testbook.xls;DRIVER=Microsoft Excel Driver (*.xls);UID=;UserCommitSync=Yes;Threads=3;SafeTransactions=0;ReadOnly=0;PageTimeout=5;MaxScanRows=8;MaxBufferSize=2048;FIL=excel 8.0;DriverId=790"

cn.Open "DRIVER=Microsoft Excel Driver (*.xls);DriverId=790;DefaultDir=C:\;DBQ=testbook.xls"

rs.Open "select * from testtable1", cn

if rs.eof then
   Response.Write("EOF or BOF")
   Response.End
end if

While Not rs.EOF
    For j = 0 To rs.Fields.Count - 1
       Response.Write( rs.Fields(j).Value )
       Response.Write( "  ")
    Next
    Response.Write ("<br>")
    rs.MoveNext
Wend

'Clean up
rs.Close
cn.Close
set rs = Nothing
set cn = Nothing
%>

By the way the error that you are seeing 0x8007000E ( E_OUTOFMEMORY )

Hope this helps

2008/11/03

patterns & practices: Visual Studio 2005 Team System Guidance - Home

 

patterns & practices: Visual Studio 2005 Team System Guidance - Home

2008/10/31

Delete a Team Project from Team Foundation Server

在Team Explorer中,我們無法直接刪除「Team Project」。那我們該如何刪除不要的Team Project呢?

其實我們可以使用Command Line指令刪除Team Project。首先,先打開Visual Studio 2005 Command Prompt。在這裏面輸入

 

TfsDeleteProject.exe [/q] [/force] [/server:servername] "Team Project Name"


這樣就可以直接刪除Team Project囉!但是請注意,你的帳號密碼是Administrator群組

2008/10/01

Microsoft Office Live Workspace Beta

微軟終於推出Office OnLine版了!!基本上,與Google Document相比,兩者的概念稍微有一點不同!!差別在於

Google Document

  1. 線上編輯器
  2. 檔案即時共用
  3. 快速上傳及保護檔案
  4. 輕鬆儲存和匯出副本

Office Live Workspace

  1. 大量的檔案儲存(超過1000份的Microsoft Office檔案儲存在網路上)
  2. 多人共用,強大的共享設定。可控制到誰只能讀取,誰可以編輯,甚至加上註解)
  3. 可同步Outlook的連絡人、工作及事件清單
  4. 可以在Office中開啟Office Live Workspace上的檔案。
Microsoft Office Live Workspace

2008/09/29

Microsoft SQL Server Data Mining Add-ins for Microsoft Office 2007

如果你安裝的是Office Excel 2007 及 Visio 2007,你可以至下列網站下載安裝這個Add-In

讓你可以透過Excel直接連接SQL Server上的Analysis Service,讓你的Excel 變成商業智慧系統的用戶端。而Visio,則可以當成是Analysis Service的報表。

IIS 7 功能簡介

微軟在最新的作業系統(Vista/Windows Server 2008)中,使用了最新版的IIS – IIS 7.0。而在合計有六個版本的Windows Vista中,每個版本的IIS 7功能也有差異。首先,Windows Vista Starter和Home Editions並不包含IIS,而Windows Vista Home Premium Edition雖然內建IIS 7,但僅包含Web網站的執行功能, 並不包含FTP伺服器端、Web驗證及授權、遠端管理等功能。Windows Vista Business、Enterprise、Ultimate Editions才包含最完整的IIS 7功能,但是與Windows Server 2008相比,仍然少了遠端管理的功能。
那究竟IIS 7有哪些新功能呢?

  • 模組化
    可以依照功能安裝、執行伺服器端的模組,讓你只安裝你想要的模組及功能,其餘的部份都可以選擇不安裝,例如:你的網站使用程式撰寫的驗證功能,所以你甚至可以連Window驗證的模組都可以選擇不要安裝。所以,你可以透過控制台的安裝功能,選擇FTP Service \ Web Management Tools \ World Wide Web Services,而每一個向下都有很多細部選項提供你選擇。
    首見的優點就是降低伺服器資源的耗用(例如:CPU或Memory),並提升Web伺服器的效能。其次的優點,是可以避免不必要的攻擊、而且也能自訂特定目的或功能的專屬伺服器。
  • 管理方式的改進
    提供了兩種管理模式,一是利用MMC圖形管理工具,另一種是命令列工具AppCmd.exe,檔案位於 %WinDir%\System32\InetSrv目錄裏,而且命令列環境的Path變數並沒有預設此路徑。
    AppCmd.exe提供了更簡便、更Power的方式來管理IIS 7,例如:
    AppCmd.exe add backup "MyBackup" -- 備份



  • 充分整合.NET能力

    IIS 7比之前的IIS版本更充分整合.NET能力,IIS 7能執行ASP.NET 2.0 API所開發的模組就是一個最好的證明。IIS 7之所以能夠與.NET更充分整合,最重要的原因是架構的改變。


    在之前的IIS,在處理ASP.NET,基本上與處理PHP、ASP、CGI沒有什麼不同,都是透過IIS ISAPI Extension的方式實作外掛到IIS上。II 7則將 ASP.NET直接整點至IIS核心內,而且也能以ASP.NET模組負責處理IIS 7的諸多種類要求,例如:ASP程式、PHP程式或是靜態的HTML網頁,也因為IIS 7.0核心內直接整合ASP.NET,因此類似ASP程式、PHP程式或是靜態HTML網頁都能使用像表單驗證(Forms Authentication)或輸出快取(Output Cache)等ASP.NET的功能(但需修改IIS 7的設定值)。也因為IIS 7允許以ASP.NET API開發並加入模組,因為開發人員將更容易擴充IIS 7和網站應用程式的功能,甚至自行開發管理IIS 7的程式,例如:以程式控制IIS 7來建製網站或是虛擬目錄。有幾項比較明顯的改變




IIS 7 目前所有的設定都使用Web.config。所以你可以直接把整個網站複製、貼上到別的IIS 7的伺服器上,所有的設定不需要重新設定。(但是SMTP Service,仍然需要meta-base)





若都沒有特別的設定,則IIS 7的預設值則放置在



%WinDir%\System32\InetSrv\Config\Schema\IIS_Schema.xml

2008/09/26

SQL Server 2008 資料壓縮技術 - 簡介

SQL Server 2008 提供了一種資料壓縮技術(只有在SQL Server 2008 Enterprise Edition才有提供),可以讓儲存空間變小,在某些狀況下也能提供更好的效率,當然在某些狀況下,也有可能讓你的系統效能變差,因為壓縮、解壓縮都是要耗損伺服器的CPU資源。

  • 評估

當您在評估是否要使用SQL Server 2008的壓縮技術之前,您可以先執行內建的Stored Procedure:sp_estimate_data_compression_savings
這支內建的Stored Procedure可以幫助您評估是否要使用這個壓縮技術。

SQL Server 2008的壓縮技術分成兩種:

  • Row Compression
  • Page Compression(Include Page Compression)。

至於壓縮原理,不在此贅述。請參考:資料列壓縮 / 頁面壓縮

  • 在應用面上:

對於沒有使用Partition功能的Table,如果資料量很大的時候,大部份都會建立很多Index。您除了可以壓縮資料表外,您甚至可以指定哪些Index要用壓縮,哪些不要。(經常大量使用的Index,就不需要壓縮了)
而Partition Table的話,您則可以指定哪些Partition Table用Row Compression。哪些Partition Table用Page Compression,甚至哪些Partition Table不用Compression。

設定壓縮的SQL Statement很簡單:

ALTER TABLE <tablename> REBUILD
WITH (DATA_COMPRESSION = <ROW / PAGE>)






  • 驗證



您可以利用SQL Profile來監控設定壓縮後的狀況。在SQL Profile中有一種Template:Compression。



另外,壓縮技術也用在備份機制上,讓您的備份檔案變的更小,也變的更快速。您可以在

Task –> Backup –> 在左邊點選「Option」->最下方的下拉式選單中,選擇「Compression Backup」。

2008/09/01

Silverlight 2.0 嚐鮮(六) – WCF

Silverlight 2.0對於遠端通訊能力增強許多,可以透過幾種方式來存取遠端的網路資源,包含WebClient Class、Socket Class以及WCF Service。其中以WCF Service是容易被使用的。

Silverlight 2.0,我們可以在開發的前端介面中直接叫用遠端的WCF Service,不再需要複雜的技術(Java Script/AJAX)來達到這樣的效果,而讓Silverlight 2.0應用程式開發上而言簡化了很多。

我們來撰寫一個範例好了:

撰寫Silverlight元件

利用Expression Blend及Visual Studio 2008 繪製Page.xaml。如下圖所示image
這樣的效果在Silverlight / Expression Blend上一點都不難做,大家可以試做一下。其中只有一個地方比較麻煩,在於圖形的位移上。在Expression Blend的拖拉功能中,我們只能做到移動及旋轉,但是我們沒有辦法做到位移的效果。所以我們可能需要在Expression Blend的Properties視窗中的Transform Section,將X值由0,改成-20,來達到位移的效果,如下圖所示
image 
或是在Page.xaml中撰寫下列這段程式碼

<UserControl x:Class="WCFDemo.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d">
<Grid x:Name="LayoutRoot" Background="White">
<Grid Margin="8,20,23,25" RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform AngleX="0"/>
<RotateTransform Angle="0"/>
<TranslateTransform/>
</TransformGroup>
</Grid.RenderTransform>
<ListBox x:Name="lstProductName" HorizontalAlignment="Stretch" Margin="63,42,121,21" RenderTransformOrigin="0.5,0.5" >
<ListBox.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform AngleX="-20"/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</ListBox.RenderTransform>
</ListBox>
<Button x:Name="btnGetData" Content="Get Data" Click="btnGetData_Click" Height="31" HorizontalAlignment="Right" Margin="0,0,27,21" VerticalAlignment="Bottom" Width="62" d:LayoutOverrides="HorizontalAlignment, VerticalAlignment" RenderTransformOrigin="0.5,0.5">
<Button.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform AngleX="-20"/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Button.RenderTransform>
</Button>
</Grid>
</Grid>
</UserControl>



建立WCF Service



在WCFDemoWeb(Web Site),非Silverlight專案上,按右鍵選擇Add--> New Item,我們會在Silverlight的Section中找到「Silverlight-Enabled WCF Service」,新增這個範本:Service1.svc。

為什麼會在WCFDemoWeb(Web Site)新增WCF Service呢?請記得,因為Silverlight是Run Client,Run在IE裏的,就算它像ASP.NET一般提供.cs檔案讓我們撰寫.NET的程式碼,它仍然是Run在Client端的,包含它的cs檔案。而現在的WCF Service是用來取代原本在Silverlight 1.0的AJAX的功能,所以WCF Service是用來取代原本設計在Web Site上的Web Service,所以我們也只能在Web Site這種專案上找得到「Silverlight-Enabled WCF Service」。所以我們在Silverlight專案上按右鍵選擇Add—>New Item 中是找不到這個範本(Silverlight-Enabled WCF Service)的。


在Service1.svc中加上下列程式碼




[OperationContract]
public ArrayList GetProductName()
{
// Add your operation implementation here
SqlConnection conn = new SqlConnection("Data Source=NB045;Database=AdventureWorks;Integrated Security=True");
conn.Open();
SqlDataAdapter da = new SqlDataAdapter("select * from Production.Product", conn);
DataTable dt = new DataTable();

da.Fill(dt);

ArrayList buf = new ArrayList();
foreach (DataRow row in dt.Rows)
{
buf.Add(row["Name"].ToString());
}

return buf;
//return buf.ToArray(typeof(string));
}





Compiler WCFDemoWeb專案並在Service1.svc上按右鍵選擇「View in Browser」,會打開IE並看到下列的內容image


將先Url複製下來,然後在Silverlight專案上按右鍵:Add Service Reference,並將複製下來的Url貼入Address欄位中按下「Go」按鈕,就可以找到WCF Service,如下圖所示:image


按下OK。我們就可以在Silverlight專案中的Solution Explorer看見它的改變。


image



撰寫呼叫WCF Service的程式碼



由於在Silverlight 2.0中呼叫WCF Service,一定要使用非同步機制。所以在一開始我們必須建立WCF Service物件並將GetProductNameCompleted Event委派出來。並在GetProductNameCompleted委派事件內撰寫將取得的資料如何呈現在Silverlight物件中的相關程式碼。然後在按下Button的事件中呼叫GetProductNameAsyn方法,而非直接叫用GetProductName方法。程式碼如下:




using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ServiceModel;
using WCFDemo.ServiceReference1;

namespace WCFDemo
{
public partial class Page : UserControl
{
private Service1Client srv1 = null;

public Page()
{
InitializeComponent();

BasicHttpBinding binding = new BasicHttpBinding();
EndpointAddress addr = new EndpointAddress("http://localhost:13630/Service1.svc");

//建立Services
srv1 = new Service1Client();
srv1.GetProductNameCompleted += new EventHandler<GetProductNameCompletedEventArgs>(srv1_GetProductNameCompleted);
}

void srv1_GetProductNameCompleted(object sender, GetProductNameCompletedEventArgs e)
{

foreach (string item in e.Result)
{
this.lstProductName.Items.Add(item);
}
}

private void btnGetData_Click(object sender, RoutedEventArgs e)
{
//非同步叫用
srv1.GetProductNameAsync();
}

}
}











Compiler Solution。執行程式就會發現我們可以輕鬆的利用Silverlight達到原本ASP.NET達不到的功能。

image

2008/08/28

Microsoft SQL Server 2005 效能調較 – Script Repository

微軟提供了一連串的SQL Server 2005的範例Script,讓我們可以更方便的即時查詢SQL Server 2005的狀態。個人覺得還蠻有用的,若再進階一點我們還可以調整Script,讓它更方便使用。

這些Script,包含了

  • Buffer Cache
  • CPU and Optimization
  • Indexes and Indexing
  • Input/Output
  • Performance(General)
  • Procedure Cache
  • SQL Text
  • SQLOS
  • Tempdb
  • Transactions and Logging
  • Waitstats

網址:Script Repository: SQL Server 2005

2008/08/26

SQL Server 2008 Sample Database

安裝完SQL Server 2008後,發現沒有範例資料庫。
image
後來在CodePlex找到SQL Server 2008的Sample Database
image

SQL Server 2008 Database Product Sample

Silverlight 2.0 嚐鮮(三)

當安裝完Silverlight 2.0之後。我們開始來寫第一隻Silverlight程式,感受一下新版的好處。

首先開啟VS2008,開啟一個新專案。我們會發現在Project Types-->Visual C#的樹狀目錄下多了一個子目錄:Silverlight,Templates則撰擇其中的Silverlight Application。(同時需指定Project Name / Project Location喔)
image

接著會跳出下列的對話框。由於Silverlight專案是一個Silverlight User Control的專案,所以會要求我們說要加入一個Web Application以方便進行Silverlight的測試。
請注意:Project Type:請選擇Web Application Project。
image

然後VS2008就會開啟整個Silverlight Application。
image

主要的專案結構如下:
BMI Project為真正的Silverlight Project,而BMIWeb則是上述提到的供開發時方便Debug用的Web Application Project。
我們觀察一下Silverlight Project裏預設有兩個檔案。其一是Page.xaml,為Silverlight元件真正所在的檔案,而App.xaml 則可供整個專案使用的全域變數。
BMIWeb中,比較重要的檔案及結構就是BMITestPage.aspx。這個檔案就是debug用的網頁。我們可以在Compiler過後,直接執行這個網頁進行測試及debug。而ClientBin的目錄,則在經過Compiler過後,會自動將BMI Project所產生的 *.xap檔案複製在到這裏,讓BMIWeb能正常執行我們撰寫出來的Silverlight控制項。
image

我們將下列的程式碼,直接覆蓋BMI Project的Page.xaml的XAML原始碼。

<UserControl x:Class="BMI.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300">
<Grid x:Name="LayoutRoot" Background="White">
<Border Margin="80,74,93,123" Background="#FFF0C5C5"/>
<StackPanel Orientation="Vertical" VerticalAlignment="Stretch" Margin="89,88,104,140" HorizontalAlignment="Stretch" Background="#FFCFD3EA">
<StackPanel Orientation="Horizontal">
<TextBlock Text="身高:" Width="50" Margin="5"></TextBlock>
<TextBox x:Name="txtHeight" Width="100" Height="25"></TextBox>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="體重:" Width="50" Margin="5"/>
<TextBox x:Name="txtWeight" Width="100" Height="25"></TextBox>
<Button x:Name="btnCalc" Width="35" Margin="5" Content="計算" Click="btnCalc_Click"></Button>
</StackPanel>
</StackPanel>
</Grid>
</UserControl>



然後,在VS2008 Solution Explorer中點選Page.xaml。按右鍵,選擇啟動「Open in Expression Blend」

image



則會在Expression Blend 2.5中出現下列的畫面

image



我們可以將畫面調整成下列的模樣後,存檔。

image 



然後,回到VS2008中。在Buutton的那一行中,加上一個屬性

Click。利用VS2008的Intellisense功能「New Event Handler」產生相對應的EVent。



 image



打開Page.xaml.cs。我們就可以發現已經產生相對應的Event:btnCalc_Click。

image 



將下列的程式碼貼入btnCalc_Click內




double result = new double();
double weight = Convert.ToDouble(this.txtWeight.Text);
double height = Convert.ToDouble(this.txtHeight.Text);

result = weight / System.Math.Pow(height/100, 2);
System.Windows.Browser.HtmlPage.Window.Alert("您的BMI值:" + result.ToString());



其中比較重要的是最後一行:

System.Windows.Browser.HtmlPage.Window.Alert(“您的BMI值:” + result.ToString());


這一行程式碼代表Silverllight 2.0,可以讓我們的Silverlight的程式碼呼叫原本Html或Browser上的功能,甚至是原本在Html上的JavaScript Function。


重新Compiler程式後。在BMIWeb Project上點選BMITestPage.aspx上按右鍵。執行「View in Browser」。則會出現下面的畫面。



image



請在身高輸入170,體重輸入70。則會跳出一個windows對話框,內容是「您的BMI值:24.22145…」。

image 



恭喜,我們完成了第一隻Silverlight 2.0的程式了。

2008/08/25

Silverlight 2.0 嚐鮮(五) – Template & Style

  • Style

Silverlight 2.0新增了許多的控制項,如同ASP.NET的控制項一樣,它也可以設定外觀。一般而言設定方式如下:

<TextBox Height="30" Width="100" Margin="100,4,4,4" Background="LightBlue" FontSize="12" HorizontalAlignment="Left" VerticalAlignment="Top"></TextBox>



但是針對每一種控制項,甚至是每一個控制項也不是辦法。所以Silverlight 2.0提供了Style的機制,讓我們可以很輕易的用相同的樣式一次設定同一種類的多個控制項外觀,建立具有一致性外觀的Silverlight 2.0 應用程式。



<Grid x:Name="LayoutRoot" Background="White">
<Grid.Resources>
<Style TargetType="TextBox" x:Key="TextBoxStyle">
<Setter Property="Height" Value="30"/>
<Setter Property="Width" Value="100"/>
<Setter Property="Margin" Value="100,4,4,4"/>
<Setter Property="Background" Value="LightBlue"/>
<Setter Property="FontSize" Value="12"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="VerticalAlignment" Value="Top"/>
</Style>
</Grid.Resources>
<TextBox Style="{StaticResource TextBoxStyle}"></TextBox>
</Grid>



其中<Grid.Resources></Grid.Resources>中用來設定樣式。而

<TextBox Style=”{StaticResource TextBoxStyle}”></TextBox>則是在使用樣式。


我們會發現這個TextBox最後呈現的結果會與上述的第一段程式碼一模一樣。


另外,我們是把Style建立在Grid.Resources中,因此這個樣式的有效範圍在Grid當中。若我們想把樣式給場景中的所有控制項來使用,則可以定義在App.xaml的Application.Resource中。

image



  • Template



Style的機制可以針對同一種控制項進行一致性外觀的設定,但是每一個控制項在顯示時還是有可能會有一些些小小的不同,Template機制則可以補足Style機制在這方面的不足。舉例而言:一般應用程式的輸入欄位一定是: 中文說明 +輸入欄位。我們可以利用Template機制再搭配Style達到這個效果。將下列程式碼放置在App.xaml的<Applicaiton></Application>中




<Application.Resources>
<Style x:Key="InputTextBoxStyle" TargetType="TextBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Grid Width="{TemplateBinding Width}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Height="20" FontSize="12" Margin="2" Text="{TemplateBinding Tag}"></TextBlock>
<TextBox Height="20" FontSize="12" HorizontalAlignment="Stretch" Margin="2" Background="LightBlue" Grid.Column="1"></TextBox>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>



另外在Page.xaml中加上一行程式碼



<TextBox Width="200" Tag="姓名:" Style="{StaticResource InputTextBoxStyle}"></TextBox>



這時,我們可以Compiler程式後執行,呈現的畫面如下:


image

2008/08/24

Silverllight 2.0 嚐鮮(四) – Layout Control

Silverlight 2.0中提供了數種Container物件:

  • Canvas
    Silverlight 1.0就提供的物件。置於其中的控制項是以相對於Canvas的左上角位置的方式來進行佈置(相對位置),而且有Group的效果(所有放置在Canvas內的控制項會與Canvas有一致的效果)。
    例如:位移、旋轉…
  • StackPanel
    放置在裏面的控制項可透過垂直或水平的方式來進行佈置。
    透過Margin屬性設定控制項與控制項之間的距離。
  • Grid
    以行(Row)及列(Column)的方式來進行佈置。

除了上述三個佈局用物件之外,還有兩個Container控制項,也可以做為控制項佈置使用,但是請特別注意,這兩個控制項都只能包含一個子控制項(但是可以是上述三種的佈局用物件。例如:子控制項項可以是StackPanel,然後我們可以在這個StackPanel中擺放數個其它控制項)。

  • Border
    適合用於特定物件的外框,呈現的效果是針對內含的控制項而進行的。
    Padding屬性可設定外框及內含控制項的相對距離。
  • ScrollViewer
    讓內含控制項具有卷軸的效果。

讓我們先來看一下StackPanel的效果,將下列程式碼複製到Page.xaml中

<StackPanel>
<TextBlock Text="姓名:"></TextBlock>
<TextBox x:Name="txtName" Height="30" Width="100"></TextBox>
</StackPanel>



我們可以發現畫面會呈現如下:

image


加上Orientation屬性的設定。將程式碼修改如下:





<StackPanel Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="20">
<TextBlock Text="姓名:" Height="30" Width="50"></TextBlock>
<TextBox x:Name="txtName" Height="30" Width="100"></TextBox>
</StackPanel>



效果如下:

image



我們再來看看,Border與Canvas搭配的效果:







<Border Background="LightBlue" Height="40" Width="340" Canvas.Left="10" Canvas.Top="10" CornerRadius="10,10,10,10" BorderBrush="#FFFF0000" BorderThickness="1,1,1,1">
<Canvas Height="35" Width="330">
<TextBlock Text="姓名:" Height="30" Width="60" Canvas.Left="5"></TextBlock>
<TextBox x:Name="txtName" Height="30" Width="200" Canvas.Left="70"></TextBox>
<Button Height="30" Width="50" Content="按鈕" Canvas.Left="275"></Button>
</Canvas>
</Border>



將上述程式碼貼在Page.xaml內,畫面呈現的效果如下:

image


其中BorderThickness可設定四邊的寬度,而CornerRadius則可決定四邊的圓角。



另外一個很重要的容哭:ScrollViewer。請將程式碼修正如下:




<StackPanel Orientation="Vertical">
<Border Background="LightBlue" Height="40" Width="340" Canvas.Left="10" Canvas.Top="10" CornerRadius="10,10,10,10" BorderBrush="#FFFF0000" BorderThickness="1,1,1,1">
<Canvas Height="35" Width="330">
<TextBlock Text="姓名:" Height="30" Width="60" Canvas.Left="5"></TextBlock>
<TextBox x:Name="txtName" Height="30" Width="200" Canvas.Left="70"></TextBox>
<Button Height="30" Width="50" Content="按鈕" Canvas.Left="275"></Button>
</Canvas>
</Border>

<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" Height="100" Width="300">
<TextBlock Height="200" Width="300"
Text="匿名型別的目的是提供一個簡單的途徑將一組唯的屬性封裝在一個物件之中,並且於第一時間不必宣告其明確型別。
er事先無法知道確定型別,必須等到Compiler編譯後,型別才能確定。匿名型別是使用new運算子並搭配物件初始設定式所建立。
查詢運算式的Select子句中,以從來源序列的各個物件傳回屬性子集。
ss型別,由一個或多個公用唯讀屬性組成。不允許其它類型的類別成員,例如方法或是事件。
型別中的成員名稱,編輯器會提供匿名型別成員與要對其進行初始化之屬性相同的名稱。
數時,該變數必須以var建構函式進行初始化。
"

TextWrapping="Wrap" FontSize="10"
></TextBlock>
</ScrollViewer>
</StackPanel>





畫面呈現如下:

image

Code Snippet Editor

Code Snippet是一個很好用的功能,也是個能節省開發時間及成本的作法。初期,我使用內建的Code Snippet,後來在微軟的網站上發現另一組很好用的Code Snippet,基本的語法及常用的寫法都分門別類的擺放及提供相對應的Code(下載點)。

最近我在想,真正對專案開發有幫助的,應該是自訂屬於這個專案專用的程式碼吧。但是要我手工打造或是去研讀相關寫法卻又覺得效益並沒有這麼高。所以找到了兩個Code Snippet Editor Tools:

Snippy – Visual Studio Code Snippet Editor

Snippet 2008 Editor

就我個人而言,我比較喜歡「Snippet 2008 Editor」,因為操作介面簡單好用。

2008/08/23

Silverlight 2.0 嚐鮮(二)

這個部份來說明一下要開發Silverlight 2.0的程式所需要的工具有哪一些:

安裝完後,你就可以利用Microsoft Visual Studio 2008開發Silverlight 2.0的程式囉

請注意:
Expressoin Blend 2.0只能用來開發Silverlight 1.0的程式。若要開發Silverlight 2.0,就只能用Expression Blend 2.5。

Silverlight 2.0 嚐鮮(一)

Sliverlight 由1.0到2.0有了大幅的改變(之前稱之為Silverlight 1.1)。首先,最基本的部份仍然與1.0相同,是以跨平台為主要的設計目標。(無論是Click-Once或是WPF都必須在Client端安裝大於20MB以上的.NET Framework Run-Time)。當然加強了功能,則Silverlight的Run-Time也從原本的1.3MB,變成了4.6MB。在現有的網路環境裏,4.6MB應該可以很迅速的佈署到用戶端。

Silverlight 2.0究竟提供哪些功能:

  • 對Networking的支援。
    例如:REST、WS*/SOAP、POX、RSS以及標準的HTTP Web Service(WCF Service)。
  • Rich WPF-based UI framework。
    • 支援.NET語言。
      例如:VB.NET、C#、JavaScript、IronPython、IronRuby。
    • 內建超過三十幾種的控制項。
      例如:TextBox、CheckBox、RadioButton、StackPanel、Grid、Panel、Silder、ScrollViewer、Calendar、DatePicker、DataGrid、ListBox。
      同時支援了Control Templating的功能,可以透過類似ASP.NET的UserControl機制,自行組合出控制項。
    • 象徵性的支援了LINQ、以及用戶端的Data Catching和Storage機制。

對Networking的支援

這個部份很重要,它讓我們可以利用大家都很熟悉的Web Service技術與Server Side進行溝通,甚至到後端的資料庫取資料。而不需要再像Silverlight 1.0的時候,需要使用AJAX,JavaScript進行複雜的Coding及技術達到這個需求。讓Silverlight 2.0更接近開發Web Application的領域,而不再只是屬於網頁一角的技術(例如:Flash一般,只是網頁上的一部份)。
同時,它也支援跨網域的呼叫,更重要的是它將可以支援Socket。

Rich WPF-based UI framework

由於這組framework包含了Graphics及Animation的engine,讓開發人員可以更輕易的建立RIA(Rich Interactive/Internet Application)。
同時具備建立User Control、Layout Management、Data-Binding、Styles和Template Skining等機制。
Silverlight 2.0 除了內建了超過三十種的控制項之外,另外最吸引人的地方,在於你可以用.NET Code以及類似ASP.NET的開發模式進行,不再需要另外使用其它複雜的技術。而它對.NET 的Class Library的部份支援,讓你可以可以使用更多、更簡單的語法完成一個需求。例如:Collections、IO、Generics、Threading、Globalization、XML及Local Storage。
同時整合了.NET與HTML DOM的API,讓你可以透過Silverlight所支援的語言來撰寫程式碼,同時又可以控制HTML DOM或是與網頁上的JavaScript互動。

2008/08/18

SQL Server 2008安裝心得 – Upgrade SQL Server 2005

這篇文章重點不在於教導或說明如何安裝SQL Server 2008。只是基於讓有些有興趣的人在安裝之前能稍微看一下安裝畫面而已,所以我並沒有針對畫面做多餘或詳細的說明,請見諒!

在安裝Microsoft SQL Server 2008之前,需安裝Microsoft Visual Studio 2008 Service Pack 1 。如果之前曾經安裝Visual Studio 2008 Hotfix或是Service Pack 1(Beta),那麼你就必須先執行Hotfix Cleanup Utility,讓Microsoft Visual Studio 2008恢復成未安裝之前再重新安裝Visual Studio 2008 Service Pack 1

接下來放入Microsoft SQL Server 2008光碟片,會出現歡迎畫面
與之前的版本不同,此次的歡迎畫面複雜的讓我嚇一跳,如下圖所示
image
 image
image
image
image
image 
image
由於此次我要做的是:Upgrade SQL Server 2005。所以我選擇了「Installation」-> 「Upgrade from SQL Server 2000 or SQL Server 2005」。

接下來進行「Setup Support Rules」
image

Setup Support Files
image

完成Support Files的準備後,會進行Upgrade to SQL Server 2008的Setup Support Rules的檢查,檢查的項目可以參考下圖的內容:
image 
輸入產品金鑰
image
License Teams
image 
「Select Instance」:由於是選擇Upgrade from SQL Server 2000 or SQL Server 2005,所以會自動帶出SQL Server 2005原本的Instance
image 
Select Features:由於是選擇Upgrade from SQL Server 2000 or SQL Server 2005,所以所有的Features都是唯讀無法變更。然而,若選擇的是安裝一個全新的SQL Server 2008,則是可以勾選的。
image 
Instance Configuration
image
Disk Space Requirements
image 
Server Configuration
image
Full-text Upgrade
image 
Error and Usage Reporting
image
Upgrade Rules:指Upgrade之前的必要檢查條件。究竟檢查那些項目請參考下圖
image
image
image

通過Upgrade Rules的檢查後,就可以準備進入Upgrade了!
Ready to Upgrade
image
image
image

按下「Upgrade」按鈕後,進行安裝的動作。
image image

完成升級後,會出現一個Complete的畫面,代表你已經完成升級的動作了!
Complete
image
image
image
image
image
接下來,重開機!恭喜你可以開始執行SQL Server 2008了。

在OpenSource中關於MS SQL Server的工具

在微軟的非官方網站:CodePlex 中有許多「Open Source」的專案。其中有一部份是Focus在MS SQL Server,列出幾個我覺得還不錯的專案,供大家參考:

Web-based的SQL Server管理工具
http://www.codeplex.com/SQLWebTools

可以將整個資料庫轉成T-SQL Script
http://www.codeplex.com/ScriptDB

可以比對兩個資料庫的工具
http://www.codeplex.com/DbDiff

SQL Server Express的管理介面
http://www.codeplex.com/ExpressMaint

可以將資料庫中的物件相關的關聯以樹狀顯示
http://www.codeplex.com/SSSDependencies

希望對大家有幫助

2008/06/30

微軟今停產XP 力拱Vista產品

微軟的Windows XP作業系統將於今(30)日起停產,未來該作業系統僅在企業授權市場、DIY隨機版產品低價電腦市場使用,但微軟強調對於XP的安全性支援延續到2014年。在XP停止銷售後,微軟將全力推展Windows Vista作業系統。

.....

微軟副總裁Bill Veghte(比爾維迪)在給所有企業客戶的公開信中表示,微軟將照原訂計畫於6月30日暫停XP的彩盒零售包裝的銷售,及不提供品牌電腦(OEM)安裝銷售。但消費者在幾個情況下仍可獲得XP作業系統,首先是企業客戶購買Windows Vista的商用入門版(Business)、旗艦版(Ultimate)者,可以使用「降級權利」來使用XP的專業版;取得大量授權的企業客戶也有降級使用的權利。另外,DIY電腦市場的隨機版也仍持續提供到明年1月31日。

.....

詳細文章

資料來源:工商時報

2008/06/25

Click-Once的更新技術

使用微軟的ClickOnce技術,我們一直遇到一個問題,就是更新時我們是不是能只更新有修改過的檔案,沒有修改過的檔案為什麼要重覆下載呢?客戶也一直在反應這個問題…為什麼每一次都要全部下載呢??

沒錯!我也一直在思考這個問題,甚至今年到北美Orlando參加Tech-Ed 2008時,也問了負責Click-Once技術的微軟人員。雖然沒有得到答案,但是我最起碼知道了一件事情,其實微軟的ClickOnce是有考慮這件事情的,而它的機制是看每個檔案的Hash Code。那既然有這樣的機制,為什麼它是沒有作用的呢?經過研究之後,發覺是另一件事造成的…

原來…Visual Studio 2005在每一次的編譯後,所有的經過編譯的檔案,無論原始碼是否有修改都會賦予檔案一個全新的Hash Code,也就是因為這樣子,所以讓ClickOnce無法辦別檔案到底是屬於全新的或是沒有修改過的,造成一律都會重新下載的結果!!

所以如果你的Click-Once系統,要達到只下載異動過的檔案,請記得千萬不可以重新Compiler沒有修改程式碼的程式(不能讓它的Hash Code有變化),如此一來,這個檔案在透過ClickOnce部署之後就不會被重新下載囉…

2008/04/11

Word 2007 Error in Vista

Word 2007在經歷過Windows Update之後,竟然…壞了!!

它狀況如下:

  • 開始任何一個Word檔案都無法正常開啟。你必須等到word 2007出現後,再按下開啟,選擇檔案,此時檔案才會開啟
  • 當你開啟word檔案的內容後,你卻發現你試過各種方法都無法將滑鼠游標放置到文件內容上。
  • 此時,我們嚐試開啟word的選項,想調整word的屬性。屬性視窗開啟後,卻發現你無法切換至任何一個選項頁籤。所以無法調整word屬性。
  • 最後,我們只能放棄關閉檔案。word 2007此時卻出現了
    "Microsoft Office has stopped working...." then "....is restarting"(中文版出現的是中文字…)

我嚐試過…重新安裝Office 2007 Service Pack 1 - 無效
利用原版光碟修復Office 2007 - 無效

最後,在網路上找到了修復方式:HKEY_CURRENT_USER\Software\Microsoft\Office\12.0\Word中找到Data的機碼,更名成Old-Data,再重新開啟Word檔。
咦…它終於恢復正常了!真是太感動了…結果是我花了一個下午加上一個晚上搞這個微軟Update所造成的Bug…

2008/04/07

Window-Form in .NET 2.0,如何顯示民國年呢?

在.NET Framework 2.0中提供了一個TaiwanCalendar類別,可以讓你很快速應用程式的日曆欄位都切換至民國年。

CultureInfo info = new CultureInfo("zh-TW");
info.DateTimeFormat.Calendar = new TaiwanCalendar();
Thread.CurrentThread.CurrentCulture = info;



 


你只要在應用程式啟動時,先將Culture切換至zh-TW,並將DateTimeFormat的Calendar物件換成TaiwanCalendar即可。

2008/03/18

如何找到 SQL Server上的效能瓶頸

許多應用程式效能的問題可能都是效能不佳的資料庫查詢語法造成的。我們該怎麼樣知道究竟瓶頸出現在哪裏呢?基本上,SQL Server 2005會收集所執行的查詢之相關資料,這些資料會保留在記憶體中,且在每次重新啟動後開始累積,換句話說,重開機之後這些資料就會消失了。

這些資料,包含了資料表索引、查詢效能及伺服器I/O相關的問題資料。我們可以透過SQL Server Dynamic Management Views (DMV)和相關動態管理函數(Dynamic Management Functions, DMF)來查詢這些資料,用來呈現伺服器狀態,利用來診斷問題及調整資料庫效能。

  • 伺服器等待的原因
  • SELECT TOP 10
    [Wait type] = wait_type,
    [Wait time (s)] = wait_time_ms / 1000,
    [% waiting] = CONVERT(DECIMAL(12,2), wait_time_ms * 100.0
    / SUM(wait_time_ms) OVER())
    FROM sys.dm_os_wait_stats
    WHERE wait_type NOT LIKE '%SLEEP%'
    ORDER BY wait_time_ms DESC;









  • 讀取及寫入




  • SELECT TOP 10 
    [Total Reads] = SUM(total_logical_reads)
    ,[Execution count] = SUM(qs.execution_count)
    ,DatabaseName = DB_NAME(qt.dbid)
    FROM sys.dm_exec_query_stats qs
    CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
    GROUP BY DB_NAME(qt.dbid)
    ORDER BY [Total Reads] DESC;

    SELECT TOP 10
    [Total Writes] = SUM(total_logical_writes)
    ,[Execution count] = SUM(qs.execution_count)
    ,DatabaseName = DB_NAME(qt.dbid)
    FROM sys.dm_exec_query_stats qs
    CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
    GROUP BY DB_NAME(qt.dbid)
    ORDER BY [Total Writes] DESC;









  • 遺漏資料庫索引




  • SELECT 
    DatabaseName = DB_NAME(database_id)
    ,[Number Indexes Missing] = count(*)
    FROM sys.dm_db_missing_index_details
    GROUP BY DB_NAME(database_id)
    ORDER BY 2 DESC;









  • 高成本的遺漏索引




  • SELECT  TOP 10 
    [Total Cost] = ROUND(avg_total_user_cost * avg_user_impact * (user_seeks + user_scans),0)
    , avg_user_impact
    , TableName = statement
    , [EqualityUsage] = equality_columns
    , [InequalityUsage] = inequality_columns
    , [Include Cloumns] = included_columns
    FROM sys.dm_db_missing_index_groups g
    INNER JOIN sys.dm_db_missing_index_group_stats s
    ON s.group_handle = g.index_group_handle
    INNER JOIN sys.dm_db_missing_index_details d
    ON d.index_handle = g.index_handle
    ORDER BY [Total Cost] DESC;









  • 未使用的索引




  • -- Create required table structure only.
    -- Note: this SQL must be the same as in the Database loop given in the following step.
    SELECT TOP 1
    DatabaseName = DB_NAME()
    ,TableName = OBJECT_NAME(s.[object_id])
    ,IndexName = i.name
    ,user_updates
    ,system_updates
    -- Useful fields below:
    --, *
    INTO #TempUnusedIndexes
    FROM sys.dm_db_index_usage_stats s
    INNER JOIN sys.indexes i ON s.[object_id] = i.[object_id]
    AND s.index_id = i.index_id
    WHERE s.database_id = DB_ID()
    AND OBJECTPROPERTY(s.[object_id], 'IsMsShipped') = 0
    AND user_seeks = 0
    AND user_scans = 0
    AND user_lookups = 0
    AND s.[object_id] = -999 -- Dummy value to get table structure.
    ;

    -- Loop around all the databases on the server.
    EXEC sp_MSForEachDB 'USE [?];
    -- Table already exists.
    INSERT INTO #TempUnusedIndexes
    SELECT TOP 10
    DatabaseName = DB_NAME()
    ,TableName = OBJECT_NAME(s.[object_id])
    ,IndexName = i.name
    ,user_updates
    ,system_updates
    FROM sys.dm_db_index_usage_stats s
    INNER JOIN sys.indexes i ON s.[object_id] = i.[object_id]
    AND s.index_id = i.index_id
    WHERE s.database_id = DB_ID()
    AND OBJECTPROPERTY(s.[object_id], '
    'IsMsShipped'') = 0
    AND user_seeks = 0
    AND user_scans = 0
    AND user_lookups = 0
    AND i.name IS NOT NULL -- Ignore HEAP indexes.
    ORDER BY user_updates DESC
    ;
    '


    -- Select records.
    SELECT TOP 10 * FROM #TempUnusedIndexes ORDER BY [user_updates] DESC
    -- Tidy up.
    DROP TABLE #TempUnusedIndexes









  • 高成本的使用中索引




  • -- Create required table structure only.
    -- Note: this SQL must be the same as in the Database loop given in the following step.
    SELECT TOP 1
    [Maintenance cost] = (user_updates + system_updates)
    ,[Retrieval usage] = (user_seeks + user_scans + user_lookups)
    ,DatabaseName = DB_NAME()
    ,TableName = OBJECT_NAME(s.[object_id])
    ,IndexName = i.name
    INTO #TempMaintenanceCost
    FROM sys.dm_db_index_usage_stats s
    INNER JOIN sys.indexes i ON s.[object_id] = i.[object_id]
    AND s.index_id = i.index_id
    WHERE s.database_id = DB_ID()
    AND OBJECTPROPERTY(s.[object_id], 'IsMsShipped') = 0
    AND (user_updates + system_updates) > 0 -- Only report on active rows.
    AND s.[object_id] = -999 -- Dummy value to get table structure.
    ;

    -- Loop around all the databases on the server.
    EXEC sp_MSForEachDB 'USE [?];
    -- Table already exists.
    INSERT INTO #TempMaintenanceCost
    SELECT TOP 10
    [Maintenance cost] = (user_updates + system_updates)
    ,[Retrieval usage] = (user_seeks + user_scans + user_lookups)
    ,DatabaseName = DB_NAME()
    ,TableName = OBJECT_NAME(s.[object_id])
    ,IndexName = i.name
    FROM sys.dm_db_index_usage_stats s
    INNER JOIN sys.indexes i ON s.[object_id] = i.[object_id]
    AND s.index_id = i.index_id
    WHERE s.database_id = DB_ID()
    AND i.name IS NOT NULL -- Ignore HEAP indexes.
    AND OBJECTPROPERTY(s.[object_id], '
    'IsMsShipped'') = 0
    AND (user_updates + system_updates) > 0 -- Only report on active rows.
    ORDER BY [Maintenance cost] DESC
    ;
    '


    -- Select records.
    SELECT TOP 10 * FROM #TempMaintenanceCost
    ORDER BY [Maintenance cost] DESC
    -- Tidy up.
    DROP TABLE #TempMaintenanceCost









  • 常用的索引




  • -- Create required table structure only.
    -- Note: this SQL must be the same as in the Database loop given in the -- following step.
    SELECT TOP 1
    [Usage] = (user_seeks + user_scans + user_lookups)
    ,DatabaseName = DB_NAME()
    ,TableName = OBJECT_NAME(s.[object_id])
    ,IndexName = i.name
    INTO #TempUsage
    FROM sys.dm_db_index_usage_stats s
    INNER JOIN sys.indexes i ON s.[object_id] = i.[object_id]
    AND s.index_id = i.index_id
    WHERE s.database_id = DB_ID()
    AND OBJECTPROPERTY(s.[object_id], 'IsMsShipped') = 0
    AND (user_seeks + user_scans + user_lookups) > 0
    -- Only report on active rows.
    AND s.[object_id] = -999 -- Dummy value to get table structure.
    ;

    -- Loop around all the databases on the server.
    EXEC sp_MSForEachDB 'USE [?];
    -- Table already exists.
    INSERT INTO #TempUsage
    SELECT TOP 10
    [Usage] = (user_seeks + user_scans + user_lookups)
    ,DatabaseName = DB_NAME()
    ,TableName = OBJECT_NAME(s.[object_id])
    ,IndexName = i.name
    FROM sys.dm_db_index_usage_stats s
    INNER JOIN sys.indexes i ON s.[object_id] = i.[object_id]
    AND s.index_id = i.index_id
    WHERE s.database_id = DB_ID()
    AND i.name IS NOT NULL -- Ignore HEAP indexes.
    AND OBJECTPROPERTY(s.[object_id], '
    'IsMsShipped'') = 0
    AND (user_seeks + user_scans + user_lookups) > 0 -- Only report on active rows.
    ORDER BY [Usage] DESC
    ;
    '


    -- Select records.
    SELECT TOP 10 * FROM #TempUsage ORDER BY [Usage] DESC
    -- Tidy up.
    DROP TABLE #TempUsage









  • 邏輯片段的索引




  • -- Create required table structure only.
    -- Note: this SQL must be the same as in the Database loop given in the -- following step.
    SELECT TOP 1
    DatbaseName = DB_NAME()
    ,TableName = OBJECT_NAME(s.[object_id])
    ,IndexName = i.name
    ,[Fragmentation %] = ROUND(avg_fragmentation_in_percent,2)
    INTO #TempFragmentation
    FROM sys.dm_db_index_physical_stats(db_id(),null, null, null, null) s
    INNER JOIN sys.indexes i ON s.[object_id] = i.[object_id]
    AND s.index_id = i.index_id
    WHERE s.[object_id] = -999 -- Dummy value just to get table structure.
    ;

    -- Loop around all the databases on the server.
    EXEC sp_MSForEachDB 'USE [?];
    -- Table already exists.
    INSERT INTO #TempFragmentation
    SELECT TOP 10
    DatbaseName = DB_NAME()
    ,TableName = OBJECT_NAME(s.[object_id])
    ,IndexName = i.name
    ,[Fragmentation %] = ROUND(avg_fragmentation_in_percent,2)
    FROM sys.dm_db_index_physical_stats(db_id(),null, null, null, null) s
    INNER JOIN sys.indexes i ON s.[object_id] = i.[object_id]
    AND s.index_id = i.index_id
    WHERE s.database_id = DB_ID()
    AND i.name IS NOT NULL -- Ignore HEAP indexes.
    AND OBJECTPROPERTY(s.[object_id], '
    'IsMsShipped'') = 0
    ORDER BY [Fragmentation %] DESC
    ;
    '


    -- Select records.
    SELECT TOP 10 * FROM #TempFragmentation ORDER BY [Fragmentation %] DESC
    -- Tidy up.
    DROP TABLE #TempFragmentation









  • I/O的高成本查詢




  • SELECT TOP 10 
    [Average IO] = (total_logical_reads + total_logical_writes) / qs.execution_count
    ,[Total IO] = (total_logical_reads + total_logical_writes)
    ,[Execution count] = qs.execution_count
    ,[Individual Query] = SUBSTRING (qt.text,qs.statement_start_offset/2,
    (CASE WHEN qs.statement_end_offset = -1
    THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
    ELSE qs.statement_end_offset END - qs.statement_start_offset)/2)
    ,[Parent Query] = qt.text
    ,DatabaseName = DB_NAME(qt.dbid)
    FROM sys.dm_exec_query_stats qs
    CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
    ORDER BY [Average IO] DESC;









  • CPU的高成本查詢




  • SELECT TOP 10 
    [Average CPU used] = total_worker_time / qs.execution_count
    ,[Total CPU used] = total_worker_time
    ,[Execution count] = qs.execution_count
    ,[Individual Query] = SUBSTRING (qt.text,qs.statement_start_offset/2,
    (CASE WHEN qs.statement_end_offset = -1
    THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
    ELSE qs.statement_end_offset END -
    qs.statement_start_offset)/2)
    ,[Parent Query] = qt.text
    ,DatabaseName = DB_NAME(qt.dbid)
    FROM sys.dm_exec_query_stats qs
    CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
    ORDER BY [Average CPU used] DESC;









  • 高成本的CLR查詢




  • SELECT TOP 10 
    [Average CLR Time] = total_clr_time / execution_count
    ,[Total CLR Time] = total_clr_time
    ,[Execution count] = qs.execution_count
    ,[Individual Query] = SUBSTRING (qt.text,qs.statement_start_offset/2,
    (CASE WHEN qs.statement_end_offset = -1
    THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
    ELSE qs.statement_end_offset END - qs.statement_start_offset)/2)
    ,[Parent Query] = qt.text
    ,DatabaseName = DB_NAME(qt.dbid)
    FROM sys.dm_exec_query_stats as qs
    CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
    WHERE total_clr_time <> 0
    ORDER BY [Average CLR Time] DESC;









  • 最常執行的查詢




  • SELECT TOP 10 
    [Execution count] = execution_count
    ,[Individual Query] = SUBSTRING (qt.text,qs.statement_start_offset/2,
    (CASE WHEN qs.statement_end_offset = -1
    THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
    ELSE qs.statement_end_offset END - qs.statement_start_offset)/2)
    ,[Parent Query] = qt.text
    ,DatabaseName = DB_NAME(qt.dbid)
    FROM sys.dm_exec_query_stats qs
    CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
    ORDER BY [Execution count] DESC;









  • 遭到封鎖的查詢




  • SELECT TOP 10 
    [Average Time Blocked] = (total_elapsed_time - total_worker_time) / qs.execution_count
    ,[Total Time Blocked] = total_elapsed_time - total_worker_time
    ,[Execution count] = qs.execution_count
    ,[Individual Query] = SUBSTRING (qt.text,qs.statement_start_offset/2,
    (CASE WHEN qs.statement_end_offset = -1
    THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
    ELSE qs.statement_end_offset END - qs.statement_start_offset)/2)
    ,[Parent Query] = qt.text
    ,DatabaseName = DB_NAME(qt.dbid)
    FROM sys.dm_exec_query_stats qs
    CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
    ORDER BY [Average Time Blocked] DESC;









  • 最低計劃重複使用率




  • SELECT TOP 10
    [Plan usage] = cp.usecounts
    ,[Individual Query] = SUBSTRING (qt.text,qs.statement_start_offset/2,
    (CASE WHEN qs.statement_end_offset = -1
    THEN LEN(CONVERT(NVARCHAR(MAX),
    qt.text)) * 2 ELSE qs.statement_end_offset END -
    qs.statement_start_offset)/2)
    ,[Parent Query] = qt.text
    ,DatabaseName = DB_NAME(qt.dbid)
    ,cp.cacheobjtype
    FROM sys.dm_exec_query_stats qs
    CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt
    INNER JOIN sys.dm_exec_cached_plans as cp on qs.plan_handle=cp.plan_handle
    WHERE cp.plan_handle=qs.plan_handle
    ORDER BY [Plan usage] ASC;


如何找到.NET程式中的效能瓶頸

在MSDN 2008年03月號中有一篇文章,介紹我們如何利用Visual Studio 2005 Team Suite Edition or Visual Studio 2005 Developer Edition中的Visual Studio Profiler找到效能瓶頸。

執行效能 - 使用 Visual Studio Profiler 找出應用程式的瓶頸 (繁體中文版)

2008/03/17

Microsoft Team Foundation Server加強版的Project Alerts

一般而言,我們在使用Microsoft Team Foundation Server的Project Alert(Email Notification),只有四種情況可以選擇,造成我們不是想收的Email收不到,就是收到一大堆可能沒有什麼用的Alert。如下圖
image

那究竟我們有什麼方式,可以很簡單、很快速的讓TFS更聰明呢?其實,我們可以利用TFS Web Access加強的功能來達到這個功能,如下圖所示
 image

image

由上圖,你可以發現設定變得更加彈性、方便,甚至可以針對某個專案成員,某種狀態及某種WorkItem,分別去設定相關的Project Alerts。

Microsoft Team Foundation Server的專案檢查清單

在Microsoft Team Foundation Server上的Team Queries中有一個專案檢查清單的查詢!就算由字面上直接解釋,我們也可以很清楚知道,這代表的是專案的Milestone。但是,我們要怎麼樣將相關的WorkItem設定成可以顯示在這上面呢??

其實很簡單,你只要修改WorkItem中的允出準則,由否改成是即可。
image

如此一來,你便可以在Microsoft Team Foundaiton Server上輕易設定專案上的Milestone

2008/03/04

Reuirements Management in TFS

請參考下列的文章

http://blogs.msdn.com/slange/archive/2007/11/06/requirements-management-in-tfs-part-1-of-4-overview.aspx

http://blogs.msdn.com/slange/archive/2007/11/06/requirements-management-in-tfs-part-2-of-4-tfs-out-of-the-box.aspx

http://blogs.msdn.com/slange/archive/2007/11/06/requirements-management-in-tfs-part-3-of-4-integrations.aspx

http://blogs.msdn.com/slange/archive/2007/11/06/requirements-management-in-tfs-part-4-of-4-summary.aspx

2008/03/03

如何利用Web Access Microsoft Team Foundation Server?

一直以來,有個疑問!為什麼Microsoft Team Foundation Server一定要安裝Team Explorer,才能存取Microsoft Team Foundation Server上的資訊?換句話說,如果沒有安裝Microsoft Visual Studio 2005是無法取得Microsoft Team Foundation Server的資訊。

最近,我才發現原來微軟早就考慮到這一點了。在微軟的下載中心(Download Center)中其實早就 Release相關的Solution - Team Foundation Server Web Access

下載的網址:http://www.microsoft.com/downloads/details.aspx?FamilyID=2105C9EE-565E-47B9-A5AC-9A8FF8A07862&displaylang=en

直接安裝在Team Foundation Server上即可喔!!此時,就會有一個Web Site可以直接Access Microsoft Team Foundation Server的資訊而不需要安裝Microsoft Visual Studio 2005。

在安裝的過程中,有兩個地方需要注意:

    • 在安裝之前,Server必須先安裝Team Explorer。
    • 無法利用Web進行Source Code的Check in & Check out...