Tạo dịch vụ Windows trong VB.NET

Tạo dịch vụ Windows có sử dụng biểu tượng trong khay hệ thống_trong VB.NET

Vấn đề: Bạn muốn tạo một dịch vụ Windows có sử dụng kiểu giao diện người dùng nào đó, chẳng hạn một biểu tượng trong khay hệ thống (system tray icon).

Hướng giải quyết: Nếu có thể, đừng hiện thực bất kỳ giao diện người dùng nào cho một dịch vụ Windows. Phương sách cuối cùng là kích hoạt sự tương tác với desktop bằng tiện ích Computer Management.

Nguyên tắc của Microsoft là tránh sử dụng giao diện người dùng với bất kỳ ứng dụng dịch vụ Windows nào. Việc thêm một giao diện người dùng có thể dẫn đến các nguy cơ bảo mật và có thể ngăn dịch vụ chạy nếu các quyền cần thiết không được cấp. Thực ra, các dịch vụ Windows nên có khả năng chạy sao cho tuyệt đối không có sự can thiệp của người dùng—ngay cả không có người dùng nào đăng nhập vào máy tính.


Trong các trường hợp cần một giao diện người dùng để cấu hình sự hoạt động của dịch vụ Windows (hoặc để xem một số dữ liệu mà nó đã xử lý), bạn nên tạo một ứng dụng riêng biệt. Ví dụ, dịch vụ Windows của bạn được cấu hình là ghi dữ liệu vào một cơ sở dữ liệu hay một nhật ký sự kiện, và bạn có thể tạo một chương trình riêng biệt để đọc thông tin này và hiển thị cho người dùng. Một mẫu thiết kế cao cấp hơn là sử dụng .NET Remoting để cho phép một công cụ giao diện người dùng “nói chuyện” với một dịch vụ Windows. Theo cách này, bạn có thể sử dụng một chương trình để cấu hình một dịch vụ Windows ở thời gian thực (mẫu thiết kế này tương tự với cách SQL Server làm việc với tiện ích khay hệ thống của nó).


Giả sử bạn đã quyết định cung cấp một giao diện cơ bản nào đó cho một dịch vụ Windows. Chẳng hạn, bạn muốn thêm một biểu tượng trong khay hệ thống để báo trạng thái của thao tác hiện hành. Bạn có thể dễ dàng thêm một NotifyIcon vào dự án và cấu hình nó trong mã lệnh dịch vụ. Ví dụ dưới đây sửa đổi phần text của biểu tượng để hiển thị trạng thái hiện tại. Để sử dụng ví dụ này, bạn phải nhập không gian tên System.ServiceProcessSystem.Threading.


Code:

Public Class IconService
  Inherits System.ServiceProcess.ServiceBase
  
  Shared Sub Main()
    Dim ServicesToRun() As ServiceBase
    ServicesToRun = New ServiceBase(){New IconService()}
    System.ServiceProcess.ServiceBase.Run(ServicesToRun)
  End Sub
  
  Private Components As System.ComponentModel.IContainer
  Friend ServiceIcon As System.Windows.Forms.NotifyIcon
  
  Private Sub InitializeComponent()
  Me.Components = New System.ComponentModel.Container()
  Dim resources As New System.Resources.ResourceManager
( _GetType(IconService))
    ' Cấu hình biểu tượng trong khay hệ thống.
    ' Hình bitmap được thu lấy từ một file nguồn.
    ' Mã lệnh này được sinh tự động bởi Visual Studio .NET.
    Me.ServiceIcon = New _ 
       System.Windows.Forms.NotifyIcon(Me.Components)
    Me.ServiceIcon.Icon = CType( _
       resources.GetObject("ServiceIcon.Icon"),
System.Drawing.Icon)
    Me.ServiceIcon.Text = ""
    Me.ServiceIcon.Visible = True
    Me.ServiceName = "IconService"
    ' (Bỏ qua phần mã lệnh được sinh tự động còn lại.)
    End Sub
   
  Private ServiceThread As Thread
  Private StopThread As Boolean = False
   
  Protected Overrides Sub OnStart(ByVal args() As String)
     ServiceIcon.Text = "Starting ..."
     ServiceThread = New Thread(AddressOf DoWork)
     ServiceThread.Start()
  End Sub
   
  Protected Overrides Sub OnStop()
     ServiceIcon.Text = "Stopping ..."
   
     ' Báo hiệu cho tiểu trình kết thúc (và đợi đến 20 giây).
     StopThread = True
     ServiceThread.Join(TimeSpan.FromSeconds(20))
   
     ' Nếu tiểu trình vẫn còn chạy thì hủy bỏ nó.
     If (ServiceThread.ThreadState And _
        ThreadState.Running) = ThreadState.Running Then
        ServiceThread.Abort()
     End If
  End Sub
   
  Private Sub DoWork()
     Do Until StopThread
        ServiceIcon.Text = "Processing"
        Thread.Sleep(TimeSpan.FromSeconds(10))
     Loop
     ServiceIcon.Text = "Not Processing"
  End Sub
   
End Class


Bạn có thể mở rộng kiểu thiết kế này bằng cách thêm một menu ngữ cảnh với các hàm thụ lý sự kiện cho các phần tử của menu.
Tuy vậy, kiểu thiết kế này không được khuyến khích vì nó sẽ giới hạn những tình huống mà bạn có thể sử dụng dịch vụ này.

Nếu bạn cài đặt dịch vụ Windows này, mặc định là nó không làm việc. Khi bạn khởi chạy dịch vụ,
một biệt lệ có thể bị ném hoặc là dịch vụ chạy nhưng không hiển thị biểu tượng trong khay hệ thống.
Giải pháp là kích hoạt thủ công đặc quyền tương tác với desktop bằng tiện ích Computer Management.
Bạn hãy tìm dịch vụ này trong danh sách, nhắp phải vào nó, và chọn Properties. Kế tiếp, trong thẻ Log On,
chọn Allow service to interact with desktop, rồi nhắp OK.