Tuesday, January 26, 2016

Đọc và ghi vào registry – Read and write to registry

Registry được xem là một “chìa khóa tối thượng” để xâm nhập vào Windows và hầu như chỉ dùng cho giới chuyên môn cao. Với những người dùng bình thường thì Registry của Windows gần như là một “đám rừng” gần như không có lối ra. Do đó, bài viết này sẽ giúp cho các bạn có những kiến thức cơ bản  cũng như các đọc và ghi vào registry khi lập trình với ngôn ngữ C#.
1. Một vài kiến thức cơ bản về Registry
–  Registry là một cơ sở dữ liệu dùng để lưu trữ mọi thông số kỹ thuật của Windows. Nó ghi nhận tất cả các thông tin khi bạn thay đổi hoặc chỉnh sửa trong Menu Settings, Control Panel v.v
–  Trong Window 95 và Windows 98 thì Registry được lưu lại trong 2 file là: user.datsystem.dat trong thư mục Windows. Trong Windows Me, Registry được lưu trong file Classes.dat trong thư mục Windows. Trong Windows 2000 và Windows XP, thì Registry được lưu trong thư mục “Windows\System32\Config”.
–  Bạn có thể chỉnh sửa Registry của các Windows bằng trình Registry Editor có sẵn trong Windows bằng cách vào cửa sổ Run và gõ lệnh “Regedit”.
–  Registry có cấu trúc hình cây, tương tự như cấu trúc của cây thư mục với rất nhiều nhánh con tỏa ra tùy theo cấu trúc ứng dụng. Thông thường Registry của Windows có 5 nhánh chính, mỗi nhánh đảm nhận viện lưu trữ những thông tin riêng biệt. Mỗi nhánh chính tỏa ra rất nhiều nhánh con và những nhánh con này cũng lưu trữ vô số thông tin đặc thù về mọi thứ có trong Windows.image
  • HKEY_CLASSES_ROOT: Lưu những thông tin dùng chung cho toàn bộ hệ thống.
  • HKEY_CURRENT_USER: Lưu những thông tin cho người dùng đang sử dụng hoặc đăng nhập vào Windows.
  • HKEY_LOCAL_MACHINE: Lưu những thông tin về hệ thống, phần cứng, phần mềm…
  • HKEY_USERS: Lưu những thông tin của tất cả các User (người dùng), mỗi user là một nhánh với tên là số ID định dạng của user đó.
  • HKEY_CURRENT_CONFIG: Lưu thông tin về phần cứng hiện tại đang dùng.
–  Những người dùng thành thạo Windows muốn hiểu sâu hơn về hệ thống đều cần tìm hiểu kỹ về Registry càng nhiều càng tốt vì những lý do sau:
  • Registry lưu tất cả các thông tin về phần cứng, phần mềm, những lựa chọn của người dùng….kiểm soát được nội dung của Registry là yêu cầu tất yếu để bạn sử dụng máy tính một cách khoa học, hiểu sâu hơn về môi trường làm vịệc của Windows.
  • Muốn tiến xa hơn trong kỹ thuật lập trình trên nền Windows, cách bảo mật, thậm chí bẻ khóa phần mềm hay đột nhập vào máy tính của người khác… thì bạn đều cần phải có hiểu biết nhất định về Registry.
  • Hầu hết các thủ thuật trong Windows mà các tạp chí tin học tên tuổi đã đăng tải đều liên quan mật thiết đến Registry. Các công cụ có thể tác động vào Windows do giới phần mềm tạo nên đa số cũng đều dựa trên cơ sở “xâm nhập” Registry bằng các công cụ được thiết kế thân thiện và trực quan hơn.
2. Lưu ý khi sử dụng Registry Editor
warning
     –  Tất cả mọi thứ tồn tại trong hệ thống Windows đều để lại những “mật mã” hoặc chìa khóa cực kỳ trọng yếu trong Registry. Việc tác động vào những mã khóa này có thể chỉ ảnh hưởng đến một phần nhỏ nào đó của Windows, nhưng đôi khi có tác động đến toàn bộ hệ thống. Khi “trót dại” chỉnh sửa sai một vài “key” tối quan trọng nào đó là có thể làm cho Winsows bị tê liệt hoặc hư hỏng hoàn toàn.
–  Khi bạn đã “dám” xâm nhập vào Registry Editor điều bắt buộc trước tiên là bạn phải sao lưu lại Registry của mình bằng cách chạy Registry Editor -> File -> Export và lưu file có đuôi .REG này vào chỗ an toàn để nếu có chỉnh sửa sai thì vẫn phục hồi lại được nguyên trạng hệ thống. Khi muốn phục hồi lại Registry nguyên thủy thì vào lại Registry Editor -> File -> Import -> Tìm đến file .REG đã lưu để tiến hành phục hồi.
–  Dòng chữ đứng sau các từ: User Key, Sytem Key, hoặc Key cho biết đường dẫn đến nhánh cần sửa chữa hoặc tạo mới nếu nó không tồn tại. Lưu ý rằng User Key là để thay đổi đó có tác dụng với người đang đăng nhập (Logon);  System Key là để thay đổi đó có tác dụng với tất cả người dùng.
  • Dòng Name là tên của khoá cần tạo, nó là nhánh con bên cửa sổ bên phải của Registry.
  • Dòng Type là kiểu dữ liệu của khoá mới tạo.
  • Dòng Value là giá trị của khoá.
–  Sau khi đã sao lưu Registry gốc và biết cách phục hồi, hầu như bạn đã có thể thoải mái “tung hoành” trong Registry. Để trở thành một “chuyên gia Registry” thực sự không phải là quá khó khăn, bạn chỉ cần có một vốn tiếng Anh đủ để đọc và hiểu đúng tất cả những gì mà Microsoft đã trình bày bằng tiếng Anh trong Windows.
–  Khi đã hiểu hết mọi từ ngữ trong Registry, bạn có thể vào “vọc” bằng cách chỉnh sửa lại các thông số mặc định bằng các thông số của mình, sau đó lưu lại Registry, thoát khỏi tài khoản User đang dùng, đăng nhập lại vào tài khoản đã bị chỉnh Registry, truy vào khoản mục đã chỉnh sửa để xem tác dụng của nó. Nếu nó quá nhanh, quá chậm hoặc… “liệt” hoàn toàn thì bạn nên vào lại Registry để điều chỉnh nó về lại thông số cũ. Nếu không nhớ nổi những thông số đã bị chỉnh sửa thì hãy tiến hành thì phục hồi lại Registry nguyên gốc
3. Lớp Registry trong .NET
regitry editor
–  Việc truy cập vào Registry trên .NET sẽ thông qua hai lớp Registry và RegistryKey thuộc namespace Microsoft.Win32.
using Microsoft.Win32;
–  Một thể hiện của lớp RegistryKey tượng trưng cho một registry key. Lớp RegistryKey cung cấp những hàm thành viên cốt lõi cho phép bạn làm việc với registry key.
– Lớp RegistryKey sẽ là lớp mà bạn sẽ dùng để làm việc với registry key. Ngược lại lớp Registry là lớp mà bạn chả bao giờ đụng đến. Vai trò của nó là cung cấp cho bạn những thể hiện RegistryKey tượng trưng cho key top-level những hive khác nhau để qua các thuộc tính static và có cả thảy 7 thuộc tính bao gồm ClassesRoot, CurrentConfig, CurrentUser, DynData, LocalMachine, PerformanceData, and Users. Chắc chắn bạn đã biết thuộc tính nào chỉ Registry hive nào Do đó muốn có một thể hiện của một RegistryKey tượng trưng cho key HKLM, bạn có thể viết:
RegistryKey hklm = Registry.LocalMachine;

– Nếu bạn muốn đọc một vài dữ liệu trên key HKLM\Software\Microsoft, bạn phải đi lấy qui chiếu về key như sau :
RegistryKey hklm = Registry.LocalMachine;
RegistryKey hkSoftware = hklm.OpenSubKey("Software");
RegistryKey hkMicrosoft = hkSoftware.OpenSubKey("Microsoft");
–  Một registry key được truy cập theo kiểu này chi cho phép bạn đọc mà thôi, Nếu bạn muốn có khả năng viết lên key (bao gồm viết lên trị của key, tạo hoặc gỡ bỏ cây con cái thuộc quyền), bạn phải sử dụng một OpenSubkey nhận thêm một thông số thứ hai thuộc kiểu bool cho biết quyền read-write đối với key. Ví dụ bạn muốn có khả năng thay đổi key Microsoft:
RegistryKey hklm = Registry.LocalMachine;
RegistryKey hkSoftware = hklm.OpenSubKey("Software");
RegistryKey hkMicrosoft = hkSoftware.OpenSubKey("Microsoft", true);
–  Phương thức  OpenSubKey() là một trong những hàm mà bạn triệu gọi nếu bạn chờ đợi key hiện hữu. Nếu nó không có thì nó sẽ trở về null preference. Còn nếu bạn muốn tạo một key mới bạn sẽ dùng CreateSubKey() (hàm này tự hoạt động cho quyền read write):
RegistryKey hklm = Registry.LocalMachine;
RegistryKey hkSoftware = hklm.OpenSubKey("Software");
RegistryKey hkMySoft = hkSoftware.CurrentUser.CreateSubKey("Thanh Cuong");
–  Một khi bạn đã có registry key bạn muốn đọc hoặc thay đổi, bạn có thể sử dụng các phương thức SetValue() hoặc GetValue() để đặt hoặc để lấy dữ liệu trên key như:
Microsoft.Win32.RegistryKey key;
key = Microsoft.Win32.Registry.CurrentUser.CreateSubKey("Thanh Cuong");
key.SetValue("Cuong", "University Of Information Technology!");
key.Close();
image
–  RegistryKey.GetValue() được định nghĩa trả về một quy chiếu đối tượng, nghĩa là trả về một quy chiếu string nếu nó thấy có kiểu dữ liệu REG_SZ, và int nếu phát hiện kiểu dữ liệu REG_DWORD:
string stringValue = (string)key.GetValue("MyStringValue"); int intValue = (int)key.GetValue("MyIntValue"); 

–  Lưu ý là sau khi xong việc bạn phải đóng registrykey của mình lại
key.Close();

– Các thành phần của RegistryKey bao gồm thuộc tính và phương thức sau:
image

Tải source về tại đây 

Nguồn: https://thanhcuong.wordpress.com/

Labels: , , , ,

Đọc và ghi tập tin bằng C# – read and write file with C# .net

Việc đọc và ghi ra một tập tin là việc làm cần thiết trong trường hợp chúng ta muôn in ra kết quả chương trình ra một file, lấy nối dung từ một file để sử dụng trong chương trình của mình… Trong môi trường .net với ngôn ngữ C# nói riêng và các ngôn ngữ khác nói chung, việc thực hiện tương đối dễ dàng với sự hỗ trợ đắc lực của lớp trình bày nội dung gọi chung là stream. Bài viết này sẽ có trình bày ngắn gọn việc đọc và ghi file trong C# dựa trên các lớp sẵn có của .NET, với mỗi trường hợp sẽ có chương trình Demo cụ thể viết trên Visual studio 2010.

1. Giới thiệu về Stream
–  Đọc và viết dữ liệu sẽ được thực hiện thông qua lớp stream. Stream là dòng dữ liệu chảy đi. Đây là một thực thể (entity) có khả năng nhận được hoặc tạo ra một “nhúm” dữ liệu. System.IO.Stream là một lớp  abstract định nghĩa một số thành viên chịu hỗ trợ việc đọc/viết đồng bộ (synchronus) hoặc không đồng bộ (asynchronous) đối với khối trữ tin (nghĩa là một tập tin trên đĩa hoặc tập tin trên ký ức).
–  Vì Stream là một lớp abstract, nên bạn chỉ có thể làm việc với những lớp được dẫn  xuất từ Stream. Các hậu duệ của Stream tượng trưng dữ liệu như là một dòng dữ liệu thô dạng bytes (thay vì dữ liệu dạng văn bản). Ngoài ra, các lớp được dẫn xuất từ Stream hỗ trợ việc truy tìm (seek) nghĩa là một tiến trình nhận lấy và điều chỉnh vị trí trên một dòng chảy. Trước khi tìm hiểu những chức năng mà lớp Stream cung cấp, bạn nên xem qua các thành viên của lớp Stream.
–  Ý tưởng của stream đã có từ lâu. Một stream là một đối tượng dùng để chuyển dữ liệu. Dữ liệu có thể được truyền theo hai hướng:
  • Nếu dữ liệu được truyền từ nguồn bên ngoài vào trong chương trình của bạn, ta gọi là đọc dữ liệu
  • Nếu dữ liệu được truyền từ chương trình của bạn ra nguồn bên ngoài , ta gọi là viết dữ liệu
–  Thường thì nguồn bên ngoài sẽ là một file, ngoài ra nó còn bao gồm cả trường hợp sau:
  • Đọc hoặc ghi dữ liệu trên mạng dùng giao thức mạng
  • Đọc hoặc ghi đến một đường ống chỉ định
  • Đọc hoặc ghi đến một vùng của bộ nhớ
–  Các lớp có mối liên hệ trong namespace System.IO như hình sau:
image
2.  Làm việc với file nhị phân (binary files)
Reading and writing to binary files thường được làm việc với lớp FileStream .
a. Làm việc với FileStream
–  Lớp FileStream đem lại việc thi công cho những thành viên của lớp abstract Stream theo một thể thức thích hợp đối với các file-base streaming giống như các lớp DirectoryInfo và FileInfo, lớp FileStream cho phép mở những tập tin hiện hữu cũng như tạo mới file. Khi tạo tập tin , lớp FileStream  thường dùng những enum FileMode, FileAccess và FileShare.
// tạo một tập tin mới trên thư mục làm việc FileStream myFStream = new FileStream("test.dat", FileMode.OpenOrCreate, FileAccess.ReadWrite);
b. The FileStream Class:
FileStream được sử dụng đọc và viết dữ liệu vào hoặc từ một file. Để khởi tạo một FileStream, bạn cần 4 phần sau:
  • file bạn muốn truy xuất .
  • mode, cho biết bạn muốn mở file như thế nào.
  • access, cho biết bạn muốn truy xuất file như thế nào – bạn định đọc hoặc viết file hoặc cả hai.
  • share access – khả năng truy xuất file.
Enumeration Values
FileMode Append, Create, CreateNew, Open, OpenOrCreate, or Truncate
FileAcess Read, ReadWrite, or Write.
FileShare Inheritable, None, Read, ReadWrite, or Write.
3. Làm việc với BufferedStream
–  Khi bạn gọi hàm Read() thì một công tác đọc dữ liệu cho đầy buffer từ đĩa được tiến hành. Tuy nhiên, để cho có hiệu năng, hệ điều hành thường phải đọc trong một lúc một khối lượng lớn dữ liệu tạm thời trữ trên bufer. Buffer hoạt động như một kho hàng.
–  Một đối tượng Bufered stream cho phép hệ điều hành tạo buffer riêng cho mình dùng, rồi đọc dữ liệu vào hoặc viết dữ liệu lên ổ đĩa theo một khối lượng dữ liệu nào đó mà hệ điều hành thấy là có hiệu năng. Tuy nhiên, bạn xũng có thể ấn định chiều dài khối dữ liệu. Nhưng bạn nhớ cho là buffer sẽ chiêmd chỗ trong ký ức chứ không phải trên đĩa từ. Hiệu quả sử dụng đến buffer là ciệc xuất nhập dữ liệu chạy nhanh hơn.
–  Một đối tượng BufferedStream được hình thành xung quanh một đối tượng Stream mà bạn đã tạo ra trước đó. Muốn sử dụng đến một BufferedStream bạn bắt đầu tạo một đối tượng Stream thông thường như trong ví dụ:
stream inputstream = File.OpenRead(@"C;\test\source\folder3.cs ");

stream outputstream = File.Openwrite(@"C:test\source\folder3.bak");
–  Một khi bạn đã có stream bình thường, bạn trao đối tượng này cho hàm constructor của buffere stream:
BufferedStream bufInput = new BufferedStream(inputstream);

BufferedStream bufOutput = new BufferedStream(outputstream);
–  Sau đó, bạn sử dụng BufferedStream như là một stream bình thường, bạn triệu gọi hàm Read() hoặc Write() như bạn đã làm trước kia. Hệ điều hành lo việc quản lý vùng đêm:
while ((bytesRead = bufInput.Read(buffer, 0, SIZE_BUFF)) > 0)
{
    bufOutput.Write(buffer, 0, bytesRead);

}
–  Chỉ có một khác biệt mà bạn phải nhớ cho là phải tuôn ghi (flush) nội dung của buffer khi bạn muốn bảo đảm là dữ liệu được ghi lên đĩa.
bufOutput.Flush();
–  Lệnh trên bảo hệ điều hành lấy toàn bộ dữ liệu trên buffer cho tuôn ra ghi lên tập tin trên đĩa.
4.  Làm việc với những tập tin văn bản
–  Nếu bạn biết file bạn đang làm việc (đọc/viết) thuộc loại văn bản nghĩa là dữ liệu kiểu string, thì bạn nên nghĩ đến việc sử dụng đến các lớp StreamReader và StreamWriter. Cả hai lớp theo mặc nhiên làm việc với ký tự Unicode. Tuy nhiên bạn có thể thay đổi điều này bằng cách cung cấp một đối tượng quy chiếu được cấu hình một cách thích hợp theo System.Text.Reference. Nói tóm lại hai lớp này được thiết kế để thao tác dễ dàng các tập tin loại văn bản.
–  Lớp StreamReader được dẫn xuất từ một lớp abstract mang tên TextReader cũng giống như String Reader. Lớp cơ bản TextReader cung cấp một số chức năng hạn chế cho mỗi hậu duệ, đặc biệt khả năng đọc và “liếc nhìn” (peek) lên một dòng ký tự (character stream).
–  Lớp StreamWriter và StringWriter cũng được dẫn xuất từ một lớp abstract mang tên TextWriter; lớp này định nghĩa những thành viên cho phép các lớp dẫn xuât viết những dữ liệu văn bản lên một dòng văn bản nào đó.
–  Các hàm thành viên của lớp TextWriter
Close() Cho đóng lại các writer và giải phóng mọi nguồn lực chiếm dụng
Flush() Cho xoá sạch tất cả các buffer đối với writer hiện hành
NewLine Thuộc tính này dùng làm hằng sang hằng
Write() Viết một hằng lên text stream không có newline constant
WriteLine() Viết một hằng lên text stream có newline constant
Ví dụ đọc, viết một tập tin văn bản:
–  Ví dụ ReadWriteText trình bày cách sử dụng của lớp StreamReader và StreamWriter. Nó trình bày file được đọc vào và hiển thị Nó cũng có thể lưu file. Nó sẽ lưu bất kỳ file ở định dạng Unicode .
–  Màn hình trình bày ReadWriteText được dùng hiển thị ở chương trình demo. Chúng ta có thể đọc được ở nhiều định dạng file khác.
–  Chúng ta nhìn vào đoạn mã sau. Trước tiên ta thêm câu lệnh using , Từ đây bên cạnh System.IO, chúng ta sử dụng  lớp StringBuilder từ System.Text namespace để xây dựng chuỗi trong textbox:
using System.Text;
using System.IO;
–  Tiếp theo chúng ta thêm các trường cho lớp main form:
public partial class Form1 : Form {
     private OpenFileDialog FileOpen = new OpenFileDialog();
     private string chooseFile;
–  Chúng ta cũng cần thêm vài chuẩn mã Windows Forms để thực hiện điều khiển cho menu và hộp thoại:
public Form1()
{
    InitializeComponent();
    this.MaximizeBox = false;
    this.StartPosition = FormStartPosition.CenterScreen;
    FileOpen.FileOk += new CancelEventHandler(FileOpen_FileOk);
}

private void openToolStripMenuItem_Click(object sender, EventArgs e)
{
    FileOpen.ShowDialog();
}
void FileOpen_FileOk(object sender, CancelEventArgs e)
{
    chooseFile = FileOpen.FileName;
    this.Text = Path.GetFileName(chooseFile);
    DisplayFile();
}
–  Từ đây chúng ta thấy mỗi khi người sử dụng nhấn OK để chọn một file trong hộp thoại, chúng ta gọi phương thức DisplayFile(), dùng để đọc file.
private void DisplayFile()
{
    int nCols = 16;
    FileStream inStream = new FileStream(chooseFile, FileMode.Open,
                                                     FileAccess.Read);
    long nBytesToRead = inStream.Length;
    if (nBytesToRead > 65536 / 4)
        nBytesToRead = 65536 / 4;
    int nLines = (int)(nBytesToRead / nCols) + 1;
    string[] lines = new string[nLines];
    int nBytesRead = 0;
    for (int i = 0; i < nLines; i++)
    {
        StringBuilder nextLine = new StringBuilder();
        nextLine.Capacity = 4 * nCols;
        for (int j = 0; j < nCols; j++)
        {
            int nextByte = inStream.ReadByte();
            nBytesRead++;
            if (nextByte < 0 || nBytesRead > 65536)
                break;
            char nextChar = (char)nextByte;
            if (nextChar < 16)
                nextLine.Append(" x0" + string.Format("{0,1:X}",
                                                     (int)nextChar));
            else if (char.IsLetterOrDigit(nextChar) ||
                                     char.IsPunctuation(nextChar))
                nextLine.Append(" " + nextChar + " ");
            else nextLine.Append(" x" + string.Format("{0,2:X}",
                                       (int)nextChar));
        }
        lines[i] = nextLine.ToString();
    }

    inStream.Close();
    richTextBox.Lines = lines;

}
–  Như vậy chúng ta đã mở được file  nhờ phương thức DisplayFile(). bây giờ chúng ta xử lý cách để lưu file chúng ta thêm đoạn mã SaveFile(). Bạn nhìn vào phương thức SaveFile() chúng ta viết mỗi dòng ra textbox, bằng  stream StreamWriter
void SaveFile()
{
    StreamWriter sw = new StreamWriter(chooseFile, false,
                          Encoding.Unicode);
    foreach (string line in richTextBox.Lines)
        sw.WriteLine(line);
    sw.Close();
}
–  Bây giờ ta xem xét làm thế nào file được đọc vào. Trong quá trình xử lý thực sự chúng ta không biết có bao nhiêu dòng sẽ được chứa. Chúng ta giải quyết vấn đề này bằng cách ban đầu đọc file vào trong lớp đại diện StringCollection, được nằm trong System.Collections.Specialized namespace. Lớp này được thiết kế để giữ một bộ của chuỗi có thể được mở rộng một cách linh hoạt. Nó thực thi hai phương thức : Add(), nó thêm một chuỗi vào bộ chọn lựa (collection) , và CopyTo(), nó sao chép string collection vào trong một mảng. Mỗi thành phần của đối tượng StringCollection object sẽ giữ 1 hàng của file.
–  Bây giờ chúng ta sẽ xem xét phương thức ReadFileIntoStringCollection() . Chúng ta sử dụng StreamReader để đọc trong mỗi hàng. Khó khăn chính là cần đếm ký tự đọc để chắc chúng ta không vượt quá khả năng chứa đựng của textbox:
private StringCollection ReadFileIntoStringCollection()
{
    const int MaxBytes = 65536;
    StreamReader sr = new StreamReader(chooseFile);
    StringCollection result = new StringCollection();
    int nBytesRead = 0;
    string nextLine;
    while ((nextLine = sr.ReadLine()) != null)
    {
        nBytesRead += nextLine.Length;
        if (nBytesRead > MaxBytes)
            break;
        result.Add(nextLine);
    }
    sr.Close();
    return result;
}
  Đến đây đoạn mã được hoàn thành.

Tải Source về tại đây

Nguồn: thanhcuong.wordpress.com

Labels: , , , ,