Calling Shell32.dll from .NET Windows Service


I have a .NET 4.0 library that uses Shell32 and Folder.GetDetailsOf() to get metadata from WTV files. I have used it successfully with Console and Windows Forms apps without issue. But for some reason, when calling the component from a .NET 4.0 Windows Service, the call to initiate the Shell class causes a COM error.

The code that fails inside the library:

Shell32.Shell shell = new Shell();

The error:

Unable to cast COM object of type 'System.__ComObject' to interface type 'Shell32.Shell'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{286E6F1B-7113-4355-9562-96B7E9D64C54}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).

I read my fill of Apartment Threading, COM Interops, Dynamic, PIA's, etc, etc, etc :) But no combination of solutions I've found has solved the problem. It must be a calling from another thread that can't see the Interop. Help, please :)


4 Answers


I had the same problem just recently with a command line application (console). Turns out, it was required to annotate the program's Main() method with the [STAThread] attribute. It has also been noted that it fails miserably in the exact same way if the entry point is annotated with [MTAThread] instead. I hope it helps.

answered on Stack Overflow Jul 26, 2014 by Leandro

I suspect this may be related to the fact that, by default, a Windows Service does not have permission to interact with the desktop.

To test that theory, reconfigure (at least on a temporary basis) your service permissions to allow for desktop interaction. The following link walks you through doing that


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

If you succeed in getting this to work, make sure that you suppress any UI interaction. Information on how to do that is available in this answer:

answered on Stack Overflow Jan 27, 2013 by Eric J. • edited May 23, 2017 by Community

I have created a Windows Service and I called Shell32 with P/Invoke.

In my case, it was to simulating the right click on file :

First, I need to create a process as user (not System) to interact with 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);

And in this process, I used the Shell32 Library (load then extract the value)

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

My Windows Service can find the differents values of Shell32 with this and interact with the desktop like user ;-)

You can find more details for P/Invoke on this website

answered on Stack Overflow May 17, 2013 by OhMyGeo

Since I found my way here by searching for the error, I wanted to add that the same thing happens if you try to make a new Shell() from a non-gui thread in a GUI app - even when Main is annotated with [STAThread]. @Eric J's answer gave me enough of a hint to figure it out from there.

So if you want Shell() from a GUI app, you need to do the if( mainForm.InvokeRequired ) { mainForm.Invoke( ... ) } dance.

answered on Stack Overflow May 25, 2018 by sizer99

User contributions licensed under CC BY-SA 3.0