2009-05-03 33 views
24

Tôi đang cố gắng xây dựng một số dịch vụ Windows để thực hiện những việc khác nhau. Ví dụ, tôi cần các dịch vụ Windows mà sẽ:Nhiều dịch vụ Windows trong một exe

  1. Gửi báo cáo hàng ngày qua email
  2. Định kỳ dọn dẹp một số thông tin được lưu trữ mỗi 30 phút
  3. , vv

Nhiệm vụ tôi cần các cửa sổ dịch vụ để làm là khác biệt vì vậy tôi không thực sự thích ý tưởng của việc có tất cả trong một dịch vụ.

Những gì tôi đã có cho đến nay là một dự án trong Visual Studio 2008. Tôi đã tạo ra một dịch vụ cửa sổ, tôi đã thiết lập một bộ đếm thời gian trên sự kiện OnStart (nó chỉ ghi vào một tập tin văn bản mỗi 5 giây cho Mục đích thử nghiệm). Sau đó tôi đã thêm một trình cài đặt vào dự án và khi tôi chạy InstallUtil.exe, mọi thứ đều hoạt động tốt.

Sự cố xảy ra khi tôi thêm dịch vụ cửa sổ thứ hai vào cùng một dự án. Tôi thiết lập mã OnStart một lần nữa, với cùng một thông tin đăng nhập (hơi khác một chút để tôi có thể biết dịch vụ nào đang ghi vào nhật ký). Với dịch vụ cửa sổ thứ hai, tôi đã thay đổi sự kiện chính trong Program.cs từ:

static void Main(string[] args) 
    { 
     ServiceBase[] ServicesToRun = new ServiceBase[] 
     { 
      new Service1() 
     }; 

     ServiceBase.Run(ServicesToRun); 
    } 

tới:

static void Main(string[] args) 
    { 
     ServiceBase[] ServicesToRun = new ServiceBase[] 
     { 
      new Service1(), 
      new Service2() 
     }; 

     ServiceBase.Run(ServicesToRun); 
    } 

Tại thời điểm này, không có lỗi thời gian biên dịch, nhưng dịch vụ Service2 không bao giờ làm bất cứ điều gì ... nhiệm vụ đăng nhập không bao giờ cháy.

Tôi đã thu hẹp nó xuống thực tế là dịch vụ thứ hai không có "Trình cài đặt" được liên kết với nó. Sau đó tôi đã cố gắng thêm Trình cài đặt theo cách tôi đã thực hiện với dịch vụ đầu tiên (nghĩa là, nhấp chuột phải vào trình thiết kế dịch vụ và nhấp vào "Thêm trình cài đặt"). Bây giờ, khi tôi đi đến tệp ProjectInstaller.cs, có một serviceInstaller khác ở đó (serviceInstaller2).

Bây giờ khi tôi xây dựng dự án và cố gắng cài đặt các dịch vụ, và tôi đi đến "Dịch vụ" cửa sổ bảng điều khiển, và tôi cố gắng để bắt đầu Service1, tôi nhận được thông báo lỗi sau:

của Windows không thể khởi động dịch vụ Service1 trên máy tính cục bộ.

Lỗi 1083: Chương trình thực thi dịch vụ này được định cấu hình để chạy không thực hiện dịch vụ.

Tôi nhận được thông báo lỗi tương tự nếu tôi cố gắng khởi động Service2 (ngoại trừ thông báo lỗi xác định Service2, tất nhiên).

Có điều gì tôi thiếu để nhận hai dịch vụ chạy từ một exe không?

+0

Có bất kỳ lý do cụ thể khác hơn là "tôi muốn" mà bạn cần phải có các dịch vụ trong một tệp thực thi duy nhất? Thông thường, mô đun sẽ thích hợp hơn, nhưng bạn có thể có tình tiết giảm nhẹ yêu cầu khác. – bsneeze

+0

Lý do thực sự duy nhất là dễ cài đặt và triển khai. Tất cả các "dịch vụ" là khá nhanh chóng một phần tắt chức năng, vì vậy tôi không muốn phải cài đặt x số cửa sổ dịch vụ cho các mảnh nhỏ của mã. –

+0

@pyrochild - Tôi tự tin có nhiều lý do để gắn kết nhiều dịch vụ trong một hội đồng duy nhất. Bây giờ tôi làm việc, chúng tôi sử dụng những con thú của thiết kế đó trên cơ sở mỗi khách hàng - nó làm cho phần mềm thử nghiệm tương tác với những dịch vụ đó một cách dễ dàng. – Hardryv

Trả lời

1

Tôi đang xây dựng một cái gì đó rất giống với những gì bạn đang nghĩ đến. Những gì tôi đã quyết định làm (cho đến nay) là có tất cả các dịch vụ của tôi (mặc dù chúng không phải là các dịch vụ, một 'controller') thực hiện một giao diện cụ thể (với các hoạt động init() và execute() như một liệt kê FREQUENCY).

Bộ điều khiển là dịch vụ cửa sổ và nó đọc danh sách chương trình/dll từ tệp cài đặt xml khi chạy và tải chúng vào Danh sách và gọi phương thức execute() của chúng (nếu có) trên bất kỳ tần suất nào chúng đã xác định.

Trong trường hợp của tôi, mỗi chương trình cũng chứa một usercontrol được tải vào một trang tab của bộ điều khiển cho phép người dùng kiểm soát/sửa đổi nó. Tôi sẽ đăng mã nếu bạn quan tâm.

Không chắc liệu điều đó có rõ ràng hay không. Tôi thực sự có ý tưởng từ một người dùng SO khác đã triển khai một cái gì đó tương tự nhưng tôi không thể tìm thấy bài đăng đó ngay bây giờ.

2

Tôi đã gặp sự cố tương tự ngày hôm nay và đã cố gắng giải quyết vấn đề đó.

Thứ nhất, tôi đảm bảo rằng mỗi dịch vụ đều có thuộc tính ServiceName có ý nghĩa và duy nhất. Máy phát điện đã cung cấp cả hai dịch vụ cùng tên mà sẽ không có ích.

Sau đó tôi đã xóa và tạo lại lớp ProjectInstaller và thêm trình cài đặt cho mỗi lớp. Tôi chắc chắn rằng họ đã được cả hai instantiated trong phương pháp tĩnh tĩnh.

Bây giờ tôi có thể cài đặt hai dịch vụ với một dll, nhưng rất tiếc khi tôi bắt đầu một trong các dịch vụ, có vẻ như thực hiện các chức năng của cả bản thân và dịch vụ khác. Nghĩa là cả hai dịch vụ đều đang chạy (mặc dù chỉ một trong các dịch vụ xuất hiện là 'Đã bắt đầu' trong Trình quản lý Máy tính). Tôi vẫn đang cố gắng tìm ra điều đó ...

0

Tôi đã có cùng một vấn đề ngay hôm nay và đã cố gắng khắc phục. Trong trường hợp của tôi, tôi chỉ phải mở các tệp * .designer.cs của các dịch vụ của mình và đảm bảo rằng tên dịch vụ được đặt chính xác. Quan trọng hơn cùng tên nên được sử dụng trong * Installer.Designer.cs và nếu bạn có mã trong * Installer.cs.

Tôi nghĩ lỗi này chỉ xảy ra do không khớp tên.

Hy vọng điều này helpds

4

Tôi đoán rằng các bạn đã giải quyết điều này, nhưng trong trường hợp đó một số khác cần nó, tôi sẽ đăng một câu trả lời cho vấn đề này mà đưa tôi vài giờ ngày hôm nay. Các giải pháp không phải là thêm trình cài đặt dự án khác, mà là trình cài đặt dịch vụ, là thành phần trong trình cài đặt dự án. Trình cài đặt dịch vụ mới được bổ sung này phải được cấu hình tên dịch vụ thứ hai.

+0

Tôi đã phải sử dụng chi tiết ở đây để cho tôi biết cách thực hiện việc này: https : //msdn.microsoft.com/en-us/library/zt39148a (v = vs.110) .aspx Đối với người lười: "Mở menu ngữ cảnh cho cửa sổ thiết kế (nếu bạn đang sử dụng thiết bị trỏ, phải nhấp vào bên trong cửa sổ), sau đó chọn Thêm trình cài đặt. " – wilsjd

+0

Tôi không thể hiểu ý của bạn bằng điểm 6 và 7. –

14

Tôi đã tìm ra cách có một tệp thực thi nhưng hai dịch vụ. Mỗi dịch vụ sẽ cài đặt cho người quản lý dịch vụ với tên riêng và khả năng bắt đầu/dừng của nó. Tôi nghĩ rằng đây là những gì bạn đang muốn, chính xác? Dưới đây là những gì tôi đã làm:

  1. Tạo dự án dịch vụ.
  2. Đã thêm dịch vụ thứ hai vào cùng một dự án (với tên dịch vụ duy nhất).
  3. Đã thêm trình cài đặt cho cả hai dịch vụ (ServiceA và ServiceB).
  4. Trong tệp ProjectInstaller.Designer.vb tôi đã thay đổi dòng Me.Installers.AddRange để hiển thị cả hai trình cài đặt dịch vụ. (Me.ServiceInstaller1, Me.ServiceInstaller2)
  5. Trong điểm vào chính của dịch vụ chính (ServiceA trong trường hợp của tôi), tôi đặt biến ServicesToRun thành một mảng ServiceBase chứa tất cả các dịch vụ mà tôi muốn nó chạy (ServiceA và ServiceB). Đây là một bước quan trọng vì trình quản lý dịch vụ đặt thuộc tính dựa trên số lượng đối số ở đây - hoặc cho phép nhiều phiên bản của cùng một exe hoặc chỉ một cá thể duy nhất.
  6. Thêm dự án trình cài đặt và sử dụng đầu ra của Dịch vụ.
  7. Thêm hành động tùy chỉnh bằng cách sử dụng đầu ra từ Dịch vụ.

Bạn có thể tìm thấy mã bản demo ở đây:
http://code.google.com/p/multi-service-install/

Thưởng thức!

0

Cài đặt 2 dịch vụ riêng biệt và không có liên quan trong một tệp thực thi có mùi buồn cười đối với tôi. Trong khi nó có thể làm cho nó hoạt động, nó không làm cho nó đúng.

Từ những gì nó có vẻ như, bạn cần phải thực hiện một số nhiệm vụ khác nhau tại các khoảng khác nhau và nhiệm vụ của bạn có thể hoặc có thể không liên quan. Bạn đã xem xét Quartz.NET chưa? Nghe có vẻ thích hợp cho nhu cầu của bạn.

http://quartznet.sourceforge.net/features.html

1

Tôi đã sử dụng sc.exe để thực hiện việc này dễ dàng. http://support.microsoft.com/kb/251192

Đối với ví dụ: sc create "My Display Service Name" binpath= "c:\app\mysvc.exe --service"

Lưu ý: mỗi bình đẳng nên có gian trước khi giá trị của nó như bạn có thể nhìn thấy cho 'binpath'

Các vấn đề liên quan