10

Shell32 と Folder.GetDetailsOf() を使用して WTV ファイルからメタデータを取得する .NET 4.0 ライブラリがあります。コンソール アプリと Windows フォーム アプリで問題なく使用できました。しかし、何らかの理由で、.NET 4.0 Windows サービスからコンポーネントを呼び出すと、Shell クラスを開始するための呼び出しで COM エラーが発生します。

ライブラリ内で失敗するコード:

Shell32.Shell shell = new Shell();

エラー:

タイプ 'System.__ComObject' の COM オブジェクトをインターフェイス タイプ 'Shell32.Shell' にキャストできません。IID '{286E6F1B-7113-4355-9562-96B7E9D64C54}' を持つインターフェイスの COM コンポーネントでの QueryInterface 呼び出しが次のエラーのために失敗したため、この操作は失敗しました: No such interface supported (HRESULT からの例外: 0x80004002 (E_NOINTERFACE)) .

Apartment Threading、COM Interops、Dynamic、PIAなどを読みました:)しかし、私が見つけた解決策の組み合わせは問題を解決していません。Interop を認識できない別のスレッドからの呼び出しである必要があります。助けてください :)

4

4 に答える 4

3

これは、デフォルトでは、Windows サービスがデスクトップと対話する権限を持っていないという事実に関連している可能性があると思われます。

その理論をテストするには、サービスのアクセス許可を (少なくとも一時的に) 再構成して、デスクトップとの対話を許可します。次のリンクは、それを行う手順を示しています

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

アップデート

Shell32 機能は、「デスクトップとの対話をサービスに許可する」チェックボックスがオフになっている場合でも、LocalSystem として正常に動作しますが、特定のユーザー アカウント (制限付きまたは管理者) ではまったく動作しないようです。

Windows サービス内での SHFileOperation の使用

これを機能させることに成功した場合は、UI インタラクションをすべて抑制してください。その方法に関する情報は、この回答で入手できます。

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

于 2013-01-27T01:03:32.170 に答える
0

Windows サービスを作成し、P/Invoke で Shell32 を呼び出しました。

私の場合、ファイルの右クリックをシミュレートすることでした:

最初に、 Desktop とやり取りするためのプロセスを (システムではなく) ユーザーとして作成する必要があります。

[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);

そして、このプロセスでは、Shell32 ライブラリを使用しました (ロードしてから値を抽出します)。

[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);

私のWindowsサービスは、これを使用してShell32のさまざまな値を見つけ、デスクトップのようなユーザーと対話できます;-)

P/Invoke の詳細については、このWeb サイトを参照してください。

于 2013-05-17T09:21:55.783 に答える