Cập nhật danh sách sinh viên mới nhất lớp CDTH9ALT

Thông báo dành cho lớp CDTH9ALT

Danh sách sinh viên mới nhất học môn Chuyên đề phát triển phần mềm:

http://www.mediafire.com/?d7dy821u11vc26a

Danh sách sinh viên mới nhất học môn Đồ án chuyên nghành:

http://www.mediafire.com/?1wh9glzcxygaojw

Đây là danh sách mới nhất mà Thầy cập nhật lúc 18h00 ngày 21/03/2012

Những sinh viên nào không có tên trong danh sách mới nhất này thì phải liên hệ với giáo vụ khoa

hạn chót là ngày 24/03/2012, sau ngày này những em không có tên trong danh sách mà vẫn không liên hệ với giáo vụ khoa để cập nhật danh sách thì Thầy sẽ hủy toàn bộ kết quả học tập của 2 môn này.

Thầy Thanh.

 

Thông báo dành cho lớp CĐTH9ALT

Hiện nay Thầy đang cập nhật thêm danh sách mới để vào điểm

Do đó sau khi Thầy gửi thông báo về DANH SÁCH MỚI NHẤT thì các em hãy email cho Thầy nếu như vẫn chưa có tên trong danh sách. Nên từ  giờ cho tới khi Thầy cập nhật danh sách mới thì mọi thắc mắc về điểm cũng như  tên của mình tại sao không có trong danh sách là chưa cần thiết.

Chú ý: Sau khi Thầy đã cập nhật danh sách cuối cùng rồi, mà vẫn còn một số sinh viên Nợ học phí hay là lý do nào đó mà Thầy không lấy được tên các em vào danh sách môn học mà các em đang tham gia, thì coi như Thầy hủy toàn bộ kết quả của những em này. Khoa đã thông báo về vấn đề đăng ký học phần, nộp học phí rất lâu rồi, còn nhiều chuyện để làm chứ không phải ngày nào cũng kiểm tra để cập nhật từng người vào danh sách cho các em như  học sinh mẫu giáo. Rất mất thời gian

Thầy Thanh.

Sự khác biệt giữa Managed code and unmanaged code trong .NET

.NET hỗ trợ 2 loại coding:

– Managed Code

– Unmanaged Code

Vậy sự khác biệt giữa chúng là gì?

– Managed Code: Các bạn hiểu nôm na là tất cả các code mà được viết trong .net framework thì được gọi là Managed code, các mã này sẽ được trực tiếp thực thi bởi CLR(Common Language Runtime). Lúc đó ứng dụng của chúng ta sẽ được CLR quản lý bộ nhớ, xử lý các vấn đề bảo mật, gỡ rối chương trình…và các tính năng hữu ích khác.

– Unmanaged Code: mã nguồn được phát triển ngoài .net framework, tức là ứng dụng không có chạy dưới sự điều khiển của CLR, Unmanaged Code được thực thi dưới sự hỗ trợ của 2 wrapper class đó là: CCW (COM Callable Wrapper) and RCW (Runtime Callable Wrapper). 2 class này thực thi như sau:

Nguồn http://www.c-sharpcorner.com

Thông báo khẩn tới sinh viên đang học Đồ Án Chuyên Nghành và CĐPTPM

Thông báo khẩn tới sinh viên đang học Đồ Án Chuyên Nghành và Chuyên đề phát triển phần mềm

Hiện nay rất nhiều em không có tên trong danh sách chính thức nên Thầy không thể vào điểm được, các em phải liên hệ với giáo vụ khoa để giải quyết sớm về vấn đề này.

Vì đang thời gian cuối kỳ, nếu như các em không giải quyết sớm những vướng mắc thì Thầy không thể nhập điểm đồng nghĩa với việc kết quả học tập của các em sẽ bị hủy bỏ.

Cụ Thể:

1) Môn đồ án chuyên nghành có tới 14 em đã nội bài cho thầy mà  không có tên trong danh sách chính thức, Thầy có gửi bảng điểm đính kèm, đó là danh sách mới nhất mà Thầy in từ Edu ra, Những em không có tên thì phải gặp giáo vụ khoa để giải quyết.

2) môn chuyên đề phát triển phần mềm, danh sách chính thức hiện nay chỉ có 34 em, Thầy không thể nhập điểm thành phần cho các em còn lại, tức là kết quả sẽ không được công nhận (đa phần nợ học phí).

Thông báo nghỉ học ngày thứ 5 tuần này (22/03/2012) http://duythanhcse.wordpress.com/2012/03/19/thong-bao-ngh%E1%BB%89-h%E1%BB%8Dc-th%E1%BB%A9-5-ngay-22032012/

Thông báo bổ sung giờ học môn CĐPTPM

Thông báo dành cho lớp CĐTH9ALT

Bắt đầu từ ngày 19/03/2012 môn Chuyên Đề Phát Triển Phần Mềm sẽ học 2 buổi : Thứ 3 và Thứ 5

Buổi học bổ sung vào tối thứ 5, học phòng A4.05 từ tiết 13->tiết 15

Sinh viên đang theo học môn này thì vào link bên dưới để xem thông tin:

http://duythanhcse.wordpress.com/l%E1%BB%8Bch-gi%E1%BA%A3ng-d%E1%BA%A1y/

Thầy Thanh.

Thông báo dành cho lớp CDTH9ALT

Để giúp cho việc chấm điểm bài tập về nhà, labreport cũng như đề tài của môn Chuyên Đề Phát Triển Phần Mềm.

Thầy đã tổng hợp danh sách và upload tại đây : http://www.mediafire.com/?13f9fgvn32rqcdu (mới)

Các em vào xem danh sách, kiểm tra xem nếu có sai sót thì email tới tranduythanh.fit@gmail.com để Thầy cập  nhật thông tin

Các em chú ý là gửi thông tin vào email của Thầy, để Thầy có thể cập nhật, bởi vì một số nhóm comment trên blog nhưng vì một số lý do về nội dung nên blog của Thầy tự động đưa những comment đó vào Spam nên Thầy không có để ý.

Trên lớp Thầy đã giải thích rõ ràng về cách thức sử dụng email, các em phải hiểu điều này, không phải thầy làm khó các em về chuyện email mà là Thầy muốn các em sử dụng email một cách chuyên nghiệp, nên một lần nữa Thầy mong muốn các em hiểu thâm ý bên trong. Thầy cảm thấy nó không khó khăn gì với sinh viên chuyên nghành CNTT để tạo một email mang họ tên của chính mình. Blog của Thầy có chế độ tự động đưa các comment không phù hợp vào Spam nên Thầy không có trả lời ngay được. Thanks All.

Chú ý:

1. Một số em đăng ký nhóm nhưng mà chưa chọn đề tài nên mục Tên đề tài sẽ để trống, các em phải gửi email gấp.

2. Còn nhiều nhóm gửi thông tin quá sơ sài. chưa đủ các thông tin: Mã số Sinh viên, tên, điện thoại, email. Yêu cầu phải cập nhật.

Thầy Thanh.

ps: Vì Thầy đang chấm điểm nên yêu cầu các sinh viên lớp CĐTH9ALT phải nhanh chóng cập nhật những thông tin đang còn thiếu sót, hạn chót là ngày 17/03/2012

Ví dụ mẫu mở các JFrame hay JDialog khác trong Java1

Trong topic này Tôi muốn hướng dẫn các bạn cách mở các cửa sổ windows khác trong Java .

Tình huống: Bạn quan sát hình Tôi chụp bên dưới, từ 1 cửa sổ chính chứa 2 JButton, mỗi JButton sẽ có chức năng mở các cửa sổ khác nhau. Ở đây Tôi muốn hướng dẫn 2 tình huống đó là mở 1 JFrame và 1 JDialog khác để từ đó các bạn có thể tham khảo áp dụng cho các chương trình tương tự. Bạn phải biết được sự khác biết giữa JFrame và JDialog (mặc định Tôi cho là các bạn đã biết  )

———————————————————————————————————————————————-

Tôi cung cấp cho các bạn 3 class:

class MyMainUI sẽ chứa 2 JButton : Open MyUI1 và Open MyUI2

class MyUI1 kế thừa từ JFrame

class MyUI2 kế thừa từ JDialog

Các bạn quan sát sự kiện tôi gán cho 2 JButton trong class MyMainUI để thấy được sự khác biệt.

———————————————————————————————————————————————-

Dưới đây là Coding mẫu:

=========================================================================

class MyMainUI

=========================================================================

import java.awt.Container;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JPanel;

public class MyMainUI extends JFrame{

private static final long serialVersionUID = 1L;

public MyMainUI(String title)

{

setTitle(title);

}

public void doShow()

{

setSize(400,200);

setLocationRelativeTo(null);

setDefaultCloseOperation(EXIT_ON_CLOSE);

addControl();

setVisible(true);

}

public void addControl()

{

JPanel pnBox=new JPanel();

JButton btn1=new JButton(“Open MyUI1”);

JButton btn2=new JButton(“Open MyUI2”);

pnBox.add(btn1);

pnBox.add(btn2);

btn1.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent arg0) {

MyUI1 ui1=new MyUI1(“Hello Teo!”);

ui1.setVisible(true);

}

});

btn2.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent arg0) {

MyUI2 ui2=new MyUI2(“Hello Teo!”);

ui2.setModal(true);

ui2.setVisible(true);

}

});

Container con=getContentPane();

con.add(pnBox);

}

public static void main(String[] args) {

MyMainUI mainUI=new MyMainUI(“Demo OPen Another Windows”);

mainUI.doShow();

}

}

=========================================================================

class MyUI1

=========================================================================

import java.awt.Container;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.JTextField;

public class MyUI1 extends JFrame{

private static final long serialVersionUID = 1L;

public MyUI1(String title)

{

setTitle(“My JFrame”);

doAddSomeControl();

}

public void doAddSomeControl()

{

JPanel pn=new JPanel();

JButton btn1=new JButton(“Hello I’m JFrame”);

JTextField txt1=new JTextField(15);

pn.add(btn1);

pn.add(txt1);

Container con=getContentPane();

con.add(pn);

setSize(300, 200);

setLocationRelativeTo(null);

}

}

=========================================================================

class MyUI2

=========================================================================

import java.awt.Container;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import javax.swing.JButton;

import javax.swing.JDialog;

import javax.swing.JLabel;

import javax.swing.JOptionPane;

import javax.swing.JPanel;

import javax.swing.JTextField;

public class MyUI2 extends JDialog{

private static final long serialVersionUID = 1L;

public MyUI2(String title)

{

setTitle(“My JDialog”);

doAddSomeControl();

}

public void doAddSomeControl()

{

JPanel pn=new JPanel();

JButton btn1=new JButton(“Hi ! My name is JDialog”);

JButton btn2=new JButton(“Click me!”);

JTextField txt1=new JTextField(15);

JLabel lbl1=new JLabel(“Hello! Hello!”);

pn.add(btn1);

pn.add(txt1);

pn.add(lbl1);

pn.add(btn2);

btn2.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

JOptionPane.showMessageDialog(null, “Click tui hả?”);

}

});

Container con=getContentPane();

con.add(pn);

setSize(300, 200);

setLocationRelativeTo(null);

}

}

Chúc các bạn thành công

Ví dụ mẫu .Net Remoting & Windows Services

VÍ DỤ NÀY TÔI TÁCH LÀM 2 PHẦN (Sử dụng Visual Studio 2010, coding bằng C#).

Phần 1: Tôi hướng dẫn các bạn cách thực hiện .Net Remoting. Sẽ có 3 Project trong solution này. Tầng ProxyObject, tầng Server và tầng Client. Trong đó tầng Server sẽ có giao diện để Start Stop Server, Tầng Client có giao diện để kết nối tới Server để gọi một số phương thức trong tầng ProxyObject.

Phần 2: Tiếp tục với ví dụ trong phần 1, nhưng trong trường hợp này Tôi sẽ không tạo giao diện cho tầng Server, mà Tôi đưa tầng Server về chạy theo dạng Windows Services.

Tôi nghĩ rằng Topic này sẽ rất hữu ích cho những bạn muốn quan tâm tới các chương trình .Net Remoting, Windows Services, cách sử dụng component Eventlog, cũng như cách làm deployed chương trình. Vì Tôi hướng dẫn chi tiết nên có thể bạn cảm thấy làm nó dài và phức tạp, nhưng thực ra nếu khi các bạn làm hiểu rành rồi thì chỉ cần 5-10 phút là xong tầng Service và Setup. Chúc các bạn thành công.

Link download hướng dẫn: http://www.mediafire.com/download/cqimq779ia65deg/NetRemotingAndWindowsServices.docx

Link download source code:http://www.mediafire.com/download/z0lpphb6np3o3b6/NetRemotingAndWindowsServices.rar

 

———————————————————————————————————————————–

Dưới đây là các bước chi tiết cho phần 1:

Bước 1: Tạo tên Solution

Bước 2: Tiến hành tạo 3 Project cho Solution: Tầng ProxyObject, tầng Server và Client

Bước 3: Tiến hành viết coding cho tầng ProxyObject

Bước 4: Tiến hành viết coding cho tầng Server

Bước 5: Tiến hành viết code cho Tầng Client

Bước 6: Biên dịch và chạy chương trình

———————————————————————————————————————————–

Bước 1: Tạo tên Solution

Tôi đặt solution cho ví dụ này là: NetRemotingAndWindowsServices

Để đơn giản, tầng ProxyObject Tôi chỉ viết 1 class gọi là PrimeProxy, class này có nhiệm vụ nhận vào 1 số nguyên từ tầng client, sau đó trả về dãy số nguyên tố từ 2 tới n và đồng thời cho biết client là người thứ mấy gọi yêu cầu lên server.

Cách tạo : Vào menu File/ New/ chọn Project hoặc nhấn tổ hợp phím Ctrl+Shift+N

Cửa sổ New Project sẽ hiển thị ra, bạn hãy chọn Blank Solution trong mục Visual Studio Solutions

Trong ô Name: Nhập tên NetRemotingAndWindowsServices sau đó nhấn nút OK.

Bạn quan sát trong mục Solution Explorer sẽ xuất hiện tên Solution mà bạn vừa tạo

Bước 2: Tiến hành tạo 3 Project cho Solution: Tầng ProxyObject, tầng Server và Client

–         Tầng ProxyObject: Trong tầng này bạn phải chọn là Class Library

–         Bấm chuột phải vào tên solution/ chọn Add / chọn New Project

–         Sau khi bạn chọn New Project thì cửa sổ Add New Project xuất hiện, tại cửa sổ này bạn hãy chọn Class Libray

–         Trong ô Name: bạn gõ tên ProxyObject rồi click OK.

–         Tiếp theo bạn tạo tầng ServerClient, cách tạo 2 tầng này sẽ tương tự như tầng ProxyObject,  nhưng chọn là Windows Forms Application thay vì Class Library

–         Bạn tuần tự tạo xong các tầng, và quan sát Solution Explorer:

Ta có 3 Projects trong Solution NetRemotingAndWindowsServices

Bước 3: Tiến hành viết coding cho tầng ProxyObject

–         Đổi tên Class1 thành PrimeProxy và viết code như bên dưới:

using System;using System.Collections.Generic;using System.Linq;using System.Text;

namespace ProxyObject{

public class PrimeProxy:MarshalByRefObject{//Biến lưu số lần client gọi hàm lấy danh sách nguyên tố

private int m_RequestNumber = 0;

//Biến lưu tên Client hiện tại gọi hàm

private string m_strCurrentClient = “”;

//Biến lưu danh sách tên các client đã connect tới server

private List<string> m_listClient = new List<string>();

//hàm kiểm tra số nguyên tố

public bool isPrime(int k)

{

if (k < 2) return false;

for (int i = 2; i <= Math.Sqrt(k); i++)

if (k % 2 == 0) return false;

return true;

}

//hàm thiết lập client hiện tại connect tới server và

//lưu client vào danh sách đã kết nối

public void setConnectClient(string clientName)

{

m_strCurrentClient = clientName;

if (!m_listClient.Contains(clientName))

m_listClient.Add(clientName);

}

//Hàm trả về danh sách các số nguyên tố

public List<int> getListPrime(int n)

{

m_RequestNumber++;

List<int>lst=new List<int>();

for (int i = 2; i <= n; i++)

if (isPrime(i))

lst.Add(i);

return lst;

}

public int RequestNumber

{

get { return this.m_RequestNumber;}

}

public string CurrentClient

{

get { return this.m_strCurrentClient; }

}

public List<string> ListClient

{

get { return this.m_listClient; }

}

}

}

Bước 4: Tiến hành viết coding cho tầng Server

Đổi class Form1.cs thành frmServer.cs và thiết kế giao diện như hình bên dưới:

Control Tên Control Mô tả
TextBox txtPort Dùng để nhập Port server
TextBox txtStatus Để hiện thị trạng thái Server
RadioButton radSingleton Singleton
RadioButton radSingleCall SingleCall
Button btnStart Khởi động
Button btnStop Tắt

Sau khi thiết kế xong, để tiến hành Coding cho tầng Server thì bạn phải tham chiếu như hướng dẫn bên dưới:

–         Tầng Server phải tham chiếu tới tầng ProxyObject và thư viện System.Runtime.Remoting

Tham chiếu tới ProxyObject: Bấm chuột phải vào References / Add Reference

Cửa sổ Add Reference hiển lên, chọn ProxyObject rồi nhấn OK

Tương tự khi Add tham chiếu tới thư viện System.Runtime.Remoting, trường hợp này bạn chọn tab .NET thay vì tab Project.

Trong tab .NET bạn chọn System.Runtime.Remoting rồi nhấn OK

Sau đó bạn quan sát tầng Server, nếu như nó như hình bên dưới là đã thành công:

–         Bây giờ ta tiến hành viết code cho tầng Server, xem coding:

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.Runtime.Remoting;

using System.Runtime.Remoting.Channels;

using System.Runtime.Remoting.Channels.Tcp;

using ProxyObject;

namespace TangServer

{

public partial class frmServer : Form

{

private TcpChannel tcpChannel = null;

private int port = 8998;

private Type type;

private WellKnownObjectMode wellKnownMode;

private string objURI;

public frmServer()

{

InitializeComponent();

}

private void btnStart_Click(object sender, EventArgs e)

{

try

{

btnStop.PerformClick();

port = Int32.Parse(txtPort.Text);

//tạo kênh truyền dữ liệu

tcpChannel = new TcpChannel(port);

ChannelServices.RegisterChannel(tcpChannel, false);

//đăng ký remote object với Remoting framework

type = typeof(PrimeProxy);

objURI = “PRIME_URI”;

if (radSingleTon.Checked == true)

wellKnownMode = WellKnownObjectMode.Singleton;

else

wellKnownMode = WellKnownObjectMode.SingleCall;

RemotingConfiguration.RegisterWellKnownServiceType

(type, objURI, wellKnownMode);

txtStatus.Text = “khởi động server tại por ” + port.ToString() + ” lúc ” + DateTime.Now.ToString();

}

catch (Exception ex)

{

MessageBox.Show(“Lỗi”, ex.Message);

}

}

private void btnStop_Click(object sender, EventArgs e)

{

if (ChannelServices.GetChannel(“tcp”) != null)

{

ChannelServices.UnregisterChannel(tcpChannel);

txtStatus.Text = “tắt server tại port ” + port.ToString() + ” lúc ” +   DateTime.Now.ToString();

}

}

}

}

Bước 5: Tiến hành viết code cho Tầng Client

Đổi class Form1.cs thành frmClient.cs và thiết kế giao diện như hình bên dưới:

Control Tên Control Mô tả
TextBox txtIP Địa chỉ server: tên hoặc IP
TextBox txtPort Để nhập Port kết nối
TextBox txtClient Tên client sử dụng : Tèo
TextBox txtN Nhập N để lấy dãy nguyên tố
Button btnConnect Bắt đầu kết nối tới server
Button btnGetResult Lấy kết quả từ server
ListBox lstbListPrime ListBox lưu dãy nguyên tố
ListBox lstbListClient ListBox lưu danh sách Client
Label lblMessage Số lần hàm được triệu gọi từ client
Label lblStatus Trạng thái

–         Tương tự như tầng Server, bạn tham chiếu tới tầng ProxyObject và thư viện System.Runtime.Remoting

–         Bây giờ ta tiến hành viết code cho tầng Client, xem coding:

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.Runtime.Remoting;

using System.Runtime.Remoting.Channels;

using System.Runtime.Remoting.Channels.Tcp;

using ProxyObject;

namespace TangClient

{

public partial class frmClient : Form

{

#region variables

string URL = “”;

Type type;

PrimeProxy primeObject;

#endregion

public frmClient()

{

InitializeComponent();

}

private void enableControl(bool b)

{

btnGetResult.Enabled = b;

txtClient.Enabled = b;

txtN.Enabled = b;

}

private void btnConnect_Click(object sender, EventArgs e)

{

try

{

//xây dựng chuỗi URL để truy tìm tài nguyên trên server

URL = “tcp://” + txtIP.Text + “:” + txtPort.Text + “/PRIME_URI”;

//đăng ký remote object

type = typeof(PrimeProxy);

RemotingConfiguration.RegisterWellKnownClientType(type, URL);

//tạo proxy

primeObject = new PrimeProxy();

lblStatus.Text = “Đã tạo xong proxy, vui lòng nhập Client, nhập N:”;

enableControl(true);

}

catch (Exception ex)

{

MessageBox.Show(ex.Message);

enableControl(false);

URL = “”;

}

}

private void frmClient_Load(object sender, EventArgs e)

{

enableControl(false);

}

private void btnGetResult_Click(object sender, EventArgs e)

{

string client = txtClient.Text;

int n = Int32.Parse(txtN.Text);

//Gửi tên client lên server

primeObject.setConnectClient(client);

//Lấy danh sách các số nguyên tố từ server về

List<int> listPrime= primeObject.getListPrime(n);

//Đưa danh sách số nguyên tố lên ListBox

lstbListPrime.Items.Clear();

foreach(int x in listPrime)

lstbListPrime.Items.Add(x);

//Lấy danh sách Client tồn tại trên server

List<string> listClient = primeObject.ListClient;

//Đưa danh sách client lên Listbox

lstbListClient.Items.Clear();

lstbListClient.Items.AddRange(listClient.ToArray());

string message = “”;

message =”Hello [” + primeObject.CurrentClient + “] Hàm này được triệu gọi ”

+ primeObject.RequestNumber +”\n”;

if(primeObject.RequestNumber==1)

message += ” Bạn là người đầu tiên triệu gọi hàm này!”;

else

message += ” Người gọi hàm này trước đó là [” +

listClient[listClient.Count-2] + “]”;

lblMessage.Text = message;

}

}

}

Bước 6: Biên dịch và chạy chương trình

Vào Menu Build / chọn Batch Build…Cửa sổ Batch Build sẽ hiển thị ra như bên dưới. Trong cửa sổ này bạn checked hết các tầng muốn build, rồi bấm Build hoặc Rebuild

Sau khi biên dịch xong, bạn vào thư mục bin/release của tầng Server và Client. Bạn tiến hành chạy chương trình:

Chạy tầng Server:

Chọn Port 8998, Singleton rồi bấm nút Khởi động, bạn sẽ được kết quả như hình trên. Để hiểu rõ cơ chế Singleton và SingleCall như thế nào thì các bạn xem các topic về .Net Remoting trong chuyên đề phát triển phần mềm mà tôi đã hướng dẫn.

–         Tiến hành chạy thử vài Client bạn sẽ có kế quả như hình bên dưới:

Các bạn chú ý là click nút Kết nối trước, sau đó mới click nút Lấy kết quả.

Bạn có thể chạy nhiều client để kiểm tra kết quả.

================================================================================

Phần 2: Cấu hình chạy Server dưới dạng Windows Services

Bước 1: Tạo project Windows Services

Bước 2: Tạo project Setup cho bước 1

Bước 3: Cài đặt, chạy và kiểm tra services, eventlog

================================================================================

Chúng ta sẽ đi vào chi tiết từng bước

Bước 1: Tạo project Windows Services

Tương tự như khi tạo các tầng trước, bạn bấm chuột phải vào solution/ Add/ New Project.

Chọn Windows Service, nhập tên project là: MyPrimeServices rồi click Ok, sau khi click ok bạn quan sát sự thay đổi trong Solution:

Bạn double click vào tập tin Service1.cs (tập tin này mặc định được tạo ra cùng với project). Sau khi double click, cửa sổ Design màu xám của Services1.cs sẽ được hiển thị ra, bạn click chuột vào vùng xám (không phải double click, tức là chỉ click chuột 1 lần)

Sau khi click chuột vào vùng xám, bạn đổi tên (Name) từ Service1 thành MyPrimeServices8998 như hình trên, 8998 ý tôi muốn ghi gợi nhớ là tôi muốn tạo services chạy ở cổng 8998.

Bây giờ ta tiến hành viết code cho class services của mình. Trong vùng design màu xám, bạn click vào dòng chữ  “Click here to switch to code view” hoặc nhấn phím F7.

Mặc định ta sẽ có class như bên dưới:

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Diagnostics;using System.Linq;

using System.ServiceProcess;

using System.Text;

namespace MyPrimeServices

{

public partial class MyPrimeServices8998 : ServiceBase

{

public MyPrimeServices8998()

{

InitializeComponent();

}

protected override void OnStart(string[] args)

{

}

protected override void OnStop()

{

}

}

}

Hàm OnStart và OnStop tự động phát sinh trong class MyPrimeServices8998 , class này sẽ được kế thừa từ ServiceBase . Bạn có thể override thêm nhiều phương thức như bên dưới để phục vụ một số yêu cầu mà bạn mong muốn, còn không thì cứ để mặc định 2 hàm trên:

protected override void OnContinue(){base.OnContinue();}protected override void OnPause(){

base.OnPause();

}

protected override void OnShutdown()

{

base.OnShutdown();

}

Tôi sửa lại class MyPrimeServices8998 này như sau: Tôi sẽ thêm 2 hàm myServerStart()

Và myServerStop() . Trong hàm myServerStart() bạn chỉ cần copy paste toàn bộ code trong button Khởi động của tầng server vào đây. Tương tự myServerStop()  bạn copy paste code trong button Tắt vào. Các bạn chú ý là chúng ta cũng phải tham chiếu tới tầng ProxyObject và thư viện System.Runtime.Remoting, các bạn xem code Tôi chép:

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

using System.Data;

using System.Diagnostics;

using System.Linq;

using System.ServiceProcess;

using System.Text;

using System.Runtime.Remoting;

using System.Runtime.Remoting.Channels;

using System.Runtime.Remoting.Channels.Tcp;

using ProxyObject;

namespace MyPrimeServices

{

public partial class MyPrimeServices8998 : ServiceBase

{

private TcpChannel tcpChannel = null;

private int port = 8998;

private Type type;

private WellKnownObjectMode wellKnownMode;

private string objURI;

public MyPrimeServices8998()

{

InitializeComponent();

}

private void myServerStart()

{

try

{

myServerStop();

//tạo kênh truyền dữ liệu

tcpChannel = new TcpChannel(port);

ChannelServices.RegisterChannel(tcpChannel, false);

//đăng ký remote object với Remoting framework

type = typeof(PrimeProxy);

objURI = “PRIME_URI”;

wellKnownMode = WellKnownObjectMode.Singleton;

RemotingConfiguration.RegisterWellKnownServiceType(type, objURI, wellKnownMode);

}

catch (Exception ex)

{

}

}

private void myServerStop()

{

if (ChannelServices.GetChannel(“tcp”) != null)

{

ChannelServices.UnregisterChannel(tcpChannel);

}

}

protected override void OnStart(string[] args)

{

myServerStart();

}

protected override void OnStop()

{

myServerStop();

}

}

}

Ở đây mặc định là chạy port 8998, và SingleTon. Một vấn đề nảy sinh là làm sao chúng ta biết được service của mình Start khi nào, Stop khi nào và các lỗi sảy ra thì chúng ta xem ở đâu??? Để làm được điều này, Tôi sẽ hướng dẫn các bạn sử dụng component Eventlog.

Bạn tìm tới EventLog trong danh mục Components, kéo thả control này vào vùng Design màu xám của Service1.cs. Sau đó bạn tiến hành viết code cho eventlog, Tôi sẽ hướng dẫn các bạn xem các thông tin Log này trong phần cuối, bây giờ bạn hãy xem code hoàn chỉnh mà Tôi cung cấp:

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

using System.Data;

using System.Diagnostics;

using System.Linq;

using System.ServiceProcess;

using System.Text;

using System.Runtime.Remoting;

using System.Runtime.Remoting.Channels;

using System.Runtime.Remoting.Channels.Tcp;

using ProxyObject;

namespace MyPrimeServices

{

public partial class MyPrimeServices8998 : ServiceBase

{

private TcpChannel tcpChannel = null;

private int port = 8998;

private Type type;

private WellKnownObjectMode wellKnownMode;

private string objURI;

public MyPrimeServices8998()

{

InitializeComponent();

if (System.Diagnostics.EventLog.SourceExists(“PRIME8998”) == false)

{

System.Diagnostics.EventLog.CreateEventSource(“PRIME8998”, “LOG8998”);

}

eventLog1.Source = “PRIME8998”;

eventLog1.Log = “LOG8998”;

}

private void myServerStart()

{

try

{

myServerStop();

//tạo kênh truyền dữ liệu

tcpChannel = new TcpChannel(port);

ChannelServices.RegisterChannel(tcpChannel, false);

//đăng ký remote object với Remoting framework

type = typeof(PrimeProxy);

objURI = “PRIME_URI”;

wellKnownMode = WellKnownObjectMode.Singleton;

RemotingConfiguration.RegisterWellKnownServiceType(type, objURI, wellKnownMode);

eventLog1.WriteEntry(“khởi động server tại port ” + port.ToString() + ” lúc ” + DateTime.Now.ToString());

}

catch (Exception ex)

{

eventLog1.WriteEntry(“Lỗi : ” + ex.Message);

}

}

private void myServerStop()

{

try

{

if (ChannelServices.GetChannel(“tcp”) != null)

{

ChannelServices.UnregisterChannel(tcpChannel);

eventLog1.WriteEntry(“tắt server tại port ” + port.ToString() + ” lúc ” + DateTime.Now.ToString());

}

}

catch (Exception ex)

{

eventLog1.WriteEntry(“Lỗi : ” + ex.Message);

}

}

protected override void OnStart(string[] args)

{

myServerStart();

}

protected override void OnStop()

{

myServerStop();

}

}

}

Như vậy bạn đã hoàn thành xong class service MyPrimeServices8998

Tiếp theo ta tiến hành Add Installer cho Services, bằng cách bấm chuột phải vào vùng xám, chọn Add Installer

Chương trình sẽ tự động add thêm tập tin ProjectInstaller.cs, trong tập tin này cũng tự động chứa serviceInstaller1 và serviceProcessInstaller1 như hình bên dưới:

Chỉnh sửa serviceProcessInstaller1:

Sửa Account thành: LocalSystem

Chỉnh sửa serviceInstaller1:

Sửa ServiceName thành : MyPrimeServices8998

Sửa StartType thành: Automatic

Sau khi chỉnh sửa xong, bạn tiến hành Build project MyPrimeServices.

Bước 2: Tạo project Setup cho bước 1

Tương tự như các tầng khác, bạn cũng tạo 1 project mới và chọn là Setup Project trong mục Setup and Deployment/ Visual Studio Installer

Đặt tên project là : MyPrimeServicesSetup rồi click OK.

Bạn quan sát Solution explorer, chúng ta sẽ thấy tầng MyPrimeServicesSetup xuấn hiện như bên dưới

Để add Project mà bạn muốn cài đặt, bạn click chuột phải vào project MyPrimeService/ chọn Add/ chọn ProjectOutput

Trong cửa sổ Add Project Output Group: bạn chọn MyPrimeServicesPrimary output rồi nhấn nút OK.

Sau khi nhấn OK, bạn sẽ được kết quả như bên dưới:

Tiếp tục, bấm chuột phải vào MyPrimeServiceSetup/ View/ Custom Actions

Trong màn hình Design, bạn sẽ thấy như bên dưới:

Tiếp theo bạn bấm chuột phải vào Custom Actions/ chọn Add Custom Actions

Màn hiình Select Item in Project sẽ hiển thị ra như bên dưới

Tại màn hình này, bạn double click vào thư mục Application Folder rồi nhấn OK:

Sau khi nhấn OK, bạn thấy kết quả :

Để hoàn tất quá trình tạo Project Setup, bạn bấm chuột phải vào MyPrimeServicesSetup, chọn Build/Rebuild:

Sau khi Build thành công thì mục InstallUninstall sẽ cho phép bạn tương tác:

Bạn chọn Install để tiến hành cài đặt chương trình của mình tự tạo, qua bước 3 để xem chi tiết:

Bước 3: Cài đặt, chạy và kiểm tra services, eventlog

Sau khi chọn Install, màn hình cài đặt sẽ xuất hiện như bên dưới:

Bấm Next để tiếp tục:

Chờ chương trình cài đặt:

Bạn đã cài đặt thành công MyPrimeService. Bây giờ để kiểm tra thực sự Service mà chúng ta tạo đã được tự động cài đặt hay chưa, bạn làm như sau:

Bấm chuột phải vào computer/ chọn Manage

Nếu bạn thấy trong Service có tồn tại MyPrimeServices8998 như hình dưới là thành công

Để xem eventlog mà chúng ta viết coding, thì bạn vào LOG8998 để quan sát:

Như vậy Service của chúng ta đã tự động cài đặt, bạn có thể Start hoặc Stop Service tùy thích bằng cách bấm chuột phải vào Service rồi chọn Start hoặc Stop.

Bây giờ chúng ta chỉ cần chạy mỗi Client mà Thôi. Server đã được Service tự động start rồi. Bạn có thể tiến hành cài đặt Service ở bất kỳ máy chủ nào bằng cách lấy tập tin cài đặt trong tầng Setup cài vào máy chủ mong muốn, sau đó tại các máy client bạn chỉ cần nhập cho đúng IP của máy chủ và port 8998 là mọi việc OK.

Bạn thấy đấy, giờ Tôi chỉ cần chạy Client…