我有一个使用SHELL32和Folder.GetDetailsOf()从WTV文件获取元数据的.NET 4.0库。 我曾与控制台成功地使用它和Windows窗体应用程序没有问题。 但由于某些原因,要求从.NET 4.0的Windows服务的组件时,呼叫发起壳牌类导致COM错误。
该库中失败的代码:
Shell32.Shell壳=新壳牌();
错误:
无法投射型“系统.__ ComObject”的COM对象为接口类型“Shell32.Shell”。 此操作失败的原因是对IID“{286E6F1B-7113-4355-9562-96B7E9D64C54}”的界面处的COM组件调用QueryInterface失败,因为以下错误:不支持此接口(从HRESULT异常:0x80004002(E_NOINTERFACE)) 。
我读了我的公寓线程,COM互操作性展示,动态,PIA的,等,等,等:)但是,没有,我发现已经解决了这个问题的解决方案组合的填充。 它必须是从另一个线程不能看到互操作的呼叫。 请帮忙 :)
我用命令行应用程序(控制台)刚刚有同样的问题。 原来,人们需要来注释该程序的Main()
与方法[STAThread]
属性。 也有人指出,如果入口点是带有加注解的惨败在完全相同的方式失败[MTAThread]
代替。 我希望它能帮助。
我怀疑这可能与这样的事实,在默认情况下,Windows服务没有权限与桌面交互。
为了检验这一理论,重新配置(至少是暂时性的),你的服务的权限,允许桌面交互。 下面的链接将引导您这样做
https://superuser.com/questions/415204/how-do-i-allow-interactive-services-in-windows-7
UPDATE
该SHELL32功能工作得很好以LocalSystem,即使在“允许服务与桌面交互”复选框取消选中,但似乎并没有在一个特定的用户帐户在所有的工作(无论是限制或管理员)
使用Windows服务中SHFileOperation
如果你在得到这个工作取得成功,请确保您禁止任何用户界面交互。 如何做到这一点的信息,可在这样的回答:
https://stackoverflow.com/a/202519/141172
我创建了一个Windows服务,我叫SHELL32用的P / Invoke。
就我而言,这是模拟文件上点击右键:
首先,我需要创建一个过程,用户(不系统)与桌面交互:
[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的详细信息网站
因为我发现我的方式在这里通过搜索错误,我想补充一点,如果你试图让一个新的shell()从非GUI线程的GUI应用程序同样的事情发生 - 即使主标注有[STAThread ]。 @Eric J的回答给了我足够的提示,以从那里弄明白。
所以,如果你从一个GUI应用程序要壳牌(),你需要做的,如果(mainForm.InvokeRequired){mainForm.Invoke(...)}舞蹈。