Chào các bạn!

Đã lâu mình không viết bài trở lại, chắc cũng 3 tháng rồi :D nhưng traffic của blog vẫn đều đều ~400 bạn truy cập/ngày. Cảm ơn các bạn đã tin tưởng và ủng hộ blog, mình hứa sẽ cho ra thêm nhiều bài viết hay và bổ ích.

Gần đây mình có nhận được một yêu cầu của một bạn theo dõi blog, bạn ấy muốn làm một chương trình C# để thay đổi giờ hệ thống.
Hôm nay mình sẽ hướng dẫn các bạn viết ra chương trình đó. Nghe có vẻ rất dễ đúng ko?




Để thay đổi System Time bạn phải can thiệp vào hệ thống, trong C# bạn có thể dùng cách P/Invoke hàm SetSystemTime() theo WIN32 API có sẵn.
Đầu tiên bạn chuẩn bị cho mình một struct như sau:
private struct SYSTEMTIME
{
            public ushort Year;
            public ushort Month;
            public ushort DayOfWeek;
            public ushort Day;
            public ushort Hour;
            public ushort Minute;
            public ushort Second;
            public ushort Milliseconds;
}

Struct này tương tự theo cấu hình của class DateTime mà giờ hệ thống đang sử dụng :D
Sau đó các bạn thêm extern method này vào:
//Method set giờ hệ thống

[DllImport("kernel32.dll", SetLastError = true)]
private extern static uint SetSystemTime(ref SYSTEMTIME lpSystemTime);

//


Đây là method sử dụng thư viện động "lõi hệ thống 32" (kernel32.dll) của windows, và gây những tác động lên nó. Lưu ý để sử dụng DllImport thì bạn cần thêm namespace sau:
using System.Runtime.InteropServices; 

Namespace này dùng để chứa class DllImport - dùng chỉ ra rằng những phương thức này được tiếp cận bởi những DLL không được chương trình quản lý với dạng 1 điểm đầu vào tĩnh (static entry point)

Sau khi using namespace, thêm method, các bạn bắt đầu gọi method đó. Các bạn có thể tạo 1 button để xử lý sự kiện onClick cho button đó để gọi hàm :D
private void submit_btn_Click(object sender, EventArgs e)
{
       //Tạo instance
       SYSTEMTIME s = new SYSTEMTIME();

       //Gán các giá trị (ở đây mình gán ngẫu nhiên)
       s.Year = (ushort)2009;
       s.Month = (ushort)12;
       s.DayOfWeek = (ushort)3;
       s.Day = (ushort)4;
       s.Hour = (ushort)5;
       s.Minute = (ushort)6;
       s.Second = (ushort)7;
       s.Milliseconds = (ushort)8;

       //Gọi extern method đã thêm ở trên và xem kết quả :D
       SetSystemTime(ref s);
}

Các bạn có thể dùng 1 Control DateTimePicker để lấy số liệu nhập vào, phân tích ra và gán cho giờ hệ thống
//Lấy dữ liệu của control DateTimePicker xuống lưu vào biến
DateTime result = dateTimePicker1.Value;

SYSTEMTIME s = new SYSTEMTIME();

//Phân tích ra và lưu vào struct
s.Year = (ushort)result.Year;
s.Month = (ushort)result.Month;
s.DayOfWeek = (ushort)result.DayOfWeek;
//v.v...

Cuối cùng các bạn build chương trình ra, tìm đến thư mục */obj/Debug. Chạy file thực thi *.exe với quyền admin (Run as administrator). Lưu ý phải chạy với quyền admin thì mới thành công, vì các hàm của WIN32 API cần quyền admin để thay đổi/can thiệp vào dll hệ thống


LƯU Ý

Một số bạn khi thay đổi ngày thì chương trình chạy ok, nhưng khi thay đổi giờ thì chương trình chạy sai. Đó là do hàm SetSystemTime() của Win32 API nhận vào giá trị UTC, rồi tự convert lên Local Time (+7). Nên chương trình mình sẽ sai. Các bạn tham khảo giải pháp Work around của mình. Các bạn nào có ý hay hơn hay inbox cho page mình nhé :D 


_______________________________________________________________________

Đừng nên làm những chương trình thay đổi giờ hệ thống như thế này, bởi vì nó sẽ:

1) Làm phiền người sử dụng, nếu 1 chương trình mình dùng mà làm thay đổi giờ hệ thống máy tính thì cực kì khó chịu
2) Có thể làm break các ứng dụng khác, làm thay đổi thông tin trial của một số phần mềm.

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