Tôi đã viết một dịch vụ Windows cho phép tôi chạy và dừng ứng dụng từ xa. Các ứng dụng này được chạy bằng cách sử dụng CreateProcess, và điều này làm việc cho tôi bởi vì hầu hết chúng chỉ thực hiện xử lý backend. Gần đây, tôi cần chạy các ứng dụng trình bày GUI cho người dùng đăng nhập hiện tại. Làm thế nào để tôi viết mã trong C++ để cho phép dịch vụ của tôi định vị desktop hiện đang hoạt động và chạy GUI trên nó?Làm thế nào một dịch vụ Windows có thể thực thi một ứng dụng GUI?
Trả lời
Roger Lipscombe của câu trả lời, để sử dụng WTSEnumerateSessions để tìm các máy tính để bàn phải, sau đó CreateProcessAsUser để khởi động ứng dụng trên máy tính để bàn (bạn vượt qua nó xử lý của máy tính để bàn như là một phần của cấu trúc STARTUPINFO) là đúng.
Tuy nhiên, tôi sẽ mạnh mẽ khuyên bạn không nên làm điều này. Trong một số môi trường, chẳng hạn như máy chủ Terminal Server với nhiều người dùng đang hoạt động, xác định máy tính để bàn nào là máy tính đang hoạt động không dễ dàng và thậm chí không thể thực hiện được. Nhưng quan trọng nhất, nếu một ứng dụng sẽ đột nhiên xuất hiện trên màn hình của người dùng, điều này có thể xảy ra vào thời điểm xấu (hoặc vì người dùng không mong đợi nó hoặc vì bạn đang cố gắng khởi chạy ứng dụng khi phiên không hoàn toàn khởi tạo, trong quá trình tắt hoặc bất kỳ thứ gì).
Cách tiếp cận thông thường hơn là đặt lối tắt cho ứng dụng khách nhỏ cho dịch vụ của bạn trong nhóm khởi động toàn cầu. Ứng dụng này sau đó sẽ khởi chạy cùng với mọi phiên người dùng và có thể được sử dụng bắt đầu các ứng dụng khác (nếu muốn) mà không có bất kỳ thông tin đăng nhập người dùng, phiên và/hoặc máy tính để bàn nào.
Ngoài ra, phím tắt này có thể được di chuyển/tắt bởi các quản trị như mong muốn, mà sẽ làm cho việc triển khai các ứng dụng của bạn dễ dàng hơn nhiều, vì nó không đi chệch khỏi các tiêu chuẩn được sử dụng bởi các ứng dụng khác của Windows ...
Nhưng nó sẽ phải lấy thông tin người dùng, phải không? – Prakash
WTSEnumerateSessions và CreateProcessAsUser.
Tôi nghĩ rằng miễn là bạn chỉ có một người dùng đăng nhập, nó sẽ tự động hiển thị trên màn hình của người dùng đó.
Dù sao, hãy rất cẩn thận khi có dịch vụ bắt đầu một exe.
Nếu quyền ghi vào thư mục bằng exe không bị hạn chế, bất kỳ người dùng nào cũng có thể thay thế exe đó bằng bất kỳ chương trình nào khác, sau đó sẽ được chạy với quyền sytem. Lấy ví dụ cmd.exe (có sẵn trên tất cả các cửa sổ sytems). Lần sau khi dịch vụ cố gắng khởi động exe của bạn, bạn sẽ nhận được lệnh shell với quyền hệ thống ...
Nếu bạn khởi chạy GUI từ dịch vụ của mình, nó sẽ hiển thị trên màn hình hiện đang hoạt động.
Nhưng chỉ khi bạn đã điều chỉnh các quyền của dịch vụ: Bạn cần cho phép nó đến interact with the desktop.
On Win2K, XP và Win2K3 người dùng bàn điều khiển được đăng nhập trong Phiên 0, cùng một phiên dịch vụ đang sinh sống. Nếu một dịch vụ được cấu hình là tương tác, nó sẽ có thể hiển thị giao diện người dùng trên màn hình của người dùng.
Tuy nhiên, trên Vista, không người dùng nào có thể đăng nhập trong Phiên 0. Hiển thị giao diện người dùng từ dịch vụ có một chút phức tạp hơn. Bạn cần liệt kê các phiên hoạt động bằng cách sử dụng WTSEnumerateSessions API, tìm phiên giao diện điều khiển và tạo quy trình với tư cách người dùng đó. Tất nhiên, bạn cũng cần một mã thông báo hoặc thông tin đăng nhập của người dùng để có thể thực hiện điều đó. Bạn có thể đọc thêm chi tiết về quá trình này here.
"Điều này" bạn nói đến là gì? Lý do duy nhất tôi ở phiên 0 là nó là phiên đầu tiên không được sử dụng khi tôi đăng nhập ... – SamB
Trên Win2K, XP và Win2K3, chỉ có một phiên điều khiển và luôn ở Phiên 0. Tất cả các phiên khác được sử dụng bởi người dùng TS. –
Một số người đã đề xuất WTSEnumerateSessions và CreateProcessAsUser.Tôi tự hỏi tại sao không ai đề nghị WTSGetActiveConsoleSessionId, vì bạn nói bạn chỉ muốn nhắm mục tiêu một người dùng đã đăng nhập.
Một số người chắc chắn có quyền đề xuất CreateProcessAsUser. Nếu bạn gọi CreateProcess cũ theo cách bạn đã nói, thì GUI của ứng dụng sẽ chạy với các đặc quyền của dịch vụ thay vì các đặc quyền của người dùng.
Câu trả lời ngắn gọn là "Bạn không", khi mở chương trình GUI chạy trong ngữ cảnh người dùng khác là lỗ hổng bảo mật thường được gọi là Shatter Attack.
Hãy xem bài viết MSDN này: Interactive Services. Nó cung cấp một số tùy chọn cho một dịch vụ để tương tác với người dùng.
Nói tóm lại bạn có các tùy chọn này:
hiển thị một hộp thoại trong phiên của người dùng bằng cách sử dụng chức năng WTSSendMessage.
Tạo ứng dụng GUI ẩn riêng biệt và sử dụng chức năng CreateProcessAsUser để chạy ứng dụng trong ngữ cảnh của người dùng tương tác. Thiết kế ứng dụng GUI để giao tiếp với dịch vụ thông qua một số phương thức liên lạc truyền thông (IPC), ví dụ, các đường ống có tên. Dịch vụ này giao tiếp với ứng dụng GUI để thông báo khi nào cần hiển thị GUI. Ứng dụng truyền đạt kết quả tương tác của người dùng trở lại dịch vụ để dịch vụ có thể thực hiện hành động thích hợp. Lưu ý rằng IPC có thể hiển thị các giao diện dịch vụ của bạn qua mạng trừ khi bạn sử dụng danh sách điều khiển truy cập thích hợp (ACL).
Nếu dịch vụ này chạy trên hệ thống đa người dùng, hãy thêm ứng dụng vào khóa sau để nó chạy trong mỗi phiên: HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Run. Nếu ứng dụng sử dụng các đường ống được đặt tên cho IPC, máy chủ có thể phân biệt giữa nhiều quy trình người dùng bằng cách đặt cho mỗi ống một tên duy nhất dựa trên ID phiên.
Dịch vụ quan trọng không thể tương tác trực tiếp với người dùng như Windows Vista. Do đó, các kỹ thuật được đề cập trong phần có tiêu đề Sử dụng Dịch vụ tương tác sẽ không được sử dụng trong mã mới.
này được lấy từ: http://msdn.microsoft.com/en-us/library/ms683502(VS.85).aspx
Đó vấn đề Session 0, Dịch vụ tương tác, dịch vụ Windows phép dịch vụ để tương tác với máy tính để bàn trên Windows 7 hoặc Windows Vista
Bạn có thể đọc bài viết này http://www.codeproject.com/KB/vista-security/SubvertingVistaUAC.aspx
Tôi thử giải thích tại đây nó hoạt động trên Windows 7
- 1. Làm cách nào để chạy ứng dụng Windows GUI trên dịch vụ?
- 2. Làm thế nào tôi có thể làm cho một ứng dụng GUI trong Lua
- 3. Làm cách nào để GUI chờ dịch vụ windows?
- 4. Làm thế nào để sử dụng dịch vụ dịch trong một thực thể?
- 5. Làm thế nào tôi có thể vượt qua biên dịch ứng dụng Linux của mình để có được một tệp thực thi Windows trong Linux?
- 6. Làm thế nào một ứng dụng có thể hiển thị một đối tượng trên thanh tác vụ Windows?
- 7. Làm thế nào để gửi một email đơn giản từ một tập tin thực thi Windows?
- 8. Làm thế nào để thực thi một Groovy Script từ ứng dụng Grails của tôi?
- 9. Làm thế nào để sử dụng Fiddler để giám sát một Dịch vụ Windows?
- 10. Có thể biên dịch một ứng dụng JS + trình thông dịch NodeJS thành một tệp thực thi duy nhất không?
- 11. Làm thế nào để Bắt đầu/Dừng một dịch vụ Windows từ một ứng dụng ASP.NET - An ninh phát
- 12. Khởi chạy Ứng dụng GUI từ Dịch vụ Windows - Cửa sổ không xuất hiện
- 13. Làm thế nào để một ứng dụng khách WPF xác thực với một dịch vụ WCF trên Azure?
- 14. làm thế nào chúng ta có thể sử dụng một tập tin thực thi trong c + +?
- 15. Linux: Làm thế nào để tạo một daemon/dịch vụ có thể sử dụng với xinetd?
- 16. Chạy một dịch vụ Windows như một ứng dụng giao diện điều khiển
- 17. Làm thế nào tôi có thể gọi một dịch vụ từ một mẫu trong AngularJS?
- 18. Làm thế nào để chuyển đổi một ứng dụng Java hiện có để một dịch vụ SYS V (daemon)
- 19. Nhiều dịch vụ Windows trong một exe
- 20. Làm thế nào để nắm bắt đầu ra lỗi tiêu chuẩn từ một dịch vụ Windows?
- 21. Làm thế nào chúng ta có thể làm việc với VB6 dll được gọi là từ một ứng dụng đa dịch vụ C# windows?
- 22. Làm cách nào để thực thi tệp .bat từ ứng dụng biểu mẫu C# windows?
- 23. Làm thế nào để cài đặt một dịch vụ windows theo lập trình trong C#?
- 24. Làm thế nào để nhúng một thông dịch viên lisp phổ biến vào một ứng dụng gui
- 25. Dịch vụ AngularJS có thể sử dụng lại trong một Ứng dụng
- 26. Dịch vụ Windows có thể xác định ServiceName của nó như thế nào?
- 27. Làm thế nào để chạy một exe từ dịch vụ windows và ngừng dịch vụ khi quá trình exe thoát?
- 28. Tôi có thể lên lịch cho Dịch vụ Windows C# để thực hiện nhiệm vụ hàng ngày như thế nào?
- 29. "sử dụng net" lệnh trong một dịch vụ Windows
- 30. Làm thế nào để thực thi JavaExec nhiều lần trong một tác vụ bằng Gradle?
Bạn đang nhắm mục tiêu phiên bản Windows nào? Với Vista và 7 cửa sổ dịch vụ không thể có các thành phần GUI. Nghiên cứu của tôi là từ vài năm trở lại đây, nhưng nó liên quan đến tài khoản Administrator bị ẩn/vô hiệu hóa (session 0) mà các dịch vụ đang chạy. Giải pháp của tôi lúc đó là sử dụng MSMQ để giao tiếp giữa dịch vụ và một ứng dụng GUI riêng biệt. – gooch