Typecast exception from ShellBrowserWindow object to ShellFolderView object

747 views Asked by At

Looking for help trying to figure out why this typecast is not working on my machine.
This code was provided as an answer to another question I had and it's not working for me. It works for the answer poster on their machine, but I'm get a an exception on the line trying to typecast from ShellBrowserWindow to ShellFolderView.

I am using Visual Studio Express 2013, running on Windows 7 Pro X64 Sp1. The target framework for the project is .Net Framework 4. I've added references to Microsoft Internet Controls and Microsoft Shell Controls and Automation and I've added the Imports statements for Shell32 and SHDocVw. DLL versions are as follows: shell32.dll = 6.1.7601.18517 and shdocvw.dll = 6.1.7601.1822 I'm not sure what I could be missing.

The code looks like this. (This code is in a form object)

     Imports EdmLib
     Imports Shell32
     Imports SHDocVw
     Public Class BlankForm   
         Private Sub BlankForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load

             Dim bar As String() = GetExplorerSelectedFiles()
             Exit Sub        
             'The rest of my program is below this line - I'm just trying to test this one function right now...

         End Sub

         'Uses the windows shell to get the files selected in explorer
         Public Function GetExplorerSelectedFiles() As String()
             Dim ExplorerFiles As New List(Of String)
             Dim exShell As New Shell32.Shell
             Dim SFV As Shell32.ShellFolderView


             For Each window As SHDocVw.ShellBrowserWindow In DirectCast(exShell.Windows, SHDocVw.IShellWindows)
                 If (window.Document).GetType.Name <> "HTMLDocumentClass" Then
                     SFV = CType(window.Document, ShellFolderView) '<--This is where it fails!!
                     For Each fi As FolderItem In SFV.SelectedItems
                         ExplorerFiles.Add(fi.Path)
                     Next
                 End If
             Next

             Return ExplorerFiles.ToArray
         End Function
 End Class

The line SFV = CType(window.Document, ShellFolderView) results in the following message:

An unhandled exception of type 'System.InvalidCastException' occurred in LaunchTemplateEPDM.exe

Additional information: Unable to cast COM object of type 'System.__ComObject' to interface type 'Shell32.ShellFolderView'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{29EC8E6C-46D3-411F-BAAA-611A6C9CAC66}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).

I've taken a screenshot of a quickwatch on the window object. A quickwatch on the window.document object shows an error saying it's either undefined or inaccessible.

Quickwatch on "window" object Quickwatch on "window.document"

I ran the query Microsoft.VisualBasic.Information.TypeName(window.document) and it returns "IShellFolderViewDual3".

1

There are 1 answers

1
CBRF23 On BEST ANSWER

I fixed it. Not sure why this happens on my system and not yours. What I found was that GetType.Name always just returns "System.__ComObject", regardless of whether the object is of type ShellFolderView, HTMLDocumentClass or something else. So what was happening was no matter what the actual type of the object was, it was passing the <>"HTMLDocumentClass" test because it was always evaluating to "System.__ComObject". Then when we tried to run the CType function on an object that didn't implement the ShellFolderView interface, it would throw that exception.

I eventually stumbled upon this article which led me to experiment with the TypeName Function which seems to return the actual type, and so I ended up with the working code below:

Public Function GetExplorerSelectedFiles() As String()
    Dim ExplorerFiles As New List(Of String)
    Dim exShell As New Shell32.Shell

    For Each window As SHDocVw.ShellBrowserWindow In DirectCast(exShell.Windows, SHDocVw.IShellWindows)

        If TypeName(window.Document) Like "IShellFolderViewDual*" Then
            For Each fi As FolderItem In DirectCast(window.Document, ShellFolderView).SelectedItems
                ExplorerFiles.Add(fi.Path)
            Next
        End If
    Next

    Return ExplorerFiles.ToArray
End Function