2008-11-06 42 views
41

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?

+0

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

Trả lời

49

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 ...

+0

Nhưng nó sẽ phải lấy thông tin người dùng, phải không? – Prakash

6

WTSEnumerateSessions và CreateProcessAsUser.

0

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 ...

0

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.

1

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.

+0

"Đ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

+0

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. –

5

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.

16

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.

0

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

2

Đó 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

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