2009-01-06 32 views
7

Tôi đang viết một ứng dụng trong C# cần chạy như một dịch vụ nhưng cũng có tương tác người dùng. Tôi hiểu rằng các dịch vụ không có giao diện người dùng, vì vậy tôi đã chia chương trình của tôi thành một ứng dụng biểu mẫu cửa sổ và một dịch vụ có thể giao tiếp với nhau.C# Chạy ứng dụng biểu mẫu Windows từ dịch vụ (và trong Vista)

Sự cố tôi gặp phải là tôi cần dịch vụ để đảm bảo ứng dụng biểu mẫu cửa sổ luôn chạy và khởi động lại ứng dụng nếu không. Tôi có thể phát hiện xem nó có đang chạy hay không và khởi động lại nó bằng mã sau trên Windows 2000/XP:

System.Diagnostics.Process.Start("ExePath"); 

nhưng trên Vista, nó chạy quy trình mới dưới dạng quy trình Local/System không thể nhìn thấy người dùng. Có ai đó quanh đây không? Có cách nào để phát hiện người dùng nào hiện đang đăng nhập và chạy quy trình mới với người dùng đó không? Tôi không cần tính đến chuyển đổi người dùng nhanh tại thời điểm này. Một cái gì đó - bất cứ điều gì - cơ bản sẽ đủ.

Tôi sẽ biết ơn bạn về mọi trợ giúp hoặc mẹo bạn có về chủ đề này.

Tôi cần làm rõ rằng tôi đang đặt tùy chọn "Cho phép dịch vụ tương tác với máy tính để bàn" khi dịch vụ được cài đặt. Đây là những gì cho phép nó hoạt động trên 2000/XP. Tuy nhiên, Vista vẫn có vấn đề nói trên.

+0

Tôi có thiếu gì đó không? Nếu bạn có một dịch vụ luôn chạy ... tại sao việc cửa sổ ứng dụng của bạn chạy không quan trọng? – bobwienholt

+0

Vì tôi cần một cách để dịch vụ liên lạc trực tiếp với người dùng. Có rất nhiều lý do cho điều này, nhưng ví dụ cơ bản nhất là để thông báo nâng cấp. –

+1

Tôi với những người khác ở đây ... Tôi nghi ngờ rằng bạn đang sử dụng phương pháp sai cho bất kỳ vấn đề nào bạn đang cố giải quyết. Nếu bạn * phải * có giao diện người dùng thì có thể bạn không nên sử dụng mô hình dịch vụ. Có lẽ cái gì đó nằm trong khay hệ thống ...? –

Trả lời

13

Ý tưởng chung cho loại điều này là, nếu người dùng cần tương tác với một dịch vụ, họ nên khởi chạy một ứng dụng riêng biệt. Nếu bạn muốn giúp họ, bạn có thể cấu hình ứng dụng riêng biệt đó để bắt đầu với các cửa sổ bằng cách đặt một phím tắt trong menu khởi động. Bạn cũng có thể tạo khôi phục sự cố vào ứng dụng của mình để ứng dụng có thể tự động khởi động lại.

Bạn không nên thực sự dựa vào việc giám sát ứng dụng biểu mẫu, nếu không có ai đăng nhập? Điều gì sẽ xảy ra nếu nhiều người đăng nhập? Nó chỉ làm mọi thứ lộn xộn theo cách này.

Có dịch vụ chỉ cần ngồi đó và phát sóng cho người nghe là cách để đi. Khi ứng dụng biểu mẫu bắt đầu, nó có thể thông báo cho dịch vụ mà nó muốn nghe các sự kiện.

+0

Như tôi đã đề cập trong các nhận xét ở trên, tôi cần dịch vụ để có thể thông báo trực tiếp cho người dùng về các sự kiện nhất định. Tôi sẽ được hạnh phúc một trong hai cách: nếu có một cách để giải quyết vấn đề tôi mô tả, hoặc nếu có một cách tốt hơn để thực hiện mục tiêu này. –

+1

Bạn cần ứng dụng biểu mẫu của mình tự động khởi động. Sau đó, nó sẽ thông báo cho dịch vụ đó là lắng nghe để cập nhật. – Bob

+0

Tôi đoán tôi sẽ phải chấp nhận điều đó. Tôi đã thực sự hy vọng có một cách để khởi động lại nó từ dịch vụ. –

2

Trong trường hợp này, bạn sẽ phải có quy trình giám sát thứ ba để phát hiện xem chương trình có bị lỗi hay không và khởi động lại trong trường hợp đó.

Tuy nhiên, bạn kết thúc với một vấn đề không thể giải quyết ở đây, vì quá trình giám sát sẽ phải được theo dõi để đảm bảo nó không bị tắt, v.v. v.v. v.v.

Bạn có thể muốn xem xét lại phương pháp này.

0

Trong Windows 2000 và XP, có một tùy chọn (hộp kiểm) trên tab Đăng nhập của cửa sổ thuộc tính dịch vụ để cho phép dịch vụ tương tác với máy tính để bàn. Tôi tin rằng đây là những gì bạn đang tìm kiếm. Tôi vừa viết một dịch vụ nhanh trong VB.NET với một Process.Start ("calc.exe") và Windows Calculator đã mở tốt.

Tôi không chắc chắn 100% tính năng này hoạt động theo cách tương tự trong Vista.

+0

Tôi nên rõ ràng hơn trong câu hỏi của mình. Tôi đã làm điều này. Đây là những gì cho phép nó khởi chạy ứng dụng biểu mẫu trên 2000/xp. Tuy nhiên, Vista sẽ mở chương trình như là một quá trình hệ thống cục bộ và nó không hiển thị với người dùng. –

0

Có vẻ như bạn có thể không cần một nửa hoạt động như dịch vụ (trừ khi có yêu cầu cao hơn), vì dịch vụ của bạn sẽ cần phải đối phó khi không có người dùng tương tác nào đăng nhập.

+0

Cảm ơn, nhưng tôi cần nó là một dịch vụ cho các đặc quyền. Tôi đang tính toán các tình huống khi ứng dụng biểu mẫu không chạy hoặc không có người dùng nào đăng nhập (giống như bây giờ). –

1

Tình huống khó khăn của nó. Như đã đề cập ở một vài địa điểm, nếu bạn phải có giao diện người dùng thì về mặt kỹ thuật, bạn không nên sử dụng dịch vụ. Sau đó, các dịch vụ chạy mà không cần người dùng đăng nhập. Nếu không có ai đăng nhập, bạn không thể có giao diện người dùng.

Thông thường, khi tôi cần một dịch vụ cần liên lạc với thế giới bên ngoài, có hai điều tôi chọn. Tôi có thể đặt một mục trong nhật ký sự kiện, hoặc tôi có thể thả một tin nhắn trong một hàng đợi.

Trong trường hợp của bạn, tôi sẽ sử dụng hàng đợi. Khi người dùng đăng nhập, bạn có thể tự động khởi động ứng dụng cho họ theo dõi hàng đợi. Nếu ứng dụng đang chạy, khi nhận được tin nhắn, chúng cũng được cảnh báo theo cách đó. Tuy nhiên, nếu người dùng đóng ứng dụng thì điều tương tự cũng xảy ra ... họ sẽ không biết.

+0

Đó là vấn đề của tôi :-p –

1

Đầu tiên, câu trả lời nhanh: Tùy chọn 'Cho phép dịch vụ tương tác với máy tính để bàn' (dịch vụ -> Thuộc tính -> Đăng nhập) hay chỉ định tài khoản cho phép bạn muốn gì? Nếu vậy, cả hai thứ này có thể được cấu hình trên lớp trình cài đặt dịch vụ của bạn.

Giống như những người khác, tôi nghi ngờ có cách tiếp cận tốt hơn cho điều này và một trong những điều sau đây là đúng: -Mã bên trong dịch vụ có thể được bao gồm trong ứng dụng winforms (có thể đang chạy trong chuỗi nền) và được thêm vào cửa sổ khởi động. Cả hai sẽ chạy -Các ứng dụng winforms chỉ có thể nghe các dịch vụ khi nó trên, và không cần phải được bắt đầu từ dịch vụ. Hoặc tương tự, ứng dụng có thể được thêm vào khởi động.

+0

Tôi đã chỉnh sửa câu hỏi ban đầu của mình. Tôi đã thiết lập tùy chọn đó khi dịch vụ được cài đặt. Cám ơn vì sự gợi ý. Tôi có lẽ sẽ khám phá cả hai lựa chọn. Tôi chỉ ước nó có thể làm những gì tôi yêu cầu. Nó sẽ làm cho cuộc sống của tôi dễ dàng hơn nhiều. –

3

Xem câu hỏi: How can a Windows Service execute a GUI application?. Nó giải quyết cùng một câu hỏi từ C/C++ (câu trả lời ngắn: CreateProcessAsUser), nhưng câu trả lời vẫn hợp lệ (với một số P/Invoke) cho C#.

+0

Cảm ơn. Sau khi nhìn vào câu trả lời đó, tôi nghĩ rằng tôi sẽ đi với phương pháp tiếp cận nền ẩn được đề cập bởi nhiều câu trả lời hữu ích/ý kiến. –

1

Để có dịch vụ của bạn chạy các ứng dụng như một người dùng (mà có vẻ là những gì bạn đang cố gắng làm), bạn cần phải làm như sau:

System.Security.SecureString ss = new System.Security.SecureString(); 

foreach (char c in password) 
    ss.AppendChar(c); 

System.Diagnostics.Process proc = Process.Start(path, arguments, username, ss, domain); 

đâu:

  • path = đường dẫn đầy đủ (bao gồm tên tệp) của tệp thực thi.
  • đối số = chuỗi các đối số (sử dụng một chuỗi rỗng là không có)
  • username = Tên của một tài khoản người dùng trên máy chủ của bạn/máy tính
  • domain = miền mạng của bạn (nếu bạn sử dụng một mạng lưới tài khoản- trống nếu không)

Ngoài ra, để dịch vụ của bạn có quyền khởi chạy ứng dụng, nó cũng phải đang hoạt động như một dịch vụ. Để thực hiện việc này, bạn cần phải thêm những dòng này vào lớp trình cài đặt dịch vụ của mình:

serviceProcessInstaller.Account = ServiceAccount.User; 

serviceProcessInstaller.Username = "yourdomain\\yourAccountName"; //Or just "AccountName" for local accounts..    

serviceProcessInstaller.Password = "yourPassword"; 
+0

bạn có thể sử dụng tên người dùng và mật khẩu từ một đối tượng Active Directory không? – SoftwareSavant

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