2013-01-27 20 views
10

Tôi có thư viện .NET 4.0 sử dụng Shell32 và Folder.GetDetailsOf() để lấy siêu dữ liệu từ tệp WTV. Tôi đã sử dụng nó thành công với các ứng dụng Console và Windows Forms mà không có vấn đề gì. Nhưng vì một lý do nào đó, khi gọi thành phần từ .NET 4.0 Windows Service, lời gọi khởi tạo lớp Shell gây ra lỗi COM.Gọi Shell32.dll từ .NET Windows Service

Mã không nằm trong thư viện:

Shell32.Shell shell = new Shell();

Lỗi:

Không thể đúc tượng COM của loại 'Hệ thống .__ ComObject' giao diện gõ 'Shell32.Shell'. Thao tác này thất bại vì cuộc gọi QueryInterface trên thành phần COM cho giao diện với IID '{286E6F1B-7113-4355-9562-96B7E9D64C54}' không thành công do lỗi sau: Không hỗ trợ giao diện như vậy (Ngoại lệ từ HRESULT: 0x80004002 (E_NOINTERFACE)) .

Tôi đọc phần điền Căn hộ, COM Interops, Dynamic, PIA's, v.v., v.v.) Nhưng không có sự kết hợp các giải pháp tôi đã tìm thấy đã giải quyết được vấn đề. Nó phải là một cuộc gọi từ một chủ đề khác mà không thể nhìn thấy Interop. Help, please :)

Trả lời

3

Tôi nghi ngờ điều này có thể liên quan đến thực tế là, theo mặc định, Dịch vụ Windows không có quyền tương tác với máy tính để bàn.

Để kiểm tra lý thuyết đó, hãy định cấu hình lại (ít nhất là trên cơ sở tạm thời) các quyền dịch vụ của bạn để cho phép tương tác với máy tính để bàn. Liên kết sau bạn đi qua làm điều đó

https://superuser.com/questions/415204/how-do-i-allow-interactive-services-in-windows-7

CẬP NHẬT

The Shell32 functionality works just fine as LocalSystem, even when the "Allow service to interact with desktop" checkbox is unchecked, but doesn't seem to work at all under a specific user account (whether limited or admin)

Using SHFileOperation within a Windows service

Nếu bạn thành công trong việc này để làm việc, hãy chắc chắn rằng bạn ngăn chặn bất kỳ sự tương tác giao diện người dùng. Thông tin về làm thế nào để làm điều đó là có sẵn trong câu trả lời này:

https://stackoverflow.com/a/202519/141172

+0

Tôi đồng ý với bạn về sự cố về quyền. +1 – FrostyFire

+0

+1, nhưng theo [MSDN] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms683502%28v=vs.85%29.aspx), trong Vista và cao hơn dịch vụ không thể tương tác với máy tính để bàn ở tất cả (trực tiếp, dù sao). Từ trang được liên kết: "** Các 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." Tôi không chắc chắn tôi sẽ nói "theo mặc định" trong trường hợp đó. :-) –

+0

@KenWhite: Chỉ cần kiểm tra Windows 8 và hộp kiểm đó cho phép tương tác vẫn còn đó. Tôi nghĩ rằng đó là việc không thể tương tác với máy tính để bàn thuộc về người dùng đã đăng nhập. Tuy nhiên, tôi nghĩ rằng các dịch vụ có quyền đó vẫn nhận được phiên * máy tính để bàn * riêng của họ. –

0

Tôi đã tạo ra một dịch vụ Windows và tôi gọi shell32 với P/Invoke.

Trong trường hợp của tôi, nó là mô phỏng nhấp chuột phải vào file:

Trước tiên, tôi cần phải tạo ra một quá trình như sử dụng (không System) để tương tác với máy tính để bàn:

[DllImport("advapi32.dll", SetLastError=true, CharSet=CharSet.Auto)] 
static extern bool CreateProcessAsUser(
    IntPtr hToken, 
    string lpApplicationName, 
    string lpCommandLine, 
    ref SECURITY_ATTRIBUTES lpProcessAttributes, 
    ref SECURITY_ATTRIBUTES lpThreadAttributes, 
    bool bInheritHandles, 
    uint dwCreationFlags, 
    IntPtr lpEnvironment, 
    string lpCurrentDirectory, 
    ref STARTUPINFO lpStartupInfo, 
    out PROCESS_INFORMATION lpProcessInformation); 

Và trong quá trình này, tôi đã sử dụng Thư viện Shell32 (tải sau đó giải nén giá trị)

[DllImport("kernel32.dll")] 
private static extern IntPtr LoadLibrary(string dllName); 
[DllImport("user32.dll", CharSet = CharSet.Auto)] 
static extern int LoadString(IntPtr hInstance, uint uID, StringBuilder lpBuffer, int nBufferMax); 

Dịch vụ Windows của tôi có thể tìm thấy các giá trị khác nhau của Shell32 với điều này và tương tác với máy tính để bàn như chúng tôi er ;-)

Bạn có thể tìm thêm thông tin chi tiết cho P/Gọi về vấn đề này website

14

tôi đã cùng một vấn đề chỉ là thời gian gần đây với một ứng dụng dòng lệnh (console).Hóa ra, nó được yêu cầu chú thích phương thức Main() của chương trình với thuộc tính [STAThread]. Nó cũng đã được lưu ý rằng nó thất bại thảm hại trong cùng một cách chính xác nếu điểm nhập cảnh được chú thích với [MTAThread] thay thế. Tôi hy vọng nó sẽ giúp.