วันจันทร์ที่ 15 ธันวาคม พ.ศ. 2551

การสร้างและใช้งาน Collection.Generic

Generic เป็นเครื่องมือที่ช่วยให้ผู้พัฒนา Collection Class สามารถนำ Class ที่สร้างไว้นำกลับมาใช้งานได้ง่ายขึ้นโดยไม่จำเป็นต้องคำนึงถึงชนิดของตัวแปรที่บรรจุอยู่ใน Collection Class เหล่านั้นในตอนออกแบบ แต่จะทำการกำหนดชนิดของตัวแปรให้กับ Class เมื่อจะนำ Class เหล่านั้นไปใช้งาน

ตัวอย่าง
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace ConsoleApplication9
{
     // กำหนดตัวแปรเป็นชนิด T ภายใต้เครื่องหมาย "< >"
    public class myCollection<T>
    {
         // นำชนิดตัวแปรนั้นมาใช้งานเช่นเดียวกับชนิดตัวแปรอื่นๆ
        T[] myStack = new T[50];

        public T this[int idx]
        {
            get
            {
                return myStack[idx];
            }
            set
            {
                myStack[idx] = value;
            }
        }

    }

    public class Student
    {
        private String _std;

        public Student(String name)
        {
            _std = name;
        }
        public override string ToString()
        {
            return _std;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            // เมื่อนำมาใช้งาน ให้กำหนดชนิดของตัวแปรตามที่ต้องการ ในที่นี้ให้แทนด้วย Class Student ที่ได้กำหนดไว้ (อาจกำหนดเป็น String, Int, ... ก็ได้แล้วแต่จะใช้)
            myCollection<Student>             mCollec = new             myCollection<Student>();

            //หลังจากที่กำหนดเรียบร้อยแล้ว จะสามารถนำตัวแปรนั้นมาใช้งานได้ทันที โดยชนิดของตัวแปรนั้นจะเป็นไปตามที่กำหนดไว้ในขั้นตอนการประการตัวแปร
            mCollec[0] = new Student("Jor");
            mCollec[1] = new Student("Ann");
            mCollec[2] = new Student("Aae");

            for(int item = 0; item < 3; item++)
                Console.WriteLine(mCollec[item]);
            Console.ReadKey();
        }
    }
}

วันพุธที่ 29 ตุลาคม พ.ศ. 2551

เพิ่มเติมกับ IEnumerator, IEnumerable และ ICloneable

จากที่ผ่านมาได้พูดถึงภาพรวมของ Collection Interface ที่ .Net ได้เตรียมไว้ คราวนี้จะมาดูรายละเอียด ของ Interface 3 ตัวคือ IEnumerator, IEnumerable และ ICloneable (ที่จริงจะกล่าวเฉพาะ IEnumerator และ IEnumerable แต่ในตัวอย่างมีการใช้งาน ICloneable ด้วยก็เลยกล่าวเพิ่มไปซะเลย)

IEnumerator เป็น interface พื้นฐานเพื่อให้ class ที่อ้างถึง interface นี้สามารถใช้ foreach ได้ ภายในมีสมาชิกดังนี้
    Methods
  • MoveNext ระบุให้เลื่อน element ปัจจุบันไป 1 ช่อง
  • Reset สังให้ current กลับไปจุดเริ่มต้น

    Properties
  • Current ดึง element ปัจจุบันจาก collection

IEnumerable เป็น interface ที่จะทำการส่งคลาส IEnumerator ไปยังคำสั่ง foreach ภายในมีสมาชิกดังนี้
    Methods
  • GetEnumerator ส่งค่า enumerator ที่จะส่งไปยัง foreach

ICloneable เป็น interface ที่กำหนดให้คลาสที่ประกาศต้องมีความสามารถในการ clone ตัวมันเอง

    Methods
  • Clone ทำการ clone ตัวมันเองแล้วส่งค่านั้นกลับไป

ตัวอย่าง Code:
ตัวอย่างต่อไปนี้จะเป็นการสร้าง single linklist โดยไม่ใช้คลาสในกลุ่ม collection ของ .Net แต่จะกำหนดโครงสร้างทั้งหมดเองตามลักษณะดังนี้

|--------------- MyList -----------------|
|---Node---|   |---Node---|   |---Node---|
|Value|Next|-->|Value|Next|-->|Value|Next|

จากโครงสร้างดังกล่าวจะมีคลาสสองตัวคือ MyList และ Node โดย MyList จะเป็น collection ของ Node ภายใน Node จะมีสมาชิกภายในคือ Value เก็บค่าตัวเลขที่ต้องการบันทึก และ Next เก็บที่อยู่ของ Node ถัดไป


using System;
using System.Collections.Generic;
using System.Collections;

namespace LinkListDemo
{
    // ประกาศคลาส Node
    public class Node : ICloneable //ประกาศใช้ ICloneable
        public int Value;
        public Node Next;
 
        public Node()
        {
            _value = 0;
        }
 
        public Node(int nValue)
        {
            _value = nValue;
        }
 
        public override string ToString()
        {
            return _value.ToString();
        }
 
        #region ICloneable Members
        public object Clone()
        {
            return new Node(_value);         }
        #endregion
    }
 
    // ประกาศคลาส MyList
    public class MyList : IEnumerator, IEnumerable, ICloneable
    {
        private Node _firstNode;
        private Node _curNode;         private Node _lastNode;
 
        public MyList()
        {
            _firstNode = new Node(); //ตำแหน่ง 1.1
        }
 
        public bool MoveNext()
        {
            _curNode = _curNode.Next; //ตำแหน่ง 1.2
            return !(_curNode == null);
        }
 
        public void Reset()
        {
            _curNode = _firstNode; //ตำแหน่ง 1.3
        }
 
        public object Current //ตำแหน่ง 1.4
        {
            get
            {
                if (_curNode != null)
                {
                    return _curNode;
                }
                else                 {
                    throw new InvalidOperationException();
                }
            }
        }
 
        public void Add(Node newNode)
        {
            if (_curNode == null)
            {
                _firstNode.Next = newNode;
                _curNode = newNode;
                _lastNode = newNode;
            }
            else
            {
                _lastNode.Next = newNode;
                _lastNode = newNode;
            }
        }
 
        public void Add(int newValue)
        {
            Node newNode = new Node(newValue);
            this.Add(newNode);
        }
 
        #region IEnumerable Members
        public IEnumerator GetEnumerator() //ตำแหน่ง 2
        {
            return (IEnumerator)Clone();
        }
        #endregion
 
        #region ICloneable Members
        public object Clone()
        {
            Node tmpNode = _curNode;
            MyList newList = new MyList();
            _curNode = _firstNode.Next;
            while (_curNode != null)
            {
                newList.Add(_curNode.Value);
                _curNode = _curNode.Next;
            }
            return newList;
        }
        #endregion
    }
 
    class Program //โปรแกรมเรียกใช้ class MyList
    {
        static void Main(string[] args)
        {
            MyList myList = new MyList();
            for (int cnt = 0; cnt < 10; cnt++)
            {
                myList.Add(new Node(cnt));
            }
            foreach (Node node in myList)
            {
                Console.WriteLine(node);
            }
            Console.ReadKey();
        }
    }

ในการวนรอบของ foreach นั้นคำสั่ง foreach จะเรียก GetEnumerable() (ตำแหน่ง 2) เพื่อเรียก object collector ขึ้นมาโดยที่ object collector ที่คืนกลับนั้นคลาสจะต้องประกาศ IEnumerator ไว้ด้วย หลังจาก foreach ได้ object collector จะมีขั้นตอนการดำเนินการดังนี้
  1. เรียก MoveNext(ตำแหน่ง 1.2) เพื่อเลื่อนตำแหน่งของ element ไปยังจุดถัดไป ถ้าผลของการ MoveNext ส่งกลับมาเป็น true จะทำงานในข้อ 2 ต่อ ถ้าเป็น false จะหยุดการทำงาน
  2. ส่งค่าใน element ออกไปผ่าน property Current (ตำแหน่ง 1.4)
  3. วนกลับไปทำข้อ 1 ใหม่

จากขั้นตอนดังกล่าวจะเห็นว่าเมื่อเริ่มต้นนั้นการวนรอบของ foreach นั้นตำแหน่งของ Current นั้นจะต้องชี้ไปยังตำแหน่งก่อนหน้าค่าแรก (ในกรณีที่เป็น array ที่มีตำแหน่งเริ่มต้นที่ array[0] ตำแหน่งของ current จะต้องชี้ที่ตำแหน่ง -1) เนื่องจาก foreach จะเรียกใช้คำสั่ง MoveNext (ตำแหน่ง 1.3) ก่อนแล้วจึงส่ง element ใน collector ออกไป ดังนั้นในตอนที่สร้าง MyList ขึ้นมาจึงได้สร้าง node ใหม่ให้กับ _firstNode ในทันทีเพื่อป้องกันความผิดพลาดที่จะเกิดจากการอ่านข้อมูลจาก object ที่ไม่มีการอ้างถึง

วันอังคารที่ 28 ตุลาคม พ.ศ. 2551

ทำความรู้จัก Collection Interface ใน .Net

ใน .Net ได้จัดเตรียมเครื่องมือสำหรับสร้างคลาส Collector ไว้หลายชนิดด้วยกัน หนึ่งในนั้นคือกลุ่ม Interface เพื่อให้คลาสกลุ่ม Collector ที่สร้างขึ้นมานั้นสามารถเชื่อมต่อการทำงานกับภายนอกได้ Interface ที่ .Net ได้จัดเตรียมไว้ให้มีหลายตัว เช่น   
  • IEnumerator และ IEnumerable  ทำให้คลาสที่ inherit จาก interface นี้สามารถใช้คำสั่งวนรอบ foreach ได้
  • ICompare และ IComparable ทำให้คลาสที่ inherit จาก interface นี้สามารถทำการจัดเรียงข้อมูลภายในได้
  • ICollection  เป็นฐานของคลาสใน System.Collection
  • IList สืบทอดมาจาก ICollection อีกต่อหนึ่ง และเป็นฐานของ non-generic lists
  • IDictionary ทำให้คลาสที่ inherit สามารถทำงานได้ในลักษณะเดียวกับคลาส Dictionary
  • IDictionaryEnumerator เหมือนกับ Dictionary แต่สามารถใช้ร่วมกับคำสั่ง foreach ได้ (คลาส Dictionary ไม่สามารถใช้คำสั่ง foreach ได้)
  • IHash คลาสที่สืบทอดมาจะต้องมีคุณสมบัติการทำฟังก์ชั่น Hash

วันศุกร์ที่ 24 ตุลาคม พ.ศ. 2551

การใช้งาน Collections ใน .Net

การเขียนโปรแกรมส่วนใหญ่จะมีการใช้งาน Collections รวมด้วยเสมอเช่น การใช้งาน ListBox ก็จะมี Property Indexs หรือแม้แต่การใช้งาน DataSet ก็จะมี Tables, Columns, Rows ก็ล้วนเป็น Collections ด้วยกันทั้งสิ้น คราวนี้หากเราต้องการสร้าง Class ที่ต้องใช้ความสามารถดังกล่าว ตัวอย่าง การสร้างรายชื่อนักเรียนภายในห้อง เราก็จะสร้างคลาส ClassRoom ภายใน ClassRoom จะมี Property Students ซึ่งจะเก็บรายชื่อนักเรียนทั้งหมดไว้ ซึ่งจะมีโครงสร้างดังนี้

    Class จะมีทั้งหมด 3 class ด้วยกันคือ
  1. Student เป็นตัวแทนนักเรียนแต่ละคนในชั้นเรียน
  2. StudentList เป็นตัวแทนรายชื่อนักเรียนทั้งหมดในชั้นเรียน class นี้จะนำเอาเทคนิคการใช้ Collection มาใช้
  3. ClassRoom เป็นตัวแทนห้องเรียน แสดงการนำ Collection ที่ประการศไว้มาใช้ โดยนำคลาส StudentList มาเป็น Property หนึ่งของ ClassRoom

    ตัวอย่าง Code:

    public class Student
    {
        private int _id;
        private string _name;
        private string _surname;

        Student()
        {
            _id = 0;
        }
       
        public Student(int id, string name, string surname)
        {
            _id = id;
            _name = name;
            _surname = surname;
        }

        public int Id
        {
            get{ return _id; }
            set{ _id = id; }
        }

        public string Name
        {
            get{ return _name; }
            set{ _name = value;}
        }

        public string Surname
        {
            get{ return _surname; }
            set{ _surname = value; }
        }

        public override string ToString()
        {
            return _name + " " + _surname;
        }
    }

    จาก Student ข้างต้นจะมี attribute ที่เป็น private คือ _id, _name, _surname มี Properties 3 ตัวคือ Id, Name, Surname และมี Constructor 2 ตัว นอกจากนี้ยังมี method 1 ตัวคือ ToString() เพื่อให้สามารถแปลงเป็น string ได้เลย

    public class ClassRoom
    {
        public class StudentList : CollectionBase // ประกาศ Nested Class
        {
            public void Add(Student std)
            {
                if ((std.id == 0) || (std.Name == null) || (std.Surname == null))
                {
                    Console.WriteLine("Error: Student not initialize.");
                    return;
                }
                List.Add(std); //เพิ่ม std ลงใน list
            }

            public void Remove(Student std)
            {
                List.Remove(std); //ลบ std ออกจาก list
            }

            public Student this[int stdIndex] // ประกาศ property เพื่อให้สามารถมองในลักษณะ array
            {
                get { return (Student)List[stdIndex]; }
                set { List[stdIndex] = value; }
            }
        }

        private string _className;
        private string _Advisor;
        public StudentList Students;

        public ClassRoom()
        {
            Students = new StudentList(); // สร้างคลาส StudentList
        }

        public string ClassName
        {
            get { return _className; }
            set { _className = value; }
        }

        public string Advisor
        {
            get { return _Advisor; }
            set { _Advisor = value; }
        }

        public override string ToString()
        {
            StringBuilder str = new StringBuilder();
            str.Append("Class Room: " + _className + "\n");
            str.Append("Adviser: " + _Advisor + "\n");
            str.Append("Student: \n");
            int cnt = 1;
            foreach (Student std in Students)
            {
                str.Append("\t" + cnt++.ToString() + ") " + std + "\tid: " + std.id + "\n");
            }
            return str.ToString();
        }
    }

    จาก Code ข้างต้นภายในคลาส ClassRoom จะมีคลาสภายในคือ StudentList ซึ่งจะถือว่าเป็น Nested Class โดยที่ StduentList จะ Inherited Class มาจาก CollectionBase โดยภายใน CollectionBase จะมี property ที่สำคัญคือ List หลังจากที่ประกาศคลาสเรียบร้อยแล้ว ได้นำคลาส StudentList มาใช้กับ property Students

    public class Program
    {
        static void Main(string[] args)
        {
            ClassRoom c1 = new ClassRoom();
            c1.Advisor = "Tanapat Warahakit";
            c1.ClassName = "p1";
            c1.Students.Add(new Student(1001, "Tanapat", "Warahakit"));
            c1.Students.Add(new Student(1002, "Tanapong", "Warahakit"));
            c1.Students.Add(new Student(1003, "Jarutas", "Patthanapanchai"));
            Console.WriteLine(c1);
            Console.ReadKey();
        }
    }

    หลังจากที่ประกาศคลาส Student, StudentList และ ClassRoom เรียบร้อยแล้วก็ถึงเวลานำคลาสที่เตรียมไว้มาใช้ดังตัวอย่างข้างต้น

วันอังคารที่ 21 ตุลาคม พ.ศ. 2551

การติดต่อ XML โดยใช้ XmlDocument

ต่อจากตอนที่แล้ว ที่กล่าวถึงการติดต่อ XML แบบ SAX ตอนนี้จะกล่าวถึงการติดต่อแบบ DOM ซึ่งจะเป็นการโหลดข้อมูลทั้งหมดเข้าหน่วยความจำแล้วสร้างโครงสร้างข้อมูลแบบ tree ขึ้นมาในหน่วยความจำ จึงทำให้เราสามารถท่องไปยังส่วนต่างๆ ของข้อมูลได้โดยง่าย นอกจากนั้นยังสามารถจัดการข้อมูลได้โดยง่าย เช่น การเพิ่ม ลบ หรือแก้ไขข้อมูล แต่ข้อเสียของการดำเนินการแบบนี้คือหากข้อมูลมีขนาดใหญ่จะต้องมีหน่วยความจำจำนวนมากมารองรับด้วย และการดำเนินการทั้งหมดนี้จะดำเนินการได้หลังจากโหลดข้อมูลทั้งหมดขึ้นหน่วยความจำแล้ว

ตัวอย่าง code

วันอาทิตย์ที่ 19 ตุลาคม พ.ศ. 2551

การติดต่อไฟล์ xml ด้วย xmlTextReader

การติดต่อไฟล์ XML ด้วย XmlTextReader จะเป็นการติดต่อแบบ SAX (Simple API for XML) ซึ่งจะมีลักษณะการทำงานเป็นแบบ อ่านข้อมูลเข้ามาทีละชุด โดยข้อมูลที่เข้ามานั้นอาจจะเป็น element หรือ text หรือ attribute ก็ได้ ดังนั้นข้อดีของการติดต่อไฟล์ XML ด้วย SAX คือสามารถติดต่อไฟล์ XML ที่มีขนาดใหญ่มากๆ ได้ดีเนื่องจากจะเป็นการอ่านข้อมูลมาทีละชุดจึงทำให้ใช้เนื้อที่ในหน่วยความจำน้อย และสามารถทำงานได้รวดเร็วเนื่องจากทำการอ่านข้อมูลมา 1 ชุดแล้วก็ดำเนินการประมวลผลได้เลยไม่ต่อรอให้ระบบอ่านข้อมูลมาจนหมด ส่วนข้อเสียคือการเพิ่ม/ลดข้อมูล และ การท่องไปยังข้อมูลต่างๆ ในไฟล์ XML จะทำได้ยากเพราะการทำงานของ SAX นั้นจะเป็นการทำงานเรียงจาก element แรกเรื่อยไปจนกระทั่งถึง element สุดท้าย

ตัวอย่าง Code

วันศุกร์ที่ 3 ตุลาคม พ.ศ. 2551

เรื่องของ Nested Class ใน .Net

ก่อนอื่นต้องทำความรู้จัก Nested Class ก่อนว่าคืออะไร พิจารณา Code ต่อไปนี้
class Container
{
class Nested
{
Nested() {}
}
}
จากตัวอย่าง code ข้างต้นจะเห็นว่าภายใน class Container จะมี class ภายใน ซึ่งเราจะเรียกว่า Nested Class โดยปกติแล้้ว การมองเห็น Nested จะเป็น private แต่เราสามารถเปลี่ยนรูปแบบการมองเห็นเป็นแบบอื่นได้ เช่น public, protected เป็นต้น
สำหรับการอ้างถึง Container Class (class นอก) จาก Nested Class (class ภายใน) สามารถทำได้โดยใช้ constructer ช่วย ดังตัวอย่างต่อไปนี้
public class Container
{
public class Nested
{
private Container m_parent;
public Nested()
{
}
public Nested(Container parent)
{
m_parent = parent;
}
}
}
การอ้างถึง Nested Class จากภายนอกสามารถทำได้โดย
Container.Nested nest = new Container.Nested();

เกร็ดเล็กๆ น้อยๆ ของ XML กับ DataSet ใน .Net

- การอ่าน XML เข้ามาใน DataSet
DataSet ds = new DataSet();
ds.ReadXml("XmlFile.xml");
- เวลาเขียนข้อมูลใน DataSet เป็นไฟล์ XML ใช้คำสั่ง
ds.WriteXML("XmlFile.xml");
- ภายหลังเรียกคำสั่ง ReadXml ถ้ามี table อยู่ก่อนหน้าใน dataset ข้อมูลเก่าจะหาย ดังนั้นหากต้องการอ่านข้อมูลเข้าข้อมูลหลายๆ ตาราง ให้สร้าง DataSet 2 ตัวโดยให้ตัวหนึ่งอ่าน แล้วค่อย copy() table ไปยัง DataSet อีกตัวหนึ่ง
- การใช้คำสั่ง clone() ของ DataTable จะเป็นเพียงการสร้าง Table ใหม่ซึ่งมีโครงสร้างทุกอย่างเหมือน Table ต้นฉบับแต่ไม่ได้คัดลอกข้อมูลภายในมาด้วย
- การใช้คำสั่ง copy () ของ DataTable นั้นคล้ายกับ clone() แต่จะต่างกันตรงที่คำสั่ง copy() จะคัดลอกข้อมูลนั้นมาด้วย
- ชนิดของข้อมูลของ column ที่อยู่ภายใน table ซึ่งได้จากการอ่าน ReadXML จะมีเฉพาะ string เท่านั้น
- ข้อมูลใน XML ที่เขียนลงไฟล์จะมีเพียง Table เดียวเท่านั้นคือ table แรกที่อยู่ใน DataSet (หรือมีค่า index เป็น 0)
- หากต้องการหาข้อมูลที่อยู่ใน DataSet ทำได้สองวิธีคือ 1. ใช้คำสั่ง find และ 2. ใช้คำสั่ง select โดยแต่ละวิธีจะมีรายละเอียดดังนี้
1. หากใช้คำสั่ง find จะต้องทำการกำหนด PrimaryKey ให้กับ Table ที่ต้องการค้นหาข้อมูลก่อน ซึ่งจะต้องกำหนด Keys โดย Keys ที่จะกำหนดนั้นต้องมี DataType เป็น DataColumn[] (Array ของ DataColumn) เมื่อเขียน Code จะมีลักษณะดังนี้
public string GetData(String itemID)
{
DataColumn[] keys = new DataColumn[1];
keys[0] = dataSet1.Tables["TableName"].Columns["ColumnName"];
dataSet1.Tables["TableName"].PrimaryKey = keys;
DataRow findRow = dataSet1.Tables["TableName"].Rows.Find(itemId);
if (findRow != null)
{
return findRow["ItemName"].ToString();
}
else
return "";
}
2. การใช้คำสั่ง select จะมีรูปแบบเหมือนกับการ filter ข้อมูล ผลลัพธ์ที่ได้จะอยู่ในรูป array ของ DataRow (DataRow[]) Code การทำงานมีดังนี้
public string GetData(String itemID)
{
DataRow[] findRow = dataSet1.Tables["TableName"].Select("ColumnName=" + itemID);
if(findRow.Length != 0)
{
return findRow[0]["ColumnName"].ToString();
}
else
{
return null;
}

วันอังคารที่ 30 กันยายน พ.ศ. 2551

วิธีการเข้า web ที่ถูก block ด้วย proxy

คำเตือน การรับส่งข้อมูลผ่าน open proxy อาจจะมีการดัก password ไว้ได้ ดังนั้นหากต้องการใช้หรือจำเป็นต้องใช้งาน open proxy ต้องแน่ใจว่าไม่มีการรับส่งข้อมูลที่มีความสำคัญในขณะรับส่งข้อมูลผ่าน open proxy
จากปัญหาการ block web site บางแห่งจากองค์กรของรัฐ (อย่างไม่เป็นธรรม)  เราสามารถเข้าถึง web ที่ถูก block ได้โดยใช้งานผ่าน proxy server ซึ่งมีบริการฟรีทั่วโลก 
การค้นหา proxy และการติดตั้งมีดังนี้
ขั้นแรก เราต้องหา proxy ที่จะใช้บริการก่อนโดยค้นจาก google ใช้คำค้นดังนี้ free proxy ตัวอย่าง proxy ที่ได้จะมีลักษณะดังนี้ http://www.publicproxyservers.com/page1.html 
ขั้นที่สอง ตรวจสอบว่า proxy นั้นสามารถใช้งานได้หรือไม่ ที่ 
http://www.checker.freeproxy.ru/checker/ โดยใช้ host และ port เช่น ข้อมูลที่ได้จาก google บอกว่า host = 123.123.123.123 port = 80 เราก็กรอกข้อมูลเป็น 123.123.123.123:80
ขั้นที่สาม (สำหรับผู้ใช้ที่มีระบบ LAN หรือผู้ใช้ ADSL ผ่านสาย LAN) ติดตั้ง proxy  โดยเลือก 
1. Control Panel -> Internet Options  (แสดงหน้าต่าง Internet Properties)
2. Connections-> LAN settings (แสดงหน้าต่าง Local Area Network (LAN) Settings)
3. ติ๊กถูกที่ Use a proxy server for your LAN .... 
4. กรอก proxy ที่ตรวจสอบแล้วว่าใช้งานได้ ลงในช่อง Address และ Port แล้วคลิ๊กตอบตกลงสองครั้ง

วันอาทิตย์ที่ 28 กันยายน พ.ศ. 2551

แก้ปัญหา "Unable to convert MySQL date/time value to System.DateTime" ใน .Net

เวลาเราต้องการนำข้อมูลจาก DataAdapter ใส่ลงใน DataSet จะใช้คำสั่ง Fill แต่หากในตารางมีข้อมูลประเภท Datetime และข้อมูลภายในมีค่าเป็น null จะทำให้เกิด Exception 
"Unable to convert MySQL date/time value to System.DateTime"
ปัญหานี้สามารถแก้ไขโดยเพิ่มข้อความ 
Allow Zero Datetime=True
ตัวอย่าง คำสั่งการใช้ MySqlConnection
string conStr = "SERVER=" + hn + ";DATABASE=" + db + ";Port=" + pt + ";UID=" + UID + ";PWD=" + PWD + ";Allow Zero Datetime=true;";
MySqlConnection conn = new MySqlConnection(conStr);

วันจันทร์ที่ 15 กันยายน พ.ศ. 2551

วิธีเชื่อมข้อมูล MySql โดยใช้ BindingSource บน .Net

คำเตือน ข้อมูลในส่วนนี้สรุปเอาจากความเข้าใจ โดยการศึกษาและพยายามลองผิดลองถูกเอา อาจจะมีวิธีการอื่นที่ถูกต้องและรัดกุมกว่านี้

สิ่งที่ต้องเตรียม
1. ฐานข้อมูล MySql พร้อมข้อมูล ในที่นี้จะใช้ฐานข้อมูลชื่อ test ภายในฐานข้อมูลมีตาราง 1 ตารางชื่อ table1 ข้อมูลมีดังนี้
==== table1 ====
id name
================
1 abc
2 def
================

2. ติดตั้ง MySql Connector สำหรับ .net

ลงมือทำ

1. สร้าง Project ใหม่ใน Visual Studio

2. เพิ่ม Refence ของ MySql โดยเลือก Project -> Add Reference -> MySQL.Data ดังรูป














3. เพิ่ม using MySql ในหัวของ Form1 ดังนี้

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 MySql.Data;
using MySql.Data.MySqlClient;


4. วาง component ดังรูป















พร้อมกับกำหนด properties ของ component แต่ละตัวดังนี้
- dataset1 ให้เลือก Tables แล้วในช่อง (Collection) จะแสดงปุ่ม '...' ให้กดปุ่มนี้ โปรแกรมจะแสดงหน้าต่างใหม่ ให้กดปุ่ม add จะได้ตารางใหม่ชื่อ Table1 ให้เปลี่ยนเป็นชื่อ table1 (เปลี่ยนตัว T เป็นตัวเล็ก) จากนั้นเลือก Columns ช่อง (Collection) จะแสดงปุ่ม '...' ให้กดปุ่มนี้ จากนั้นโปรแกรมจะแสดง หน้าต่างใหม่ ให้เพิ่ม 2 column แบบเดียวกับที่เพิ่ม table จากนั้นเปลี่ยนชื่อ ColumnName เป็น id และ Name
- bindingSource1 ให้กำหนด properties DataSource = dataSet1, DataMember = table1
- bindingNavigator1 ให้กำหนด BindingSource = bindingSource1
- dataGridView1 ให้กดปุ่มเล็กๆ ตรงมุมขวา (จะมีหน้าต่างๆ เล็กๆ ขึ้นมา) แล้วเลือก ข้อมูลในช่อง Choose Data Source เป็น bindingSource1
5. แก้ไข Source Code ให้เป็นดังนี้ (ขี้เกียจแสดงอธิบายรายละเอียดการใส่ code นะ)

public partial class Form1 : Form
{
private MySqlConnection conn;
private MySqlDataAdapter adp;

public
Form1()
{
InitializeComponent();
}
private void Form1_Load(object
sender, EventArgs e)
{
conn = new
MySqlConnection("database=test;server=localhost;uid=root;pwd=password");
adp = new MySqlDataAdapter();
adp.SelectCommand = new MySqlCommand("SELECT * FROM
table1", conn);
MySqlCommandBuilder cb = new
MySqlCommandBuilder(adp);
conn.Open();
adp.Fill(dataSet1,
"table1");

// ในกรณีที่ไม่ได้สร้าง table ภายใน dataSet1 ตามข้อ 4 ให้เพิ่ม  Code นี้ลงไป

DataColumn dc1 = new DataColumn("id", System.Type.GetType("System.Int32"));
DataColumn dc2 = new DataColumn("Name", System.Type.GetType("System.String"));
DataTable tb = new DataTable("NameList");
dataSet1.Tables.Add(tb);
bindingSource1.DataSource = dataSet1;
bindingSource1.DataMember = "table1";
dataGridView1.AutoGenerateColumns = true;

}


private void Form1_FormClosed(object sender, FormClosedEventArgs
e)
{
conn.Close();
}

private void dataGridView1_CellEndEdit(object sender,
DataGridViewCellEventArgs e)
{
adp.Update(dataSet1.Tables["table1"]);
}
private void
dataGridView1_RowsRemoved(object sender, DataGridViewRowsRemovedEventArgs e)
{
adp.Update(dataSet1.Tables["table1"]);
}
}


เพิ่มเติม ในกรณีที่ต้องการเชื่อมต่อกับ control อื่นๆ เช่น textbox, combobox ให้ใช้ code ดังต่อไปนี้ในส่วนที่จะเชื่อมต่อกับฐานข้อมูล

ในกรณี textbox

textBox1.DataBindings.Add(new Binding("Text", bindingSource1, "id", true));

ในกรณี combobox

comboBox1.DataSource = dataSet1;
comboBox1.DisplayMember = "table1.Name";
comboBox1.DataBindings.Add(new Binding("Text", bindingSource1, "Name"));



วันพุธที่ 20 สิงหาคม พ.ศ. 2551

ลืม password ของ admin ใน joomla

หากลืม password ของ admin ใน joomla สามารถแก้ไขได้โดยการเปลี่ยน password ใหม่ ให้ดำเนินการดังนี้
1. เข้าไปที่ฐานข้อมูล mysql ของ joomla
2. มองหา table "jos_users"
3. มองหา user ที่เป็น admin
4. แก้ไข password โดยใช้ function md5

ตัวอย่าง SQL ที่ใช้แก้ไข password admin
UPDATE `joomla`.`jos_users` SET `password` = MD5( 'newpassword' ) WHERE `jos_users`.`username` = 'admin';

จะเป็นการเปลี่ยน password ของ admin เป็น 'newpassword'

session ใน PHP 4 กับ UTF-8

ในระหว่างการพัฒนา web หนึ่งโดยใช้ notepad++ เป็น editor ในการพัฒนา php ควบคุม session ปรากฎว่าไม่ว่าจะเขียนโปรแกรมอย่างไร ก็จะมีปัญหาเรื่อง php แจ้งเตือนว่าไม่สามารถใช้งาน session ได้เพราะว่า cookie ซ้ำ หรือ ไม่สามารถส่ง cookie ได้ ดังตัวอย่าง

Warning: session_start() [function.session-start]: Cannot send session cookie - headers already sent by (output started at C:\AppServ\www\guestbook\guestbook_del_confirm.php:1) in C:\AppServ\www\guestbook\guestbook_del_confirm.php on line 2

Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at C:\AppServ\www\guestbook\guestbook_del_confirm.php:1) in C:\AppServ\www\guestbook\guestbook_del_confirm.php on line 2


จากตัวอย่างดังกล่าวปัญหาเกิดจากในตอนพัฒนาโปรแกรมนั้นการ encoding ตัวอักษรได้เลือกเป็น utf-8 ดังนั้นการแก้ปัญหาดังกล่าวทำได้โดยการเปลี่ยน encodeing อื่นๆ ที่ไม่ใช้ utf-8 เช่น utf-8 without BOM หรือ ascii เป็นต้น

การทำ link ใน html เป็นแบบ button

ปกติเวลาเราทำ link ใน html จะใช้คำสั่ง


<a href="url_link">link</a>


แต่บางครั้งเราอาจต้องการให้ link ที่แสดงนั้นเป็นปุ่มเพื่อให้สอดคล้องกับปุ่มอื่นๆ หรือ เพื่อความสวยงาม คำสั่งที่ใช้สร้าง link คือ


<input type="button" onclick="window.location.href='url_link'" value="link_text">



โดยที่ url_link คือ url ของ link ที่จะไป ส่วน link_text คือ ข้อความที่แสดงบนปุ่ม

หมายเหตุ ในหนังสือบางเล่มอาจใช้คำสั่งภายใน onclick เป็น "window.navigate('link_text')" ก็สามารถจะใช้ได้เช่นกัน แต่เฉพาะกับ ie เท่านั้น จะใช้ไม่ได้กับ firefox ดังนั้นเพื่อให้สามารถทำงานได้ทั้ง ie และ firefox ก็ควรจะใช้คำสั่งที่แนะนำในข้างต้น

วันศุกร์ที่ 1 สิงหาคม พ.ศ. 2551

วิธีทำให้สามารถพิมพ์ DOS กับเครื่องพิมพ์ USB Port ใน Windows XP

1. ให้ทำการ Share Printer

2. เรียก dos โดยใช้คำสั่ง cmd แล้วพิมพ์คำสั่งต่อไปนี้

net use lpt1: //comname/shareprinter/ Persistent:yes


หมายเหตุ
comname -> ชื่อคอมพิวเตอร์ที่ share เครื่องพิมพ์
ในกรณีที่ไม่ผ่านระบบเครื่องข่ายหมายถึงเครื่องตัวเอง(อาจจะใช้หมายเลข ip:127.0.0.1 แทนก็ได้)
shareprinter -> ชื่อเครื่องพิมพ์ที่ทำ share



3.ระบบ dos พร้อมพิมพ์เรียบร้อยแล้ว

วันพฤหัสบดีที่ 10 กรกฎาคม พ.ศ. 2551

ลำดับการเรียก Exception ใน C#

การเกิด Exception ใน C# กรณีที่เป็น Nested ให้พิจารณาตัวอย่างต่อไปนี้


using System;
using System.Text;

namespace DemoEsception
{
class Program
{
static void Main(string[] args)
{
try
{
Console.WriteLine("Point A");
try
{
Console.WriteLine("Point B");
// Try to convert wrong format
Console.WriteLine(int.Parse("abc"));
Console.WriteLine("Point C");
}
catch (FormatException e)
{
Console.WriteLine("Catch exception:{0}",e);
}
Console.WriteLine("Point D");
}
catch (Exception e)
{
Console.WriteLine("Outer exception:{0}",e);
}
Console.WriteLine("Point E");
Console.ReadKey();
}
}
}


ผลลัพธ์ที่ได้
Point A
Point B

Catch exception:System.FormatException: Input string was not in a correct format. at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal) at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info) at System.Int32.Parse(String s) at DemoEsception.Program.Main(String[] args) in D:\Data\Visual Studio 2008\Projects\DemoEsception\DemoEsception\Program.cs:line 17
Point D
Point E


สังเกตว่าใน code นี้เกิดความผิดพลาดขึ้นเมื่อเกิดความพยายามเปลี่ยนตัวอักษร abc ให้เป็นตัวเลขโดยใช้คำสั่ง int.Parse("abc") ซึ่งจะทำให้เกิด FormatException ขึ้น และเมื่อเกิด Exception ขึ้นนั้นโปรแกรมจะข้าม Point C แล้วทำงานในส่วนของ exception แล้วกลับไปทำงานยัง Point D และ Point E จะเห็นว่าโปรแกรมจะไม่เข้าไปดำเนินการ exception ด้านนอกเนื่องจากได้ดำเนินการ FormatException ไปเรียบร้อยแล้ว

พิจาณา Code ต่อไปนี้เพิ่มเติม

using System;
using System.Text;

namespace DemoEsception
{
class Program
{
static void Main(string[] args)
{
try
{
Console.WriteLine("Point A");
try
{
Console.WriteLine("Point B");
// Try to convert wrong format
Console.WriteLine(int.Parse("abc"));
Console.WriteLine("Point C");
}
catch (IndexOutOfRangeException e)
{
Console.WriteLine("Catch exception:{0}",e);
}
Console.WriteLine("Point D");
}
catch (Exception e)
{
Console.WriteLine("Outer exception:{0}",e);
}
Console.WriteLine("Point E");
Console.ReadKey();
}
}
}

ผลลัพธ์ที่ได้
Point A
Point B
Outer exception:System.FormatException: Input string was not in a correct format. at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal) at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info) at System.Int32.Parse(String s) at DemoEsception.Program.Main(String[] args) in D:\Data\Visual Studio 2008\Projects\DemoEsception\DemoEsception\Program.cs:line 17
Point E

จากตัวอย่างข้างต้นได้เปลี่ยนแปลง Exception เป็น IndexOutOfRangeException ซึ่งทำให้เกิด exception ที่ไม่ได้ดักจับไว้ ผลคือ โปรแกรมจะข้ามการดำเนินการ exception ภายในไปยัง exception ภายนอกซึ่งไม่ได้กำหนดชนิดของ exception ไว้จึงทำให้ การดำเนินการใน Point C และ Point D ถูกข้ามไป เมื่อทำงานในส่วน exception เสร็จแล้วโปรแกรมจึงกลับมาดำเนินการใน Point E ต่อไป

วันเสาร์ที่ 28 มิถุนายน พ.ศ. 2551

วิธีการสร้างแผ่น boot xp ให้สามารถทำงานกับ SATA (เฉพาะของ intel)

เครื่องมือที่ต้องมี
1. แผ่น CD Windows XP ต้นฉบับ
2. image สำหรับ boot xp
3. driver sata 2 ชุดด้วยกัน คือ iastor-sata-drivers.zip และ iastor-sata-i386.zip
4. โปรแกรม Nero

การทำงานจะแบ่งเป็น 2 ขั้นตอนคือ ขั้นตอนการเตรียมการ และ ขั้นตอนการไรท์แผ่น

ขั้นตอนการเตรียมการ
1. สร้าง folder ไว้สำหรับทำงานให้ภายในมี folder ย่อย 2 รายการ โดยในที่นี้จะให้ชื่อ folder ว่า OS ภายในมี folder ย่อยคือ boot และ root ดังนี้

d:\os
d:\os\boot
d:\os\root

2. copy ไฟล์จาก cd ต้นฉบับไปไว้ใน folder ที่ชื่อ root (ก่อน copy ไฟล์ให้เปลี่ยน option ของ folder option ให้เห็นไฟล์ทั้งหมดก่อนโดยเลือก tools->folder options->View แล้วเลือก Show hidden files and folders และ เอาติ๊กถูกหน้า Hide protected operation system files ออก)

3. สร้าง folder d:\os\root\$OEM$\$1\DRIVERS แล้วแตกไฟล์ iastor-sata-drivers.zip ลงใน folder ที่เพิ่งสร้าง

4. แตกไฟล์ iastor-sata-i386.zip ลงใน folder d:\os\root\i386

5. สร้างไฟล์ d:\os\root\i386\winnt.sif โดยเพิ่มข้อความนี้ลงไป

[Data]
AutoPartition=0
MsDosInitiated="0"
UnattendedInstall="Yes"

[Unattended]
UnattendMode=FullUnattended
UnattendSwitch=Yes
OemSkipEula=Yes
OemPreinstall=Yes
ConfirmHardware=No
OemSkipEula=Yes
TargetPath=\WINDOWS
Repartition=No
WaitForReboot="No"
DriverSigningPolicy=Ignore
OemPnPDriversPath="DRIVERS\SATA\IASTOR"

[GuiUnattended]
OEMSkipWelcome = 1

[UserData]
ProductKey=xxxxx-xxxxx-xxxxx-xxxxx-xxxxx
ComputerName=WorkStation
FullName=""
OrgName=""
หมายเหตุ ข้อมูลในส่วน UserData นั้นให้แก้ไขเองตามสะดวกนะครับ
- ProductKey คือ Keyของ windows
- ComputerName คือ ชื่อเครื่องคอมที่เราต้องการกำหนด
- FullName คือ ชื่อเจ้าของเครื่อง
- OrgName คือ ชื่อขององค์กร


6. เพิ่มข้อมูลลงในไฟล์ d:\os\root\i386\TXTSETUP.SIF ตาม Section ต่อไปนี้ครับ

- [SourceDisksFiles] เพิ่มข้อมูลนี้
iastor.cat = 1,,,,,,,1,0,0
iastor.inf = 1,,,,,,,1,0,0
iastor.sys = 1,,,,,,4_,4,1,,,1,4
iastor.sys = 1,,,,,,,1,0,0
iaahci.cat = 1,,,,,,,1,0,0
iaahci.inf = 1,,,,,,,1,0,0
-[HardwareIdsDatabase] เพิ่มข้อมูลนี้
PCI\VEN_8086&DEV_2922&CC_0106 = "iastor"
PCI\VEN_8086&DEV_282A&CC_0104 = "iastor"
PCI\VEN_8086&DEV_2829&CC_0106 = "iastor"
PCI\VEN_8086&DEV_2822&CC_0104 = "iastor"
PCI\VEN_8086&DEV_2821&CC_0106 = "iastor"
PCI\VEN_8086&DEV_2682&CC_0104 = "iastor"
PCI\VEN_8086&DEV_2681&CC_0106 = "iastor"
PCI\VEN_8086&DEV_27C3&CC_0104 = "iastor"
PCI\VEN_8086&DEV_27C6&CC_0104 = "iastor"
PCI\VEN_8086&DEV_27C1&CC_0106 = "iastor"
PCI\VEN_8086&DEV_27C5&CC_0106 = "iastor"
PCI\VEN_8086&DEV_2653&CC_0106 = "iastor"
-[SCSI.Load] เพิ่มข้อมูลนี้
iastor = iastor.sys,4
-[FileFlags] เพิ่มข้อมูลนี้
iastor.sys = 16
-[SCSI] เพิ่มข้อมูลนี้
iastor = "Intel(R) SATA RAID/AHCI Controller"
7. เพิ่มข้อมูลลงในไฟล์ d:\os\root\i386\DOSNET.INF ตาม Section ต่อไปนี้ครับ

-[FloppyFiles.1] เพิ่มข้อมูลนี้
d1,iastor.sys
-[Files] เพิ่มข้อมูลนี้
d1,iastor.cat
d1,iastor.inf
d1,iastor.sys
d1,iaahci.cat
d1,iaahci.inf
ถึงตรงนี้ถือว่าขั้นตอนการเตรียมการเสร็จสิ้นแล้ว ต่อไปจะเป็นการ write แผ่น cd โดยใช้โปรแกรม Nero

การไรท์แผ่น boot windows xp

1. แตกไฟล์ image สำหรับ boot xp ลงใน folder d:\os\boot\ ที่ได้เตรียมไว้

2. เปิดโปรแกรม nero โดยเลือกหัวข้อ cd-rom(boot)

3. กำหนดตัวแปรดังนี้
บูต--> อิมเมจไฟล์ [d:\os\boot\boot.ima]
-> ขั้นสูง เปิดใช้การตั้งค่าของผู้เชี่ยวชาญ (สำหรับผู้ใช้ระดับสูงเท่านั้น) [ติ๊กถูก]
-> ลักษณะของอิมูลเลชั่น [ไม่มีอีมูเลชั่น]
-> โหลดเซ็คเมนต์เซ็คเตอร์(hex!) [0000]
-> จำนวนเซ็คเตอร์ที่โหลด [4]

ISO--> โหมดข้อมูล [โหมด 1]
-> ระบบไฟล์ [ISO 9660 + โจเลียต]
-> ชื่อไฟล์ความยาม(ISO) [สูงสุดของ 31 ตัวอักษร (level 2)
-> ชุดอักขระ (ISO) [ISO 9660 (สแตนดาร์ด ISO CD-รอม)]

(ติ๊กถูกทั้งหมดนี้)
-> อนุญาตความลึกของพาธมากกว่า 8 ไดเรกทอรี่
-> อนุญาตให้ใช้ตัวอักในในพาธมากกว่า 255 ตัว
-> ห้ามใส่นามสกุึลเวอร์ชั่นไฟล์ ISO '1'
-> อนุญาตให้มากกว่า 64 ตัวอักษรสำหรับชื่อโจเลียต
เลเบล-->

วันพฤหัสบดีที่ 26 มิถุนายน พ.ศ. 2551

วิธีรีเซ็ท password Linksys WAP54G

ก่อนอื่นต้องเตรียมต่อเครื่องคอมพิวเตอร์เข้ากับ AP ทางสาย LAN ให้เรียบร้อยก่อนแล้วดำเนินการดังนี้

1. กดปุ่ม Reset ที่ท้ายเครื่องค้างนานประมาณ 30 วินาที (สังเกตว่าไฟในช่อง Act-สีเขียว จะดับแสดงว่า Reset แล้ว)
2. Set network เครื่องคอมฯ ที่จะ config AP ให้เป็น 192.168.1.xx/24
3. เปิดเบราว์เซอร์ติดต่อไปยัง AP ที่ URL http://192.168.1.245 USERNAME:<ว่าง> PASSWORD:admin
4. Config ค่าตามต้องการ

วันอังคารที่ 24 มิถุนายน พ.ศ. 2551

วิธีการเปลี่ยน Serial Key ของ Windows XP

อ่านจาก Link นี้ได้เลย

http://www.taotoon.com/forums/showthread.php?t=2123

วันจันทร์ที่ 2 มิถุนายน พ.ศ. 2551

วิธีการติดต่อฐานข้อมูลโดยใช้ SharpDevelop

1. ก่อนอื่นต้อง Download MySql Connector มาก่อน
2. หลังจากติดตั้งเสร็จแล้ว ให้เรา Add Reference ลงใน Project ของเราโดยเลือก
Project->AddReference->GAC->MySQL->Select

3. เพิ่ม Code ลง "using Mysql.Data.MySqlClient;" ลงในส่วน using

ตัวอย่าง Code


using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using MySql.Data.MySqlClient;
namespace TestDatabase
{
///
/// Description of MainForm.
///

public partial class MainForm : Form
{
public MainForm()
{
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
//
// TODO: Add constructor code after the InitializeComponent() call.
//
}
void Button1Click(object sender, EventArgs e)
{
string MyConString = "SERVER=localhost;" +
"DATABASE=test;" +
"UID=root;" +
"PASSWORD=;";
MySqlConnection connection = new MySqlConnection(MyConString);
MySqlCommand command = connection.CreateCommand();
MySqlDataReader Reader;
command.CommandText = "select * from test";
connection.Open();
Reader = command.ExecuteReader();
while (Reader.Read())
{
string thisrow = "";
for(int i= 0;ithisrow+=Reader.GetValue(i).ToString() + ",";
listBox1.Items.Add(thisrow);
}
connection.Close();
}
}
}

วันพุธที่ 28 พฤษภาคม พ.ศ. 2551

การติดตั้ง wireless intel รุ่น 2200BG, 2300BG บน FreeBSD รุ่น 6.3

1. ติดตั้ง firmware iwi ผ่านทาง Ports

# cd /usr/ports/net/iwi-firmware-kmod/
# make install clean

หมายเหตุ หากมี error ฟ้อง ประมาณว่าไม่เจอ tree ของ Kernel ให้ทำการติดตั้ง Source Code ของ FreeBSD รุ่นนั้นก่อน

2. ทดสอบ Load driver

# kldload -v if_iwi

แล้วลองเรียกคำสั่ง

# dmesg grep iwi

ถ้าทุกอย่างถูกต้อง ผลที่ได้ควรจะมีลักษณะอย่างนี้

iwi0: mem 0xe0206000-0xe0206fff irq 11 at device 4.0 on pci2 iwi0: Ethernet address: xx:xx:xx:xx:xx:xx

3. กำหนดให้ระบบ load driver ในขณะิ boot โดยเพิ่มข้อมูลลงในไฟล์ /boot/loader.conf ดังนี้

if_iwi_load="YES"
wlan_load="YES"
firmware_load="YES"

4. กำหนดให้ wireless เริ่มทำงานโดยเพิ่มข้อมูลลงในไฟล์ /etc/rc.conf ดังนี้

ifconfig_iwi0="ssid testwlan wepmode on wepkey 0x12345678901234567890123456 weptxkey 1 wepmode on DHCP"

ตัวอย่างข้างต้นเป็นการกำหนด ค่าของระบบ wireless ที่มี ssid ชื่อ "testwlan" และมีการเข้ารหัสแบบ WEP โดยใช้ key "12345678901234567890123456" ซึ่งเป็น key ที่ 1 และสุดท้ายเป็นการระบุให้ทำการสอบถามหมายเลข IP จาก DHCP

แหล่งข้อมูลอ้างอิง:
1) http://damien.bergamini.free.fr/ipw/iwi-freebsd.html
2) man iwi (สามารถใช้ได้หลังจากติดตั้ง firmware ในข้อ 1 เสร็จแล้ว)
3) freebsd document ใน Handbook หัวข้อที่ 29 Wireless Networking

Tip:
1) หลังจากติดตั้ง iwi-firmware แล้ว สามารถทำการค้นหา ssid บริเวณนั้นได้โดยใช้คำสั่ง
# ifconfig iwi0 scan

2) หากต้องการเิริ่มระบบ network ใหม่โดยไม่ต้อง boot ระบบ ใช้คำสั่งดังนี้
# /etc/rc.d/netif restart

การติดตั้ง driver เสียงให้ FreeBSD 6.3

เพิ่มข้อมูลลงใน /boot/loader.conf ดังนี้
snd_ich_load="YES"

Network - การติดตั้ง PC Router เพื่อเชื่อมต่อเครือข่าย Internet ผ่าน PPPoE (ADSL Shareing)

ข้อมูลเบื่องต้นของระบบเครือข่ายที่ต้องการ
1. ระบบเครือข่ายใช้ภายในองค์กร โดยแบ่ง LAN ออกเป็น 2 กลุ่มคือ กลุ่มพนักงานในองค์กร และ กลุ่มบุคคลทั่วไป
1.1 กลุ่มพนักงานในองค์กรจะสามารถเข้าถึงทรัพยากรต่างๆ ที่มีอยู่ในระบบเครือข่ายได้ทั้งหมด โดยกำหนดหมายเลขเครือข่ายคือ 192.168.131.0/24
1.2 กลุ่มบุคคลทั่วไปสามารถเข้าใช้ระบบ Internet ได้เพียงอย่างเดียว โดยมีหมายเลขเครือข่ายคือ 192.168.132.0/24

2. จะเชื่อมต่อกับ ADSL modem ผ่านสาย Ethernet โดยกำหนดให้ ADSL modem มีหมายเลข IP 192.168.1.1

3. กำหนดให้ Gateway เป็น PC Router มีหมายเลข IP ดังนี้
3.1 NIC (Network Interface Card) ที่เชื่อมต่อกับ ADSL modem มีหมายเลข 192.168.1.2
3.2 NIC ทำหน้าที่เป็น Gateway ของ Lan สำหรับพนักงานในองค์กร มีหมายเลข 192.168.131.1
3.3 NIC ทำหน้าที่เป็น Gateway ของ Lan สำหรับบุคคลทั่วไป มีหมายเลข 192.168.132.1

4. PC Router ต้องมีบริการ DHCP, Cache Proxy และมีกราฟแสดงปริมาณการใช้งานเครือข่ายในขณะนั้น

=========================================================================จากปัญหาข้างต้นสามารถแบ่งการติดตั้งออกเป็น 3 กลุ่มดังนี้

1. การกำหนดหมายเลขหมายเลข IP ใหักับ NIC
2. การติดตั้ง PPPoE
3. การติดตั้ง Firewall และ NAT (Network Address Translation)
4. การติดตั้ง DHCP Server
5. การติดตั้ง Proxy Squid
6. การติดตั้ง mrtg (รวมการติดตั้ง apache, net-snmp, mrtg)

Windows Tips - วิธีลบ Shared Documents ออกจาก My Computer

1. เรียก regedit
2. เลือก HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\Delegate Folders
3. หาคีย์ {59031a47-3f72-44a7-89c5-5595fe6b30ee} แล้วลบออก