Feeds:
文章
迴響

Archive for 2008 年 08 月

懷舊照片

oldphoto(3)

Read Full Post »

8c7bfb2b1934c83d219b024e0c412b6f_4801

Read Full Post »

我想如果你用過 Windows 的命令列模式,一定會使用 Tab 鍵的自動完成。可是我最近遇到 Tab 鍵不是自動完成,而是輸出 Tab 字元 @_@

今天找到"http://wiki.0x209.org/Command_Prompt" 這篇文章才知道

原來是透過登錄檔定義 Tab 鍵為自動完成,當然你也可以定義其他按鍵為自動完成。這個定義位置在

[HKEY_CURRENT_USERSoftwareMicrosoftCommand Processor]

"CompletionChar" REG_DWORD 值,預設 0×9 為 TAB 鍵。

Read Full Post »

在某一台機器編譯 WF 程式總會出現下的錯誤訊息

錯誤    1    "CompileWorkflowTask" 工作發生未預期的失敗。
System.NullReferenceException: 並未將物件參考設定為物件的執行個體
   於 System.Environment.GetEnvironmentVariable(String variable, EnvironmentVariableTarget target)
   於 System.Workflow.ComponentModel.Compiler.CompileWorkflowTask.Execute()
   於 Microsoft.Build.BuildEngine.TaskEngine.ExecuteInstantiatedTask(EngineProxy engineProxy, ItemBucket bucket, TaskExecutionMode howToExecuteTask, ITask task, Boolean& taskResult)    WorkflowConsoleApplication2

找了一陣子,可能 keyword 下錯的關係,找不到太有幫助的資訊。今天注意到錯誤訊息中有呼叫 System.Environment.GetEnvironmentVariable

會不會是系統變數抓不到,於是我參考另一台可運作的環境變數,在使用者環境變數新增下面兩個變數就解決了 ^^

image

image

不過編譯器提供的錯誤訊息也太簡陋了,對於開發人員什麼太大的幫助~

Read Full Post »

實作"Pro WF: Windows Workflow in .NET 3.5"一書中的計算機範例,該文章片段可參考"http://www.scribd.com/doc/5089679/WF-"

http://documents.scribd.com/ScribdViewer.swf?document_id=5089679&access_key=key-2i65n6aquujrnb9vjrzn&page=&version=1&auto_size=true

流程圖
image
 
calc.cs

using System;
using System.Workflow.Activities;

namespace CalcWorkflowLib
{
    public sealed partial class Calc: SequentialWorkflowActivity
    {
        public Calc()
        {
            InitializeComponent();
        }

        public String Operation { get; set; }
        public int Number1 { get; set; }
        public int Number2 { get; set; }
        public double Result { get; set; }

        private void codeActivity2_ExecuteCode(object sender, EventArgs e) {
            Result = Number1 + Number2;
        }

        private void codeActivity1_ExecuteCode(object sender, EventArgs e) {
            Result = Number1 – Number2;
        }

        private void codeActivity4_ExecuteCode(object sender, EventArgs e) {
            Result = Number1 * Number2;
        }

        private void codeActivity3_ExecuteCode(object sender, EventArgs e) {
            Result = Number1 / Number2;
        }

        private void codeActivity5_ExecuteCode(object sender, EventArgs e) {
            throw new ArgumentException("Invalid Operation");
        }
    }

}

 
使用者介面
image
 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Workflow.Runtime;
using System.Threading;

namespace CalcWin {
    public partial class Form1 : Form {
        private WorkflowRuntime m_wk_runtime;
        private AutoResetEvent m_event = new AutoResetEvent(false) ;
        private int n1;
        private int n2;
        private string op;
        private double result;

        public Form1() {
            InitializeComponent();

            InitWorkflowRuntime();
        }

        private void Form1_Load(object sender, EventArgs e) {

        }

        /// <summary>
        /// 工作流程環境初始化
        /// </summary>
        private void InitWorkflowRuntime() {
            m_wk_runtime = new WorkflowRuntime();
            m_wk_runtime.WorkflowCompleted += new EventHandler<WorkflowCompletedEventArgs>(m_wk_runtime_WorkflowCompleted);
            m_wk_runtime.WorkflowTerminated += new EventHandler<WorkflowTerminatedEventArgs>(m_wk_runtime_WorkflowTerminated);
        }

        void m_wk_runtime_WorkflowTerminated(object sender, WorkflowTerminatedEventArgs e) {
            MessageBox.Show("Terminate");
            m_event.Set();
        }

        void m_wk_runtime_WorkflowCompleted(object sender, WorkflowCompletedEventArgs e) {
            result = (double)e.OutputParameters["Result"];
            //MessageBox.Show("Result: " + result);
            m_event.Set();
        }

        /// <summary>
        /// 數字鍵
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnNum_click(object sender, EventArgs e) {
            txtNumber.AppendText(((Button)sender).Text.Trim());

        }

        /// <summary>
        /// 清除鍵
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button11_Click(object sender, EventArgs e) {
            Clear();
        }

        /// <summary>
        /// 運算鍵
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnOp_click(object sender, EventArgs e) {
            try {
                n1 = Int32.Parse(txtNumber.Text);
                op = ((Button)sender).Text.Trim();
                txtNumber.Clear();
            }catch(Exception){
                MessageBox.Show("Invalid Opeartion");
            }
        }

        private void Clear() {
            n1 = 0;
            n2 = 0;
            op = String.Empty;
            txtNumber.Clear();
        }

        private void btnResult_Click(object sender, EventArgs e) {
            try {
                n2 = Int32.Parse(txtNumber.Text);
                var args = new Dictionary<string, object>()
                {
                    {"Number1", n1},
                    {"Number2", n2},
                    {"Operation", op}
                };
                WorkflowInstance wfi = m_wk_runtime.CreateWorkflow(typeof(CalcWorkflowLib.Calc), args);
                wfi.Start();
                m_event.WaitOne();
                Clear();               
                txtNumber.Text = result.ToString();

            } catch (Exception) {
                MessageBox.Show("Invalid Opeartion");
            }
        }

    }
}

在這個實作可以學到
1. 主程式與 Workflow 切割獨立開發
2. IfElseActivity 可以有多個分支
3. Workflow 輸出入參數

 
 

Read Full Post »

.NET 3.0 開始包含 Workflow,以前不懂怎麼使用,直到最近再次翻閱 BizTalk 才比較了解 Workflow 的運作。

VS2008 的 Workflow Designer 設計的相當不錯,繪製流程相當直覺方便,比起人工撰寫那些流程方便太多。

為了體驗一下流程的方便,寫了一個 1-9 偶數相加的流程,哈,有點殺雞用牛刀,不過我個人透過這個流程到有蠻多的體驗。

流程圖

wwf

程式碼

// Workflow1.cs

using System;
using System.Workflow.Activities;

namespace WorkflowConsoleApplication1
{
    public sealed partial class Workflow1: SequentialWorkflowActivity
    {       
        public Workflow1()
        {
            InitializeComponent();
        }

        private int m_i = 1;
        private int m_sum = 0;

       // 流程結束
        private void wk_complete(object sender, EventArgs e) {
            Console.WriteLine("total: " +  m_sum);
            Console.ReadKey();
        }

        // 流程初始化
        private void wk_init(object sender, EventArgs e) {
            m_i = 1;
            m_sum = 0;
        }

        private void while_true_condition(object sender, ConditionalEventArgs e) {
            if (m_i <= 9) {               
                e.Result = true;
            } else {
                e.Result = false;
            }
           
        }

        private void codeActivity1_ExecuteCode_2(object sender, EventArgs e) {
            m_sum += m_i;
            Console.WriteLine(m_i);           
        }

        private void codeActivity2_ExecuteCode_1(object sender, EventArgs e) {
            ++m_i;
        }
    }

}

// program.cs

using System;
using System.Threading;
using System.Workflow.Runtime;

namespace WorkflowConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            using(WorkflowRuntime workflowRuntime = new WorkflowRuntime())
            {
                AutoResetEvent waitHandle = new AutoResetEvent(false);
                workflowRuntime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e) {waitHandle.Set();};
                workflowRuntime.WorkflowTerminated += delegate(object sender, WorkflowTerminatedEventArgs e)
                {
                    Console.WriteLine(e.Exception.Message);
                    waitHandle.Set();
                };

                WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(WorkflowConsoleApplication1.Workflow1));
                instance.Start();

                waitHandle.WaitOne();
            }

        }
    }
}

執行結果

Snap1

討論

這個範例使用了 IfElse, While, Code 和 sequence 等 Activity,IfElse 和 While 就是一般熟悉的條件判斷與迴圈,Code 是你要執行的程式區段,sequence 是用來包含多個 Activity。sequence 有點像程式碼中的 {},將多個敘述合在一個區段中,如上述流程圖的 While 就使用 Sequence 來合併 IfElse 和 Code。透過這些簡單的 Activity 可以組合成軟體或網站所需要的工作流程。

在撰寫這個範例時,我腦海中浮現出以前用過的 LabView 軟體,那是一套圖控設計軟體,他也是透過拖拉圖形元件將程式撰寫完成,包含變數初始設定都透過元件來指定,這是目前 Workflow Designer 沒有辦法作到,所以上述我需要手動撰寫 wk_init 事件來初始相關變數。可能我對於 Workflow 的輸出/入還不是很清楚,所以覺得用起來有點鱉腳,不過 MSDN 上有 Workflow 與 Windows Form 整合範例,所以,輸出入部份應該有一定程度的完善才對,找時間再研究看看~

Read Full Post »

令人懷念的"仙劍奇俠傳"

今天同事轉寄了一個"仙劍奇俠傳DOS版經典事件回顧"網址給我,內容真是超讚的,都是一些讓我回為無窮的片段,可惜後續版本都沒有延續一代的劇情,劇情也沒有像一代這麼感人~ 好懷念啊~

林月如之死

最後一戰

片尾

Read Full Post »

Older Posts »