I am trying to use Shell32 to get extended file properties in c#.
My code for this is as follows.
var file = FileUpload1.PostedFile;
List<string> arrHeaders = new List<string>();
Shell shell = new ShellClass();
//Exception is thrown at next line
Folder rFolder = shell.NameSpace(Path.GetDirectoryName(file.FileName));
FolderItem rFiles = rFolder.ParseName(Path.GetFileName(file.FileName));
for (int i = 0; i < short.MaxValue; i++)
{
string value = rFolder.GetDetailsOf(rFiles, i).Trim();
arrHeaders.Add(value);
}
I am getting exception as follows.
Message – Unable to cast COM object of type 'Shell32.ShellClass' to interface type 'Shell32.IShellDispatch6'. 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)).
Stack Trace – at System.StubHelpers.StubHelpers.GetCOMIPFromRCW(Object objSrc, IntPtr pCPCMD, IntPtr& ppTarget, Boolean& pfNeedsRelease)
at Shell32.ShellClass.NameSpace(Object vDir)
at PBSWebApplication.Test.Button1_OnClick(Object sender, EventArgs e) in c:\Projects\PBSWebApplication\PBSWebApplication\PBSWebApplication\Test.aspx.cs:line 33
at System.Web.UI.WebControls.Button.OnClick(EventArgs e)
at System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument)
at System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument)
at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument)
at System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
How to fix this?
Thanks.
Best Answer
As you identified this is because Shell32 requires an STA thread. If you can't simply configure your app to run with an STA Thread as in your solution then as an alternative you can create a separate STA Thread, use it to run the Shell32 code, then continue execution. e.g. this is what I ended up with when writing an SSIS Script Task which as I understand it always runs on MTA thread. In my case I'm calling a different method of Shell32 (CopyHere) but same logic would apply whichever method you want to call: