2008-10-01 4 views
6

Tôi có một ứng dụng C# chạy dưới dạng dịch vụ cửa sổ kiểm soát các kết nối ổ cắm và những thứ khác. Ngoài ra, còn có một ứng dụng biểu mẫu cửa sổ khác để điều khiển và định cấu hình dịch vụ này (systray với bắt đầu, dừng, hiển thị biểu mẫu với các tham số cấu hình).Các dịch vụ Windows có dạng cửa sổ trong cùng một quy trình

Tôi đang sử dụng .net từ xa để thực hiện IPC và điều đó là tốt, nhưng bây giờ tôi muốn hiển thị một số lưu lượng truy cập thực và các báo cáo khác và điều khiển từ xa sẽ không đáp ứng các yêu cầu về hiệu suất của tôi. Vì vậy, tôi muốn kết hợp cả hai ứng dụng trong một.

Đây là vấn đề:

Khi tôi bắt đầu biểu mẫu từ dịch vụ cửa sổ, không có gì xảy ra. Googling xung quanh tôi đã tìm thấy rằng tôi phải bấm vào dịch vụ, hãy vào Đăng nhập và kiểm tra tùy chọn "Cho phép dịch vụ tương tác với máy tính để bàn". Vì tôi không muốn yêu cầu người dùng của tôi làm điều đó, tôi đã nhận được một số mã googling một lần nữa để thiết lập tùy chọn này trong regedit của người dùng trong thời gian cài đặt. Vấn đề là thậm chí thiết lập tùy chọn này, nó không hoạt động. Tôi phải mở các tùy chọn Đăng nhập của dịch vụ (nó được chọn), bỏ chọn và kiểm tra lại.

Vì vậy, cách giải quyết điều đó? Làm thế nào là cách tốt nhất để có một dịch vụ cửa sổ với một điều khiển systray trong quá trình tương tự, có sẵn cho bất kỳ người dùng đăng nhập?

CẬP NHẬT: Cảm ơn bạn đã nhận xét cho đến giờ, các bạn. Tôi đồng ý nó là tốt hơn để sử dụng IPC và tôi biết rằng nó là xấu để trộn các cửa sổ dịch vụ và giao diện người dùng. Mặc dù, tôi muốn biết làm thế nào để làm điều đó.

+0

"Tôi biết rằng khớp nối UI với dịch vụ của tôi sẽ phá vỡ phần mềm của tôi, và có lẽ máy tính người dùng của tôi, nhưng tôi muốn để làm điều đó. " Thực hiện lại 3 hoặc 4 bước và đánh giá lại nếu bạn nên làm những gì bạn đang cố gắng làm. Nó thậm chí có ý nghĩa không? –

+2

@Greg D: Tôi không biết bạn đã nhận được báo giá này ở đâu, nhưng tôi chưa bao giờ nói một dịch vụ có giao diện người dùng sẽ phá vỡ máy tính của người dùng.Trên thực tế, bất kỳ phần mềm nào cũng có thể gây nhiều lộn xộn với máy tính của người dùng, vì vậy bạn không có điểm nào cả. Dù sao, tôi không bao giờ hỏi tôi có nên làm hay không, tôi hỏi LÀM THẾ NÀO để làm điều đó. – andrecarlucci

Trả lời

18

Hai quy trình riêng biệt liên lạc bằng công nghệ bạn chọn. Các dịch vụ có giao diện người dùng là ý tưởng tồi. Đừng đi xuống con đường này - bạn sẽ hối tiếc.

Tôi đã có kết quả rất tốt khi giao tiếp dịch vụ thông qua kết nối ổ cắm đơn giản - ghi lại giao thức dịch vụ của bạn tốt, giữ cho nó đơn giản nhất có thể được và dễ dàng hơn bạn nghĩ.

+1

Tôi hoàn toàn đồng ý với điều này. Nếu có thể tôi sẽ xem xét một số phương pháp giao tiếp không phải là cồng kềnh như remoting. ổ cắm, đường ống, vv – mattlant

+1

@andrecarlucci: Khi chúng ta nói về các dịch vụ với giao diện người dùng, nó không phải là "sở thích cá nhân", đó là thực tế kiến ​​trúc. Đi với các cổng TCP/IP và một giao thức đơn giản, được ghi chép đầy đủ sẽ là cách tốt nhất để bạn truy cập từ đây, mà không gặp vấn đề gì liên quan đến Service + UI trong cùng một quá trình. –

+0

Xin chào tất cả. Tôi đồng ý với tất cả các bạn. DotNet remoting chỉ là vậy. Nhưng đó không phải là câu hỏi, câu hỏi đặt ra là cách tốt nhất để làm điều đó trong cùng một quy trình và không phải là cách tốt nhất chút nào. Tôi sẽ rephrase cập nhật của tôi để nó không âm thanh thô lỗ, xin lỗi về điều đó. – andrecarlucci

1

Trong thực tế, bạn không nên kết hợp dịch vụ của mình với giao diện người dùng quản lý.

1

Tôi đồng ý với Greg. Có lẽ bạn có thể kiểm tra một cơ chế IPC khác. Có lẽ sử dụng ổ cắm và giao thức của riêng bạn. Hoặc, nếu ứng dụng điều khiển dịch vụ của bạn chỉ có thể kiểm soát dịch vụ trên máy cục bộ, bạn có thể sử dụng các đường ống có tên (thậm chí nhanh hơn).

0

Rất đơn giản - bạn cần tạo một chuỗi để thực hiện các sự kiện ứng dụng. Như thế này (mã nguồn cho C++ với CLR, nhưng bạn có thể làm điều này trong C#):

ref class RunWindow{ 
public: 
    static void MakeWindow(Object^ data) 
    { 
     Application::EnableVisualStyles(); 
     Application::SetCompatibleTextRenderingDefault(false); 

     Application::Run(gcnew TMainForm()); 
    }; 
}; 

Và tạo chủ đề trong chính

int main(array<System::String ^> ^args) 
{ 
    bool bService = RunAsService(L"SimpleServiceWithIconInTrayAndWindow"); 

    if (bService) 
    { 

     System::Threading::Thread ^thread = gcnew System::Threading::Thread(gcnew ParameterizedThreadStart(RunWindow::MakeWindow)); 
     thread->Start(); 

     ServiceBase::Run(gcnew simpleWinService()); 
     Application::Exit(); 
    } 
    else 
    { 
     Application::EnableVisualStyles(); 
     Application::SetCompatibleTextRenderingDefault(false); 

     // Create the main window and run it 
     Application::Run(gcnew TMainForm()); 
    } 

    return 0; 
} 
0

Những vấn đề chính với các dịch vụ tương tác là:

  • Bảo mật - quá trình khác có thể gửi tin nhắn thông qua máy bơm tin nhắn của nó, từ đó đạt được quyền truy cập vào quy trình HỆ THỐNG/ĐỊA PHƯƠNG.

  • Không đầy đủ - một dịch vụ tương tác không bao giờ thấy thông báo shell, do đó nó không thể tương tác với các biểu tượng Khu vực thông báo.

Chúng tôi thường xuyên sử dụng kết nối TCP và UDP để chuyển thông tin từ dịch vụ sang các dịch vụ khác, và trong một số trường hợp, MSMQ.

1

tôi đã tìm ra cách để làm điều này từ this article (nhấp vào liên kết "Change" trong bảng phương pháp).

string wmiPath = "Win32_Service.Name='" + SERVICE_NAME + "'"; 
using (ManagementObject service = new ManagementObject(wmiPath)) 
{ 
    object[] parameters = new object[11]; 
    parameters[5] = true; // Enable desktop interaction 
    service.InvokeMethod("Change", parameters); 
} 
+0

Vâng, tôi đã sử dụng mã của bạn ở đây và nó hoạt động. Nhưng tôi đã tạo giao diện điều khiển ứng dụng mới chạy sau khi cài đặt xong dịch vụ ... vì vậy, nếu ai đó cố gắng đặt điều này ở đâu đó trong 'OnStart()', nó không hoạt động như thế. – Cipi

+0

Và bạn có thể muốn chỉnh sửa và thêm: 'parameters [6] =" LocalSystem "; tham số [7] = ""; 'để đăng nhập như tài khoản hệ thống cục bộ được chọn. ;) – Cipi

+0

Giả sử bạn muốn có tài khoản LocalSystem. Hầu hết thời gian tôi nghĩ mọi người sẽ muốn giữ tài khoản giống nhau hơn là đảm bảo tài khoản là LocalSystem. – Phil

1

tôi có giải pháp trong một vài bước, đây là kế hoạch

  1. chúng tôi sẽ không để tạo ra một dự án dịch vụ với aa dạng cửa sổ, thay vào đó chúng ta sẽ tạo ra một hình ảnh studio giải pháp có chứa dự án dịch vụ cửa sổ, dự án biểu mẫu cửa sổ và dự án thiết lập.

  2. Ý tưởng là có cơ sở dữ liệu hoặc tệp hoặc bất kỳ thứ gì bạn cảm thấy thoải mái với lưu trữ dữ liệu mà bạn sẽ lưu trữ các thông số mà dịch vụ Windows của bạn sẽ luôn sử dụng để chạy. Vì vậy, cửa sổ dịch vụ của bạn và cửa sổ của bạn hình thức ứng dụng sẽ có thể sửa đổi và lấy dữ liệu từ nó.

  3. Để biểu mẫu chính của ứng dụng Windows kéo và thả một NotifyIcon trên biểu mẫu, trong tab thuộc tính, duyệt và chọn hình ảnh .ico (Bạn có thể tạo một trong studio trực quan nhưng đó là một chủ đề khác bạn có thể nhận được trên google hoặc liên hệ với tôi) Điều đó sẽ hiển thị trong khay hệ thống khi bạn chạy ứng dụng và biểu mẫu chính đang hoạt động hoặc được hiển thị, hãy thử nó, chạy ứng dụng.

  4. Thêm cả hai làm đầu ra trong dự án thiết lập của giải pháp. Để thêm một dự án vào một dự án thiết lập, chúng phải nằm trong cùng một giải pháp. Nhấp chuột phải vào dự án thiết lập trong trình khám phá giải pháp, đánh dấu thêm và sau đó chọn đầu ra của dự án, thêm dịch vụ cửa sổ và các kết quả đầu ra của cửa sổ và bạn sẽ thấy chúng trong trình khám phá giải pháp trong dự án thiết lập.

  5. thêm một dịch vụ windows đi xa hơn thế nhưng đó cũng là một chủ đề google nó

  6. Tạo phím tắt cho ứng dụng cửa sổ và thêm nó vào thư mục khởi động cũng là một google chủ đề hoặc liên hệ với tôi.

    LƯU Ý Lập biểu mẫu của bạn theo cách mà nút đóng không hiển thị và biểu mẫu đi vào Me.visible = false và nhấp đúp vào biểu tượng trong khay hệ thống là cách duy nhất để đặt me.visible = true. theo cách đó bất cứ khi nào máy tính khởi động, ứng dụng biểu mẫu windows của bạn cũng bắt đầu và hiển thị ngay lập tức được đặt thành false nhưng vì nó có biểu tượng thông báo với hình ảnh biểu tượng, nó sẽ hiển thị trong khay hệ thống và nhấp đúp vào nó. các cài đặt mà bạn đang lưu trữ cho dịch vụ, dịch vụ cũng tự động khởi động vì bạn đã cài đặt dịch vụ này trong khi thiết lập dịch vụ trong dự án thiết lập. mail của tôi là [email protected] cho một minh họa tốt hơn sử dụng ảnh chụp màn hình và giải thích đầy đủ