Thứ Bảy, 24 tháng 1, 2015

Đóng gói ứng dụng C# bằng Visual Studio

Bài viết này sẽ trình bày chi tiết cách đóng gói một ứng dụng C# bằng Visual Studio mọi phiên bản.

I. Mở đầu

Trong bài này tôi sẽ trình bày cách tạo file Setup, đồng thời cũng sẽ hướng dẫn tạo Shortcut Uninstall trên Start Menu. Bài viết thực chất chia làm hai phần: phần tạo Install và phần tạo Uninstall.


II. Install

1. Tạo một Demo project

Bất kỳ ai muốn đóng gói phần mềm của họ thành file setup thì họ tất nhiên đã tạo một file setup của riêng họ rồi. Trong bài này tôi sẽ lấy một WinForm project đơn giản để làm ví dụ, thông qua ví dụ đó để áp dụng cho các trường hợp khác.
Tôi tạo một WinForm project tên là "Test of Setup". Mã chương trình như sau (nhớ là phải thêm using System.IO nhé):


Căn cứ vào đoạn code thì chúng ta cần phải vào thư mục Bin\Debug, trong thư mục Debug tạo một thư mục Input, trong thư mục Input tạo một file text có tên Sample.txt và trong file Sample thì bạn muốn viết gì vào thì viết, còn tôi thì viết trong đó là "gianpzo".
Khi biên dịch, kết quả như sau:


Ok, một chương trình đã được tạo ra, và tôi muốn đem chương trình đó đi tặng cho bạn gái tôi để cô ấy thấy tôi giỏi đến mức nào. Thế là mình phải đóng gói chương trình vừa viết lại để đem cho cô ấy.

2. Tạo Setup project


a. Tạo Setup project

Bây giờ chúng ta sẽ tạo Setup project cho chương trình vừa viết ở trên. Chuột phải vào Solution "Test of Setup" => Add => New Project => Other project type => Setup Project:


Chú ý: đối với những phiên bản VS 2012 trở đi, chúng ta phải lên mạng và tìm cách down thêm Visual Studio Installer và cài đặt thì mới xuất hiện Setup Project trong Other Project Type được. Tải Visual Studio Installer TẠI ĐÂY.
Tôi giữ nguyên tên là Setup1 cho nó đỡ lằng nhằng.
Kết quả, giao diện như sau:



b. Các bước cài đặt cơ bản

Bây giờ chúng ta cần tạo một Output cho setup. Chuột phải vào Application Folder => Add => Project Output... như bên dưới:


Sau đó chọn Primary Output => Ok:


Và kết quả như sau:


Trong Demo Project, chương trình của chúng ta sẽ phải lấy thông tin từ file Sample.txt để hiển thị ra ngoài màn hình. Do đó, file Sample.txt cũng phải đi kèm với file Setup luôn, có nghĩa là chúng ta cần phải add Sample.txt vào trong Setup Project (nếu không add thì chương trình của chúng ta sẽ bị lỗi). Để Add được thì chúng ta chuột phải vào Application Folder => Add => Folder => thế là một Folder mới xuất hiện, sửa thành Input, kết quả như sau:


Chuột phải vào thư mục Input => Properties => chọn thuộc tính AlwaysCreate là True:


Làm như thế có nghĩa là: khi chạy file Setup thì chương trình luôn tạo một Folder tên là Input trong ổ C, còn nó ở chỗ nào thì ta chẳng quan tâm, chỉ cần biết khi mà cài xong thì chương trình cần dùng những gì từ thư mục Input đó thì nó sẽ tự biết tìm đến và lấy, thế thôi.
Ok, chúng ta tiếp tục add Sample.txt vào trong thư mục Input để sau này khi phần mềm của mình đem sang máy khác cài thì nó còn biết đường mà tìm đến Input/Sample.txt.
Động tác Add như sau: chuột phải vào Input => Add => File => chọn đến file Sample.txt. Kết quả như sau:


c. Tạo Shortcut

Chuột phải vào Primary Output ở giữa màn hình và chọn Create Shortcut:


Tôi sửa lại tên thành "Test of setup", cái shortcut này sẽ là cái xuất hiện trên nền desktop khi mà chúng ta cài đặt xong.
Bây giờ chúng ta cần thiết đặt Icon cho Shortcut: chuột phải vào Shortcut vừa mới tạo => Properties => trong cửa sổ Properties, chọn Icon => Browse => Browse => nháy kép vào Application Folder thì nút Add File sẽ có hiệu lực, bấm vào Add File => chọn đến một file ảnh có đuôi dạng .ico để làm Icon cho Shorcut, chọn được file .ico rồi thì bấm OK:


Sau đó chúng ta cắt cái Shortcut vừa tạo và paste vào trong thư mục User's Desktop

Tiếp theo, chúng ta sẽ quan tâm đến thư mục User Program Menu, nhìn cái tên thì biết ngay thư mục này liên quan đến các hoạt động ở Program Menu (cái Menu mà khi bấm Start thì hiện ra đấy). Bây giờ chúng ta sẽ Add thư mục và Short cut vào thư mục User Program Menu. Điều đó có nghĩa là khi mà chương trình của chúng ta được cài thì sau khi bấm Start, thư mục chương trình và shortcut chương trình của chúng ta sẽ nằm trên cả Program Menu nữa (như vậy trông nó mới chuyên nghiệp).
Trước tiên là Add thư mục (tên thư mục thì tùy chọn, trong trường hợp này tôi cũng vẫn đặt tên là "Test of setup"), làm giống như add thư mục Input vào thư mục Application Folder:


Sau đó, chọn thư mục Test of setup vừa tạo, tiếp đó đưa chuột ra khung giữa chọn Create Shortcut (cái này là Shortcut nằm ở trên Program Menu), một hộp thoại sổ ra,  chúng ta nháy kép vào thư mục Application Folder sau đó chọn Primary ouput from Test of setup (Active) và ấn OK. Sau đó đặt tên cho Shortcut đó là được. Kết quả như sau:


3. Tiểu kết

Nếu bạn làm đến bước này mà không có vướng mắc gì thì chúc mừng bạn, bạn đã có thể Build chương trình và vào thư mục Setup1\bin\debug và chạy file setup được rồi. Sau khi cài xong thì sẽ có một Shortcut ở ngoài desktop và một trong Program Menu. Khi muốn gỡ chương trình thì chúng ta vào Control Panel gỡ như những chương trình bình thường khác. Còn nếu bạn không muốn vào đó để gỡ thì cũng có thể tự tạo cho mình một Uninstaller riêng theo như bên dưới.

III. Uninstall

Bước 1
Chuột phải vào File System On Target Machine => Add Special Folder => System Folder:


Bước 2
Chuột phải vào thư mục vừa tạo, chon Add => File và chọn đường dẫn đến file có tên là msiexec.exe nằm trong ổ C\Windows\System32 ở trong máy của bạn (cái file này chịu trách nhiệm thao tác việc uninstall chương trình của bạn):


Thiết đặt thuộc tính của file vừa mới chọn như trong hình bên dưới.


Bước 3
Tạo một Uninstall Shortcut trong thư mục Test of setup ở Program Menu (cái Menu xuất hiện khi ấn nút Start ấy):
Chọn System Folder => đưa chuột ra khoảng giữa và nháy chuột phải => Create new Shortcut => một hộp thoại mới mở ra, bên trong hộp thoại đó chọn System Folder => msiexec.exe => OK, sau đó đặt tên cho Shortcut đó là Uninstall:


Bước 4
Kích vào Setup Project của chúng ta sau đó ấn F4 một hộp thoại Properties (Properties của project) hiện ra. Ở đó chúng ta có thể tự mình thiết đặt rất nhiều các thuộc tính tùy chọn (cái này rảnh thì mới để ý đến):


Chú ý đên Production code, chúng ta sẽ phải dùng đến nó.

Bước 5
Chuột phải vào Shortcut Uninstall và chọn properties, chọn thuộc tính Arguments.
Trong thẻ Arguments chúng ta viết một đoạn code ngắn để chương trình biết là phải uninstall chương trình nào:
/x {product code} /qr
/x is for uninstalltion.
product code là cái mã mà tôi bảo bạn phải chú ý ấy, mã product code của bạn và của tôi là không giống nhau nhé.
các cú pháp thì chúng ta có thể tham khảo trong trang này: http://technet.microsoft.com/en-us/library/cc759262(v=ws.10).aspx



Bước 6
Save mọi thứ lại và Build chương trình. Thế là chúng ta đã có một file cài đặt rất pro rồi.

IV. Kết Luận

Thực ra thì chúng ta có thể tự viết setup code cho chương trình của mình nhưng cái này cũng khá là loằng ngoằng, đợi một thời gian sau tôi sẽ tiếp tục viết thêm.

Tài liệu tham khảo:
http://www.codeproject.com/Articles/568476/Creating-an-MSI-Setup-Package-for-Csharp-Windows

Chủ Nhật, 18 tháng 1, 2015

Làm đẹp code trong blog với Syntaxhighlighter

Cách đây vài ngày tôi mới bắt đầu viết một blog cho riêng mình (chính là blog này),  tôi không biết về HTML hoặc các ngôn ngữ đánh dấu khác cho nên khi đọc một số bài viết nói về những chiếc thẻ (tag) là thấy đau đầu liền. Nhưng về thực chất, không cần hiểu về những cái đó nhưng vẫn có thể đăng những bài viết với những đoạn code đẹp như trong Stackoverflow.com bằng cách sử dụng Syntaxhighlighter.
Không cần phải download Syntaxhighlighter về máy, chỉ cần copy đoạn code dưới đây và paste vào bên trên thẻ </head> (nhớ là bên trên thẻ </head> chứ không phải là bên trên thẻ <head> đâu nhé) trong cửa sổ edit HTML là được.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Cách mở cửa sổ Edit HTML:

 Đăng nhập bào blog của chính mình và chọn "thiết kế"

Chọn mẫu -> chọn "chỉnh sửa HTML" 

 Trong cửa sổ HTML bên dưới chọn đến thẻ </head> và paste đoạn mã bên dưới vào là được.

Cách Edit code trong blog

Khi muốn viết 1 đoạn code trong blog thì chúng ta phải chọn viết ở chế độ HTML
Sau đó đặt đoạn code của mình nằm bên trong thẻ <pre> là được. Ví dụ:
// Comment
// Comment
public class Testing {
public Testing() {
}
 
public void Method() {
/* Another Comment
on multiple lines */
int x = 9;
}
}
Sau khi lưu sẽ trở thành như sau:


// Comment
public class Testing {
public Testing() {
}
 
public void Method() {
/* Another Comment
on multiple lines */
int x = 9;
}
}

Và như vậy là mình đã có một blog viết code khá là chuyên nghiệp rồi.

Tài liệu tham khảo: 
http://www.craftyfella.com/2010/01/syntax-highlighting-with-blogger-engine.html

Thứ Năm, 15 tháng 1, 2015

Ví dụ đơn giản về Plug-in

Khi tìm kiếm trên mạng về Plug-in thì có rất nhiều bài đã viết về vấn đề này, nhưng có điều những bài viết đó hầu hết là viết cho những cao thủ có nội công thâm hậu cho nên mình tìm và đọc trong hai ngày mà đầu óc cứ choáng hết cả váng. Nhưng cũng thật may mắn, cuối cùng thì mình cũng tìm được một bài khá là đơn giản và có thể làm mình hiểu được đôi chút, hôm nay rảnh rỗi ngồi viết lại (có sửa đôi chút) để giết thời gian.hj

I. PLUG-IN LÀ GÌ?

"Trong kỹ thuật máy tính, plugin là một bộ phần mềm hỗ trợ mà thêm những tính năng cụ thể cho một phần mềm ứng dụng lớn hơn. Nếu được hỗ trợ, plugin cho phép tùy biến các chức năng của một ứng dụng. Ví dụ, plugin thường được sử dụng trong các trình duyệt web để chơi video, quét virus, và hiển thị các tập tin mới. Ví dụ hai plugin được biết đến rộng rãi bao gồm Adobe Flash Player và QuickTime."--http://vi.wikipedia.org/wiki/Plugin.
Tóm lại plugin là một phần mềm mà mình viết độc lập với chương trình chính nhằm thêm mới chức năng.
II. VÍ DỤ MINH HỌA

Trong phần này mình sẽ viết một chương trình WinForm minh họa Plugin.

1. Đề bài

Vì nhu cầu giải toán của học sinh lớp 1 tăng cao, cho nên các chuyên gia đề xuất viết một chương trình máy tính (Calculator) để làm cho học sinh lớp 1 dễ dàng làm toán hơn. các phép toán thì có rất nhiều: cộng, trừ, nhân, chia... nhưng vì đội ngũ nhân lực chỉ có hai người có hạn nên tạm thời chỉ viết chương trình tính phép cộng trước đã, còn các phép tính khác sẽ để sau này có thời gian thì viết tiếp (tạo các plugin trừ, nhân, chia,... và gắn vào chương trình Calculator).
Nhưng ở đây tôi sẽ viết luôn một thư viện(cũng có thể hiểu là plugin) CalculatePluginLibrary.dll gồm hai phép trừ (CalculatePluginLibrary.Minus) và nhân (CalculatePluginLibrary.Multiply) luôn.

2. Giao diện chương trình chính

Các bạn đừng ngại thiết kế lại giao diện nhé, nếu ngại thì chẳng hiểu được đâu. hehe
Mở Visual Studio lên, chọn New Project -> Window Form, đặt tên cho solution là CalculatorWithPlugin và thiết kế như bên dưới.
- lbxFunctions là để chứa các chức năng mà mình muốn chương trình làm (ví dụ cộng, trừ, nhân, chia...)
- còn tại mnsPlugin có chức năng thêm các plugin mới vào cho chương trình (Add Plugin)



3. Tạo Interface ICalculate

Để các plugin có thể gán vào chương trình CalculatorWithPlugin , chúng ta phải đặt ra một số qui tắc qui định những plugin nào mới có thể được gắn vào chương trình. Interface chính là để làm điều đó.
Tạo một Solution mới độc lập với solution CalculatorWithPlugin, loại của solution này là Class
Library, đặt tên là Interfaces. Mã chương trình như sau:
// Comment

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

namespace Interfaces
{
    public interface ICalculate
    {
        int Operate(int a, int b);
    }
}

sau đó buld chương trình này, trình biên dịch sẽ tạo ra một file Interfaces.dll trong thư mục ...Interfaces\bin\Debug. Tẹo nữa chúng ta sẽ dùng đến nó để qui định plugin nào được gắn vào chương trình CalculatorWithPlugin của chúng ta.

4. Viết một thư viện .dll để gắn vào chương trình chính (cái này gọi là 1 Plug-in)

Mở Visual Studio lên và tạo một Solution mới với tên là CalculatePluginLibrary, loại của Solution này cũng là Class Library. Sau đó vào phần Solution Exploer -> reference-> nháy chuột phải và chọn Add reference -> chọn đến file Interfaces.dll mà chúng ta vừa mới tạo.
sau đó trong solution này tạo hai Class là Minus và Multiply:
// Comment

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Interfaces;

namespace CalculatePluginLibrary
{
    class Minus:ICalculate
    {
        public int Operate(int a, int b)
        {
            return (a-b);
        }
    }
}

}


// Comment

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Interfaces;

namespace CalculatePluginLibrary
{
    public class Multiply:ICalculate
    {
        public int Operate(int a, int b)
        {
            return a * b;
        }
    }
}

Sau đó build chương trình và chúng ta sẽ nhận được một file thư viện (plugin) CalculatePluginLibrary.dll
5. Viết code trên chương trình chính

Ô kê, phần viết plugin đã xong, chúng ta sẽ viết phần chương trình chính, ngoài việc tính toán được phép cộng, chúng ta cũng có thể add CalculatePluginLibrary.dll để tính toán phép trừ và nhân. dưới là code chương trình:
note: nhớ using System.Reflection nhé

// Comment
public partial class Form1 : Form
    {
        private ArrayList plugins = new ArrayList();
        private int a;
        private int b;
        public Form1()
        {
            InitializeComponent();
        }

        private void addPluginToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog openDialog = new OpenFileDialog();
            openDialog.InitialDirectory = "c:\\";
            openDialog.Filter = "Calculate plugin files (*.dll)|*.dll";
            if (openDialog.ShowDialog()==DialogResult.OK)
            {
                string file = openDialog.FileName;
                AddPlugIn(file);
            }
        }
        private void AddPlugIn(string file)
        {
            try
            {
                Assembly ab = Assembly.LoadFrom(file);
                Type[] types = ab.GetTypes();
                foreach (Type t in types)
                {                    
                    if (t.GetInterface("ICalculate") != null)
                    {
                        plugins.Add(ab.CreateInstance(t.FullName));
                        lbxFunctions.Items.Add(t.FullName);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }             
        }
        private void btnOperate_Click(object sender, EventArgs e)
        {
            if (this.lbxFunctions.SelectedIndex == -1) return;

            //initial value
            a = int.Parse(txtFirstNumber.Text.Trim());
            b = int.Parse(txtSecondNumber.Text.Trim());
            //
            if (this.lbxFunctions.SelectedIndex==0)
            {
                MessageBox.Show((a+b).ToString());
            }
            else
            {
                object selObj = this.plugins[this.lbxFunctions.SelectedIndex-1];
                Type t = selObj.GetType();
                MethodInfo onOperate = t.GetMethod("Operate");

                object returnValue = onOperate.Invoke(selObj, new object[] { a, b });

                MessageBox.Show(returnValue.ToString());
            }           
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            lbxFunctions.Items.Add("Add");
        }       
    }

6. chạy thử nghiệm và kết quả

sau khi viết xong chương trình chính, chúng ta chạy thử chương trình. nếu bạn chưa Add Plugin thì chương trình của bạn chỉ thực hiện được phép cộng thôi.
Nhưng nếu bạn chọn PlugIn -> Add Plugin -> chọn đến thư viện CalculatePluginLibrary.dll thì trong Listbox sẽ xuất hiện thêm hai chức năng nữa, đó là CalculatePluginLibrary.Minus và CalculatePluginLibrary.Multiply
Lưu ý: trong bài này tôi viết Interface ICalculator là để chỉ cho phép các lớp có thừa kế từ ICalculator mới được phép đưa vào trong chương trình. Bạn cứ thử chọn PlugIn -> Add Plugin -> chọn đến thư viện .dll khác mà xem, trong lbxFunction sẽ không hiện gì khác ngoài Intem Add đâu.