顯示具有 .NET Framework 標籤的文章。 顯示所有文章
顯示具有 .NET Framework 標籤的文章。 顯示所有文章

2010年1月24日 星期日

Installer 類別裡如何取得實際安裝路徑?

會被帶入 Context.Parameters 的參數裡, 安裝路徑的名稱是"assemblypath"
可以用以下程式追蹤得知安裝程式還帶那些參數進去.

public override void Install(IDictionary stateSaver)
{
base.Install(stateSaver);
string msg = "";
foreach (DictionaryEntry entry in this.Context.Parameters)
{
msg += entry.Key + "," + entry.Value + "\r\n";
}
MessageBox.Show("Install..." + msg);
}

如何清除GAC 的Download cache?

很簡單
gacutil /cdl

就可以了~

參考: http://florent.clairambault.fr/gac-download-cache

2009年5月10日 星期日

ASP.NET Web Site 使用Trace.WriteLine()無效??

ASP.NET 有提供追蹤的功能, 你在網頁是會這樣寫:
Trace.Write("category","message")

這個實際上是System.Web.TraceContext類別. 它當然不會有問題.

這裡說的是System.Diagnostics 命名空間中的Trace 類別.
當你在網頁中撰寫Trace.WriteLine() 的指令時, 會發現無效, 不管是不是在除錯模式下, 它無法被列印出來.

這是因為Visual Studio的Web Site 專案模式, 對於網頁的編譯動作並沒有將TRACE 定義編譯進來, 所以Trace 指令會無效.

因此, 必須修改Web.config 的<system.codedom> 中的 <compiler ...
要加上 compilerOptions, VB 與 C# 的參數不同.
VB
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" warninglevel="4" compilerOptions="/d:TRACE=TRUE" type="Microsoft.VisualBasic.VBCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">

C#
<compiler language="c#;cs;csharp" extension=".cs" warninglevel="4" compilerOptions="/d:TRACE" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">

預設System.Diagnostics.Trace 會輸出到Visual Studio 的Output Window, 可是大部份的情況會想讓他輸出的檔案或事件檢視器, 你可以再加上以下設定:
<configuration> <system.diagnostics> <trace autoflush="true" >
<listeners>
<add name="myListener" type="System.Diagnostics.TextWriterTraceListener, system version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" initializeData="c:\myListener.log" />
<add name="MyEventListener" type="System.Diagnostics.EventLogTraceListener, system version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" initializeData="MyConfigEventLog"/>
</listeners>
</trace>
</system.diagnostics>

另一個問題:
如何ASP.NET 的Trace.Write("category","message") 功能也可以像System.Diagnostics的Trace 一樣可以輸出到檔案或事件記錄檔呢?
答案很簡單:
<configuration>
<system.web>
<trace enabled="true" writeToDiagnosticsTrace="true" />
<system.web>
<configuration>

當然要能成功的輸出必須設定compilerOptions 及 listener

2009年5月2日 星期六

List 的 其他排序選擇

List 有提供 Sort 方法, 當你呼叫它時, 它會根據項目的型別裡實作的IComparable介面的CompareTo方法排序.

同學問到了, 如果我想提供其他的排序方式, 怎麼寫?

可以在項目的型別裡加上新的比較方法:
Shared Function EmpSortByName(ByVal emp1 As Employee, ByVal emp2 As Employee) As Integer
Return emp1.Name.CompareTo(emp2.Name)
End Function

然後在呼叫Sort 方法時指定這個Delegate
Dim employees As New List(Of Employee)
employees.Add(New Employee(101, "Anita", #7/1/1999#))
employees.Add(New Employee(201, "Andy", #7/1/1998#))
employees.Add(New Employee(301, "Lisa", #1/1/2009#))
employees.Add(New Employee(102, "Mary", #7/1/2000#))
employees.Sort(AddressOf Employee.EmpSortByName)

2009年4月13日 星期一

Window Service 如何偵錯?

這是4/12 上 u2956c .NET Framework 課程時同學問的問題.

解法步驟如下:

  1. 首先啟用你寫好的Windows Service
  2. 開啟要偵錯的Windows Service 專案, 並設定中斷點.
  3. 接著Tools --> Attach to Process, 選取服務的Proccess 項目 (如果找不到請勾選 Show processes from all users, 就可找到)

這樣就可以進入Windows 服務的偵錯模式了.

2008年11月26日 星期三

應用程式如何得知 "控制台" --> "地區語言選項" 的改變

系統事件的使用者喜好設定變更時可以藉由 命名空間Microsoft.Win32 的 SystemEvents.UserPreferenceChanged 事件進行通知,

以下程式是註冊該事件

Visual Basic
AddHandler SystemEvents.UserPreferenceChanged, AddressOf SystemEvents_UserPreferenceChanged DisplayCultureInfo()
C#
SystemEvents.UserPreferenceChanged += new UserPreferenceChangedEventHandler(SystemEvents_UserPreferenceChanged);

它的事件參數 UserPreferenceChangedEventArgs 的 Category 屬性會傳入變更的事件類別, 如果是 "地區語言選項" 的改變, 是 UserPreferenceCategory.Locale

事件程序如下:

Visual Basic
Sub SystemEvents_UserPreferenceChanged(ByVal sender As Object, ByVal e As Microsoft.Win32.UserPreferenceChangedEventArgs)
        If e.Category = UserPreferenceCategory.Locale Then
            DisplayCultureInfo()
        End If
    End Sub
C#
static void SystemEvents_UserPreferenceChanged(object sender, UserPreferenceChangedEventArgs e)
{
if (e.Category== UserPreferenceCategory.Locale )
DisplayCultureInfo();
}

Thread.CurrentThread.CurrentCulture 會回傳目前執行緒的文化特性, 只有應用程式載入初期會寫入這個值, 所以控制台改變, 這個值並不會跟著異動, 若要取得控制台最新的文化特性, 必須先將目前的快取資料清除, 呼叫ClearCachedData 方法. 當快取被清除時, 將會自動取得控制台最新的設定.

Visual Basic
    Sub DisplayCultureInfo()
        Thread.CurrentThread.CurrentCulture.ClearCachedData()
        Dim UsersCulture As CultureInfo = Thread.CurrentThread.CurrentCulture
        Dim region As New RegionInfo(UsersCulture.Name)
        Console.WriteLine(region.DisplayName)
        Console.WriteLine(region.EnglishName)
        Console.WriteLine(region.NativeName)
        Console.WriteLine(region.CurrencyEnglishName)
        Console.WriteLine(region.CurrencyNativeName)
    End Sub
C#
private static void DisplayCultureInfo()  
{
Thread.CurrentThread.CurrentCulture.ClearCachedData();
CultureInfo UsersCulture = Thread.CurrentThread.CurrentCulture;
RegionInfo region = new RegionInfo(UsersCulture.Name);
Console.WriteLine(region.DisplayName);
Console.WriteLine(region.EnglishName);
Console.WriteLine(region.NativeName);
Console.WriteLine(region.CurrencyEnglishName);
Console.WriteLine(region.CurrencyNativeName);
}

2008年3月20日 星期四

.NET 可以算出農曆嗎?

答案, 還是Yes!!

.NET Framework (2.0以上)的類別庫中有一個TaiwanLunisolarCalendar 類別(參考: http://msdn2.microsoft.com/zh-tw/library/system.globalization.taiwanlunisolarcalendar.aspx)

這個類別的可看性就多囉!

它與一般的西曆及國曆是很不一樣的, 尤其可能有閏月. 要顯示完整的年月日, 至少要用到以下幾個方法:

  • GetSexagenaryYear
  • GetCelestialStem
  • GetTerrestrialBranch
  • GetMonth
  • GetLeapMonth
  • GetDayOfMonth

下列程式是完整的範例:

        Dim cal As New TaiwanLunisolarCalendar()
Dim now As Date = Date.Now.AddYears(-1)

Dim 天干 As String = "甲乙丙丁戊己庚辛壬癸"
Dim 地支 As String = "子丑寅卯辰巳午未申酉戌亥"

Dim lun60Year As Integer = cal.GetSexagenaryYear(now)
Dim 天干Year As Integer = cal.GetCelestialStem(lun60Year) - 1
Dim 地支Year As Integer = cal.GetTerrestrialBranch(lun60Year) - 1

Dim lunMonth As Integer = cal.GetMonth(now)
Dim leapMonth As Integer = cal.GetLeapMonth(cal.GetYear(now))

If leapMonth > 0 AndAlso lunMonth >= leapMonth Then
lunMonth -= 1
End If
Dim lunDay As Integer = cal.GetDayOfMonth(now)

MessageBox.Show(String.Format("農曆:{0}年{1}月{2}日", _
天干(天干Year) & 地支(地支Year), lunMonth, lunDay))

                TaiwanLunisolarCalendar cal =new TaiwanLunisolarCalendar()  ;
DateTime now = DateTime.Now.AddYears(-1) ;

String 天干= "0甲乙丙丁戊己庚辛壬癸" ;
String 地支= "0子丑寅卯辰巳午未申酉戌亥" ;

int lun60Year = cal.GetSexagenaryYear(now) ;
int 天干Year = cal.GetCelestialStem(lun60Year) ;
int 地支Year = cal.GetTerrestrialBranch(lun60Year) ;

int lunMonth = cal.GetMonth(now) ;
int leapMonth = cal.GetLeapMonth(cal.GetYear(now)) ;

if (leapMonth > 0 && lunMonth >= leapMonth )
{
lunMonth -= 1 ;
}
int lunDay = cal.GetDayOfMonth(now) ;

MessageBox.Show(String.Format("農曆:{0}年{1}月{2}日",
天干[天干Year].ToString() + 地支[地支Year].ToString(), lunMonth, lunDay));

以今天的日期(AddYears(-1))來執行, 得到的結果會是(去年的今天):
農曆:丁亥年2月2日

2008年3月19日 星期三

.NET 會算中華民國曆嗎?

答案是: Yes!!

.NET Framework (2.0以上)的類別庫中有一個 TaiwanCalendar (參考http://msdn2.microsoft.com/zh-tw/library/system.globalization.taiwancalendar.aspx)

不過, 台灣曆法與西曆只有差在紀元的計算, 例如, 西曆的2008年3月18日, 等於中華民國年的97年3月18日.

比較常用的會是它的GetYear方法, 如以下範例:

Dim cal As New TaiwanCalendar
Dim twYear As Integer = cal.GetYear(Date.Now)
MessageBox.Show("現在是中華民國:" & twYear & "年")
如果想直接讓應用程式使用中華民國曆法, 可以這樣寫:
Dim twCI As New CultureInfo("zh-TW")
twCI.DateTimeFormat.Calendar = New TaiwanCalendar()
Thread.CurrentThread.CurrentCulture = twCI
Console.WriteLine(Date.Now.ToLongDateString)

            CultureInfo twCI =new CultureInfo("zh-TW")  ;
twCI.DateTimeFormat.Calendar = new TaiwanCalendar() ;
Thread.CurrentThread.CurrentCulture = twCI ;
listBox1.Items.Add(DateTime.Now.ToLongDateString());

這樣將會印出如下格式的日期:
中華民國97年3月18日