2008年12月31日 星期三

如何在.net程式中加密, Java程式中解密(Encode in .net and decode in java)

Q: 如何在.net程式中加密, Java程式中解密?

A:
.net:
Imports System.Web
...
Me.TextBox2.Text = HttpUtility.UrlEncode(Me.TextBox1.Text)


Java:
import java.net.*;
public class EncodeDecode{
public static void main(String[] args) {
System.out.println= URLDecoder.decode(args[0], "UTF-8");
}
}

2008年11月20日 星期四

以 VS 2008 製作 .net framework 2.0 的安裝專案

Q: IDE 採 VS 2008, 但專案以 .net framework 2.0 開發, 但執行安裝檔時卻需安裝 .net framework 3.5, 應如何處理 ?


A: 可依下列步驟解決:
  1. 在方案總管中的安裝專案按滑鼠右鍵, 選取【屬性】, 畫面如下:


  2. 按【必要條件】, 改勾選【.net framework 2.0】

  3. 在【偵測的相依性】下點選【Microsoft .NET Framework】,修改Version屬性為2.0.50727












Keep coding.

2008年9月29日 星期一

全球化(Globalization)與本地化(Localization)作法

Q: .net 程式如何實作多語系功能?

A: 多語系一般分為全球化(Globalization)與本地化(Localization)兩部份.

  1. 全球化(Globalization):將系統介面改成多國語言, 使用者可依喜好選擇他所要的語言.
  2. 本地化(Localization):針對貨幣、日期、數字等格式,依當地的文化顯示適當的格式.

在VS2005中可直接針對畫面設定Localizable屬性=True,並且切換Language屬性,之後即可依所定語言修改畫面,系統會自動產生資源檔;其他訊息也可每一語言自訂一資源檔儲存。

接著在程式中設定語系即可切換不同語系的系統介面,程式如下:

' 設定系統介面,即全球化(Globalization)

Thread.CurrentThread.CurrentUICulture = new CultureInfo(“zh-tw”)

' 設定貨幣、日期、數字等格式,即本地化(Localization)

Thread.CurrentThread.CurrentCulture = new CultureInfo(“zh-tw”)

That's all.

2008年8月20日 星期三

如何使用AJAX Javascript library?

Q: 如何使用AJAX Javascript library, 改變Radio Button的選項 ?

A: AJAX Javascript library 包含一個 $get 函數, 可輕易取得HTML控制項及asp.net server控制項,例如,表單上有一TextBox1控制項,只要在Javascript中使用

$get('TextBox1').value='test';

就可以在client端改變TextBox1控制項的內容了。


我作了一個簡單的例子,改變Radio Button的選項,程式如下:

只要使用$get('RadioButton1').checked = true; 就可以改變Radio Button的選項,很簡單吧!
但是進一步的問題來了, 如果使用Master Page該怎麼辦? 我的解法是在asp.net server端網頁產生上述的function, 秘訣是以 me.RadioButton1.ClientID 取得控制項名稱,加到 $get() 中。
mScript &= vbNewLine & "function setRadioButton(){ "
mScript &= "$get('" & Me.RadioButton1.ClientID & "').checked = true;"
mScript &= "}"
ClientScript.RegisterClientScriptBlock(GetType(XXX), "RadioButtonFunc", mScript)
其中XXX是類別名稱(class name)。

2008年7月23日 星期三

如何在執行階段指定SQLDataSource的參數值?

Q: SQLDataSource的SQL指令可以指定參數, 並繫結控制項、session、cookie或Query String值, 不幸的是要指定的變數值非以上任何一種, 應如何在執行階段指定參數值?

A: 很簡單, 只要在SqlDataSource1_Selecting 或其他 -ing的事件中指定即可, 例如下例, 指定參數userid值為login的用戶代號:
e.Command.Parameters("@userid").Value = User.Identity.Name

** 切不可使用
SqlDataSource1.SelectCommand &= " where userid = '" & User.Identity.Name & "'"

2008年7月20日 星期日

變數轉型的三種指令

Q: 我們常要在執行時期使用 FindControl 抓取某一控制項的屬性, 在存取屬性時須先轉換變數, 應該如何處理?

A: 轉換變數有三種方法:
1. CType
Ctype(obj, TextBox).Text --> 將 obj 轉為TextBox型態, 並取得Text屬性值
2. DirectCast, 参數與CType相同, 效率較佳, 但原始型別必須與欲轉換的型別完全相同, 縮小也不可。

3. TryCast, 参數與CType相同, 差別是轉換失敗也不會產生錯誤(exception), 只會將obj設為nothing。

2008年7月10日 星期四

response.redirect 不可出現在try...catch 中

Tips:response.redirect 不可出現在try...catch 中

response.redirect 會產生 exception, 而出現靈異現象, 例如

Try
...
connection1.Close()
Response.Redirect("CompanyGroup1.aspx")
Catch ex As Exception
Try : objTransaction.Rollback() : Catch : End Try
AlertMessage(Replace(Replace(Replace(ex.Message, """", ""), "'", ""), vbNewLine, "")) : Exit Sub
End Try

2008年7月3日 星期四

自動調整ComboBox寬度

Q:如何自動調整ComboBox寬度, 使其下拉自動展為最適合寬度?

A:加一ComboBox事件如下
Private Sub ComboBox1_DropDown(ByVal sender As Object, ByVal e As System.EventArgs)_
Handles ComboBox1.DropDown
Dim senderComboBox As ComboBox = DirectCast(sender, ComboBox)
Dim width As Integer = senderComboBox.DropDownWidth
Dim g As Graphics = senderComboBox.CreateGraphics()
Dim font As Font = senderComboBox.Font
Dim vertScrollBarWidth As Integer = _
IIf((senderComboBox.Items.Count > senderComboBox.MaxDropDownItems), _
SystemInformation.VerticalScrollBarWidth, 0)

Dim newWidth As Integer
For Each s As String In DirectCast(sender, ComboBox).Items
newWidth = CInt(g.MeasureString(s, font).Width) + vertScrollBarWidth
If width < width =" newWidth" dropdownwidth =" width" graphics =" senderComboBox.ComboBox.CreateGraphics()

2008年6月14日 星期六

ThreadPool 的用法

在多層式架構(N Tier Architecture)下, 中介層(Middle Tier)擔任工作分派(Dispatch)的任務, 接受前端程式的委託, 將各項工作以非同步方式同時執行, 執行後再將結果傳回; 這時我們常會碰到一個問題, 若前端程式的短時間內委託的工作過多, 會造成中介層負擔過重, 可能會使伺服器當機。因此中介層必須設定工作佇列(Task Queue), 讓過多的工作緩一緩, 等待前面委託的工作處理完, 再從佇列中取出執行, 這就是ThreadPool的功能。

以下是一個簡單的console程式範例, 唯一要注意的是執行緒內一定要用try...catch, 讓執行緒能正常結束。

Imports System
Imports System.Threading
Module Module1
' 非同步工作總數
Private mTaskCount As Integer = 3
Sub Main()
Dim mCompletionEvent As New AutoResetEvent(False) '全部工作完成的通知事件
Dim objStopWatch As New Stopwatch ' 馬錶
objStopWatch.Start() ' 啟動馬錶

' 設定集區的最大執行數及IO數
ThreadPool.SetMaxThreads(1, 1)

' 所有工作送入集區
For i As Integer = 1 To mTaskCount
' 設定執行緒參數
Dim objThreadParameters As New ThreadParametersClass
objThreadParameters.mThreadNumber = i
objThreadParameters.mCompletionEvent = mCompletionEvent

' 工作送入集區
ThreadPool.QueueUserWorkItem(New WaitCallback( _
AddressOf MyAsyncOperation), objThreadParameters)
Next
' 等待全部工作完成的事件通知
mCompletionEvent.WaitOne()

' 停止馬錶並顯示耗費時間
objStopWatch.Stop()
MsgBox(objStopWatch.ElapsedMilliseconds)
End Sub


' 執行緒之工作內容
Sub MyAsyncOperation(ByVal mThreadParameters As Object)
' 取得參數
Dim objThreadParameters As ThreadParametersClass = _
CType(mThreadParameters, ThreadParametersClass)
' 擷取錯誤
Try
Console.WriteLine("WorkItem {0} thread: Performing asynchronous operation.", _
objThreadParameters.mThreadNumber)

' 製造錯誤
If objThreadParameters.mThreadNumber = 2 Then
Dim ds As New DataSet
Console.WriteLine(ds.Tables(0).Rows(0).Item(0))
End If
' 停5秒
Thread.Sleep(5000) ' Sleep for 5 seconds to simulate doing work
Catch
Finally
' 待完成工作數減一
If Interlocked.Decrement(mTaskCount) = 0 Then
CType(objThreadParameters.mCompletionEvent, AutoResetEvent).Set()
End If
End Try
End Sub

' 參數定義
Public Class ThreadParametersClass
Public mThreadNumber As Integer

' ' *****不能使用 new, 因為要使用公共變數 *****
Public mCompletionEvent As AutoResetEvent
End Class
End Module

2008年5月26日 星期一

新電腦語言的介紹

這一期的MSDN雜誌介紹各種新電腦語言的特色, 簡潔扼要, 值得一讀。
http://msdn.microsoft.com/en-us/magazine/cc507636(printer).aspx

摘要如下:

  1. Functional Programming: 將電腦計算視為數學運算式的解析, 把問題拆成多個function, 之後再將各個function串連起來算出答案, 其實就是所謂的 Devide-And-Conquer, 聽起來很像模組化(Modulization), 但是Functional Programming是將一個function放入另一個function的參數, 以這種方式串連出整個程式架構。目前微軟產品有F#。
  2. Dynamic Languages: 不像傳統的Static Language, 執行前先compile, 若型別有錯, 就會產生編譯錯誤, Dynamic Languages會在run time時才依據程式當時狀態決定變數型態, 例如作者舉的例子:
    animal = dock.new()
    animal = cow.new()
    animal 可以是dock物件, 也可以事後改為cow物件

    聽起來又很像早期變數不用宣告的Basic Intepreter.
  3. LINQ: Microsoft力推的物件查詢語言, 提供類似SQL的語法操作各種類型的物件, 例如Database、XML、Object等, 值得注意的是PLINQ, 它是平行運算的LINQ, 搞不好就是微軟雲端運算(Cloud Computing)的要角。

2008年4月25日 星期五

設定建置前/後事件之動作

Q: 如何在VS.net IDE中設定建置前/後事件之動作?

A: 有時候我們建置執行檔後, 希望複製執行檔製特定目錄, 以便測試或發行, 這時我們可以在VS.net IDE中設定建置前/後事件所要執行的DOS指令.

1. 打開專案屬性頁, 切換到【編譯】(Build)頁籤,點選【建置事件...】按鈕, 如下:

2. 輸入DOS指令,可利用巨集以存取專案相關目錄、檔名或其它屬性,例如下列指令將所有輸出檔複製到bin\exe目錄:

xcopy /y /s $(TargetDir)*.* $(TargetDir)..\exe

可輸入多行指令, 或使用批次檔, 撰寫複雜的邏輯。

2008年4月11日 星期五

今天看了一篇 AJAX enabled Gridview 的文章, 寫得有點簡略, 重新給它整理一下, 希望有志之士能較快速上手。

  1. asp.net網站下載 ASP.NET Ajax Extension 及 ASP.NET Ajax Control Kit, 並安裝.
  2. 新增一個 ASP.NET Ajax Enabled Web Site
  3. 將 AjaxControlToolkit.dll (Ajax Control Kit) 加入參考
  4. 加入一個 Textbox、GridView、Button
  5. 設定GridView的資料來源, 連接至資料庫, 並設參數連接至 Textbox
  6. 加入一個UpdatePanel、UpdatePanelAnimationExtender
  7. 將GridView拖入UpdatePanel
  8. 設定UpdatePanelAnimationExtender的TargetID=UpdatePanel1
  9. 設定UpdatePanel的Trigger為Button1.Click
  10. 設定UpdatePanel的UpdatePanelAnimationExtender1文字為...
  11. 在Button1.Click事件中, 撰寫程式如下:
    System.Threading.Thread.Sleep(2000)
    Me.GridView1.DataBind()

2008年4月10日 星期四

SQL指令LIKE 的用法

Q: SQL指令中的LIKE有何使用技巧?

A: LIKE 主要是搭配萬用字元, 以類似Regular Expression的方式篩選資料, 舉例如下:

  • 找出【台】開頭的公司
    Select * from Company where CompanyName like '台%'
  • 找出【台】結尾的公司
    Select * from Company where CompanyName like '%台'
  • 找出【台】開頭且只有兩個字的公司, 如台泥、台塑, 但【台石化】就不符合了
    Select * from Company where CompanyName like 台_'
  • 找出【台】開頭且第二個字為【泥】或【南】的公司, 如台泥、台南, 但【台肥】、【台鳳】就不符合了
    Select * from Company where CompanyName like 台[泥南]'
  • 找出【台】開頭且第二個字筆畫介於【泥】與【南】之間的公司, 如台泥、台肥, 但【台鳳】就不符合了
    Select * from Company where CompanyName like 台[泥-南]'
  • 反之, 要找出【台】開頭且第二個字為【泥】或【南】的公司, 只要加個^,代表否定的意思
    Select * from Company where CompanyName like 台[^泥南]'

2008年4月8日 星期二

如何將MSQL備份資料庫放上其他的Server

Q: 如何將MSQL備份資料庫放上其他的Server

A: 步驟如下
1. 登入
mysql -u root -D mysql
2. 新增一個user
INSERT INTO user (Host,User,Password) VALUES('%','user1',PASSWORD('pwd1'));
3. Create database
create database newdb
4. 指定database
use newdb
5. 執行備份後的資料庫指令 (目錄分隔"\"須以"\\"替代)
source c:\\20080409 1159.sql
6. 授權
grant all privileges on newdb.* to user1@localhost;

2008年4月7日 星期一

MySQL 初入門

1. 安裝
在Windows下安裝有兩種, 一為註冊為Windows Service, 開機自動啟動, 另一種為手手動開啟.

2. 手動開啟

  • 開啟:在安裝目錄下, double click start.bat
  • 關閉:在安裝目錄下, double click shutdown.bat

3. 輸入SQL指令

  • Connect:mysql -D {database} -u {user id} -p {password}
  • Execute SQL:select * from {table_name}

4. Backup/Restore

  • Backup:mysqldump -u root {database} [{table_name}] {output_file}
  • Restore

mysql -u root -p {password}

create database aaa

use {database_name}

source ~/{output_file}

2008年4月4日 星期五

ITIL 簡介

ITIL(IT Infrastructure Library) 為1980年代英國政府支持的一項計畫, 主要是規範資訊技術服務管理的架構,西元2000年發表第二版,強調IT Service的主要流程,例如

  • 事件管理(incident management)
  • 問題管理(problem management)
  • 變更管理(change management)
  • 組態管理(configuration management)
  • 風險管理(risk management)

西元2004年發表第三版, 強調How to do,而非What to do,提供最佳實務(best practice)作法,全部文件包括五部分:
  • 服務策略(Service Strategy)
  • 服務設計(Service Design)
  • 服務移轉(Service Transition)
  • 服務運作(Service Operation)
  • 持續服務改善(Continuous Service Improvement)

2008年3月25日 星期二

Treeview 的 ExpandDepth 屬性無作用

Q: 我以 unbound的方式建立Treeview 的節點, 產生後設定ExpandDepth 屬性卻無作用, 應如何解決?

A: 先展開所有節點, 再以程式自行收合至特定層級, 程式如下:
mRootNode.ExpandAll() ' mRootNode:為根節點, 先展開所有節點
CollapseTreeNodes(mRootNode) '以遞迴方式找到特定層級, 收合節點

Sub CollapseTreeNodes(ByVal mNode As TreeNode)
For Each mSubRootNode As TreeNode In mNode.ChildNodes
' DropDownListLevel.SelectedValue 為特定層級
If mSubRootNode.Depth = DropDownListLevel.SelectedValue Then
mSubRootNode.Collapse() ' 特定層級, 收合節點
ElseIf mSubRootNode.Depth < color="#660000">' 若為特定層級以上之節點, 繼續往下搜尋子節點
End If
Next
End Sub

2008年3月24日 星期一

使用SELECT比較區間值

Q: 如何以簡潔的語法, 作多重區間值的比較?

A: 用If ...ElseIf...End If, 寫多重比較, 程式會像樓梯愈走愈往右, 很難一目瞭然, 用Select ... Case就漂亮多了。

Sub Main()
Dim IntPurchaseOrderID = 11
Dim StrPurchaseOrderNumber As String
Select Case IntPurchaseOrderID
Case Is < 10
StrPurchaseOrderNumber = "00000" & IntPurchaseOrderID
Case Is < 100
StrPurchaseOrderNumber = "0000" & IntPurchaseOrderID
Case Is < 1000
StrPurchaseOrderNumber = "000" & IntPurchaseOrderID
Case Is < 10000
StrPurchaseOrderNumber = "00" & IntPurchaseOrderID
Case Is < 100000
StrPurchaseOrderNumber = "0" & IntPurchaseOrderID
Case Else
StrPurchaseOrderNumber = CStr(IntPurchaseOrderID)
End Select
Console.WriteLine(StrPurchaseOrderNumber)
Console.ReadLine()
End Sub

2008年3月22日 星期六

設定與擷取程式的結束碼(Exit Code)

Q: 我希望在Workflow中執行外部程式, 如果成功, 則繼續執行另一個外部程式, 否則就將錯誤代碼寫入log. 首先需要設定與擷取外部程式的結束碼(Exit Code) , 程式該怎麼作呢?

A: 分成兩部分解釋:
1. 設定程式的結束碼
Sub Main()
Environment.ExitCode = 99
End Sub
2. 擷取外部程式的結束碼
Dim filename As String = "H:\TestExitCode.exe"
Dim pInfo As ProcessStartInfo = New ProcessStartInfo(filename)
pInfo.WindowStyle = ProcessWindowStyle.Normal
pInfo.WorkingDirectory = Environment.CurrentDirectory
Dim p As Process = Process.Start(pInfo)
p.WaitForExit()
mExitCode = p.ExitCode

2008年3月20日 星期四

抓取網頁的最短程式

Q: 如何在.net中抓取網頁?

A: 要抓取網頁可以呼叫System.Net命名空間中的 WebClient 或 WebRequest 類別, 其中WebClient 較簡單, 只要幾行就搞定了。

Dim myClient As WebClient = New WebClient()
Dim response As Stream = myClient.OpenRead _("http://www.contoso.com/index.htm")
Dim Buffer(10240) As Byte
Dim Buffer_all(1024000) As Byte
Dim bytesread As Integer
Dim length As Integer
length = 10240
' 從資料流讀取,並將任何資料寫至主控台。
' *** bytesread 不等於 length
Dim sb As New StringBuilder
Dim i As Integer = 0
bytesread = response.Read(Buffer, 0, length)
Do While (bytesread > 0)
Array.Copy(Buffer, 0, Buffer_all, i, bytesread)
i = i + bytesread
bytesread = response.Read(Buffer, 0, length)
Loop
' 完成後關閉資料流。
response.Close()
MsgBox(System.Text.Encoding.UTF8.GetString(Buffer_all, 0, i))

2008年3月11日 星期二

取得 Enum 的資訊

Q: 使用Enum取代 hard code, 是一個很好的coding方式, 但是, 要如何取得enum的所有內容及個數呢? (以免又 hard code !!)

A: .net 提供標準函數, 可將enum的元素名稱轉成陣列, 範例如下:

Public Enum FormulaElement
Sheet
Row
Column
Formula
RowCount
ColumnCount
End Enum

Public mArrayFormulaElement() As String = _
System.Enum.GetNames(GetType(FormulaElement))

Public mFormulaElementCount As Integer = _
System.Enum.GetNames(GetType(FormulaElement)).Length

2008年2月25日 星期一

中文全形/半形轉換

Q:
如何作全形/半形轉換?

A:
原來以為要判斷第一個byte的ASCII大小, 沒想到 .net 提供一個簡便函數, 專門處理這項工作, 實在太帥了.

  • 全形轉半形

Strings.StrConv(mDigit, VbStrConv.Narrow, 0)

  • 半形轉全形

Strings.StrConv(mDigit, VbStrConv.Wide, 0)

日文字串也可以, 我想所有DBCS也都可以吧.

That's all, keep coding!!

2008年2月24日 星期日

指定表單預設欄位及按鈕

Q:
不管是Web Application 或 Windows Application, 使用者都會要求表單顯示時, 游標必須擺在第一欄, 而且按Enter時會觸發最常使用的按鈕, 這要怎麼做呢?

A: 使用.net 2.0 or above

Web Form

  • 招式一

在 html 的 form 標籤直接加入defaultbutton、defaultfocus屬性如下:

<form id="form1" runat="server" defaultbutton="Button2" defaultfocus="TextBox2">

  • 招式二

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

If Page.IsPostBack = False Then

Me.Form.DefaultButton = Button2.UniqueID

Me.Form.DefaultFocus = TextBox2.UniqueID

End If

End Sub

  • 招式三

使用Master Page時, form 標籤在主板網頁, 無法直接指定, 須調整一下姿勢, 如下:

Page.Form.DefaultButton = Button2.UniqueID

Page.Form.DefaultFocus = TextBox2.ClientID

Windows Form

  • 指定游標所在欄位, 只要將該欄的 TabIndex 屬性設為0即可
  • 要指定Enter預設按鈕, 則要修改【表單】的AcceptButton屬性為某一控制項即可
  • 另外要指定【取消】(Esc)的預設按鈕, 則要修改【表單】的CancelButton屬性

That's all, keep coding.

2008年2月19日 星期二

.net 建置時出現 lc.exe 錯誤

.net 建置時出現 lc.exe 錯誤, vs IDE無任何詳細訊息, 通常原因是引用third party元件, 並將專案複製給他人使用時產生錯誤, 處理方法有二:

A方案

  1. 先關閉vs 2005
  2. 至專案的My Project目錄刪除license.licx 檔案
  3. 開啟vs 2005
  4. 執行重建該專案,此時在「方案總管」會出現 license.licx 驚嘆號,對 license.licx 按滑鼠右鍵,選擇刪除,再重建該專案就 OK 了。

B方案

  1. 重新產生一個新專案
  2. 先加入third party元件, 再複製原專案所有程式即可

PS. A方案為同事Frank所想出的方式, 給他拍拍手.

That's all, keep coding.

2008年2月18日 星期一

Linux 效能調校心得

這兩天同事反映Linux server效能不彰, 嚴重影響應用程式效能, 但因之前也未接觸過Linux, 事情來了, 也只好硬著頭皮上場了, 之下是我的一些租淺看法:

  1. top指令: 監看CPU、Memory的使用量, 定時更新, 有很多指令可用, 例如排序、自訂欄位、調整process priority ...等, 還蠻好用的, 只差I/O資料
  2. iostat、vmstat指令: 監看I/O資料,可配合watch指令, 定時更新, 例如 watch -n 2 iostat, 不幸的事我們的Server好像偵測不到變化值, 希望善心人士能惠賜高見.
  3. nice指令: 可指定程式執行的優先等級,等級由 -19 ~ 20, 愈小等級愈高
  4. renice指令: 可調整執行中的程式(Process)優先等級, top指令也有提供, 我在top指令設定成功, 但直接下renice卻失敗, why ? :-(
  5. 心得:
    1) 發現java 的CATALINA_OPTS 環境變數設在profile中, 造成每一個Java程式都占據大量的memory, 使系統一直在作Swap。
    2) 用nice啟動較重要的程式, 給予優先等級
    3) Tomcat需要較大的heap memory, 可在tomcat/bin 目錄的setenv.sh 檔案設定
    set JAVA_OPTS=-server -XX:+UseParallelGC -Xmx768m -XX:MaxPermSize=160m -Djava.awt.headless=true

    *** xmx: max heap size
    *** server mode : 指示JVM採取run-time optimization

為了Linux, 最近度數又要增加了. 預告下次要寫一篇【眼睛保健】的文章與大家分享.

Keep coding.

2008年2月17日 星期日

建立 IE 的右鍵選單(Context Menu)

今天看了一篇關於『如何建立 IE 的右鍵選單(Context Menu)』的文章, 網址如下:
http://www.codeproject.com/KB/menus/IE_Context_Menu_Installer.aspx

它是以C#安裝專案為例子, 說明如何建立右鍵選單, 我試著以VB.NET直接產生右鍵選單, 效果還不錯, 步驟如下:

  1. 建立VB.NET 2005視窗專案
  2. 在Form1放入兩個Button
  3. 打開『程式碼檢視』, 輸入下列程式

  4. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim mSubKey As Microsoft.Win32.RegistryKey = My.Computer.Registry.CurrentUser.CreateSubKey("SOFTWARE\Microsoft\Internet Explorer\MenuExt\Sample Action")
    '1,2,4,8,10,20 in heximal are 1,2,4,8,16,32 in decimal (respectively)
    ' 0x1:Default, 0x2:Images, 0x4:Controls, 0x8:Tables, 0x10:Text selection, 0x20:Anchor
    Dim keyValueInt As String = "16"
    mSubKey.SetValue("Contexts", Convert.ToInt32(keyValueInt), Microsoft.Win32.RegistryValueKind.DWord)
    mSubKey.SetValue(Nothing, "file://" & Application.StartupPath & "\action.htm")
    mSubKey.Close()
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    My.Computer.Registry.CurrentUser.DeleteSubKey("SOFTWARE\Microsoft\Internet Explorer\MenuExt\Sample Action")
    End Sub

  5. 再產生一個檔action.htm, 放在執行目錄中, 內容如下:
    http://www.box.net/shared/nz3cngvsw0
  6. 按F5執行, 執行第一個按鈕
  7. 開啟一個新的IE, 選擇一段文字, 按右鍵, 即可看到Sample Action選單

That's all, keep coding.

2008年2月14日 星期四

部署 Html 編輯器

從網路上可以找到不少Html 編輯器的控制項, 例如下列網址 : http://windowsclient.net/articles/htmleditor.aspx

使用起來很方便, 功能也很帥, 但是部署時卻發生兩個問題:
1. ieframe.dll 無法註冊
2. 程式死當, 微軟要我們向他報告, 且保證不回覆, #$%^&

還好努力找了一陣子, 才把它搞定了.
1. ieframe.dll 無法註冊, 那就在部署專案中排除它
2. 程式死當, 是因為.net 2.0不再支援 ActiveX的..., 必須copy mshtml.dll 至應用程式目錄下.


That's all :-) , Keep Coding !!

PS.
其實可以直接用 .net 2.0 所提供的控制項再加上ExecCommand, 就可以製作一個類似的Html 編輯器了, 只是已經搞定, 就算了.

產生SQL Server 的DB Schema文件

網際網路上有許多產生DB schema的作法, 今天看到一個滿簡單的, 介紹給大家:
http://www.codeproject.com/KB/database/SQL_DB_DOCUMENTATION.aspx?msg=2424192#xx2424192xx

作法:

  1. 解開附件Script_to_generate_DB_Document.zip
  2. 執行Query Analyzer(SQL 2000) 或SQL Server Management Studio(SQL 2005)
  3. 選定要製作文件的資料庫(Use xxx)
  4. 點選選單, 查詢>結果至>將結果存檔, 或直接按 CTRL+Shift+F
  5. 執行Script_to_generate_DB_Document.sql內容

That's all :-)

2008年2月3日 星期日

資料庫存取速度提升

我們通常使用索引來提升SQL指令的執行速度, 其實做大量資料更新時還有一個簡單的地方可以提升速度, 就是使用交易(Transaction), 新增一萬筆資料至MS SQL Server, 大約快了三倍多, 測試程式如下:
1. 不使用交易
Dim cnn As New SqlConnection("server=.;database=sampledb;integrated security=sspi;")
cnn.Open()

Dim MyWatch As New Stopwatch
MyWatch.Start()
Dim mycommand As New SqlCommand()
mycommand.Connection = cnn
Dim n As Integer
Try
mycommand.CommandText = "truncate TABLE ex1;"
mycommand.ExecuteNonQuery()
Catch
End Try

For n = 0 To 10000 - 1
mycommand.CommandText = String.Format("INSERT INTO ex1 (a,b,c) VALUES('a','c',{0})", n + 1)
mycommand.ExecuteNonQuery()
Next
MsgBox("MyWatch.ElapsedMilliseconds=" & MyWatch.ElapsedMilliseconds)

2. 使用交易
Dim cnn As New SqlConnection("server=.;database=sampledb;integrated security=sspi;")
cnn.Open()

Dim MyWatch As New Stopwatch
MyWatch.Start()
Dim mycommand As New SqlCommand()
Dim mytransaction As SqlTransaction = cnn.BeginTransaction
mycommand.Connection = cnn
mycommand.Transaction = mytransaction
Dim n As Integer
Try
mycommand.CommandText = "truncate TABLE ex1;"
mycommand.ExecuteNonQuery()
Catch
End Try

' use transaction to make the process more quick
For n = 0 To 10000 - 1
mycommand.CommandText = String.Format("INSERT INTO ex1 (a,b,c) VALUES('a','c',{0})", n + 1)
mycommand.ExecuteNonQuery()
Next
mytransaction.Commit()
MsgBox("MyWatch.ElapsedMilliseconds=" & MyWatch.ElapsedMilliseconds)

3. 不使用交易, 但採用批次更新, 比第一種快1/5
Dim cnn As New SqlConnection("server=.;database=sampledb;integrated security=sspi;")
cnn.Open()

Dim MyWatch As New Stopwatch
MyWatch.Start()
Dim mycommand As New SqlCommand()
mycommand.Connection = cnn
Dim n As Integer
Try
mycommand.CommandText = "truncate TABLE ex1;"
mycommand.ExecuteNonQuery()
Catch
End Try

Dim da1 As New SqlDataAdapter()
da1.InsertCommand = mycommand
da1.UpdateBatchSize = 10000
For n = 0 To 100000 - 1
mycommand.CommandText = String.Format("INSERT INTO ex1 (a,b,c) VALUES('a','c',{0})", n + 1)
da1.InsertCommand.ExecuteNonQuery()
Next
MsgBox("MyWatch.ElapsedMilliseconds=" & MyWatch.ElapsedMilliseconds)

2008年2月2日 星期六

設定(Setting)與資源(Resources)的差別

Q: VS.net專案在My Project中具有設定(Setting)與資源(Resources)兩個頁籤, 都可以設定字串, 我一直搞不懂兩者有甚麼差別? 它們個字的使用時機為何呢?

有一天當我試圖要做多語系(Globalization)時, 我就暸了, 原來設定(Setting)是沒辦法進行多語系的, 而資源(Resources)是可以很輕鬆完成多語系工作, 例如要繁體化字串資源, 只要複製My Project目錄中的Resource.resx 成 Resource.zh-tw.resx, 再編輯該檔內容即可, 反之設定(Setting)在建置後會產生*.exe.config檔, VS.net不提供*.exe.zh-tw.config.

That's all. Keep Coding.

開站了!

這是一個 .net 程式開發的技術討論區.
筆者目前從事工具軟體開發, 同時也是Crazy Coding Boy. 希望能將日常遭遇的問題及解決技巧, 與大家分享. 內容會以解決現實問題為重點, 而非一味的追逐新技術, 主要內容包括:

  1. 專案問題與解答
  2. 有用的工具程式
  3. 參雜一點點的方法論(Methodology)

希望各方人士不另賜教, 能激勵筆者用力的寫下去.