从 ShellBrowserWindow 对象到 ShellFolderView 对象的类型转换异常 [英] Typecast exception from ShellBrowserWindow object to ShellFolderView object
问题描述
寻求帮助,试图找出为什么这种类型转换在我的机器上不起作用.
此代码作为时t 实现 ShellFolderView
接口,它会抛出那个异常.
我最终偶然发现了这篇文章,这让我对TypeName Function 似乎返回了实际类型,所以我最终得到了下面的工作代码:
公共函数 GetExplorerSelectedFiles() As String()Dim ExplorerFiles 作为新列表(字符串)Dim exShell As New Shell32.Shell对于每个窗口 As SHDocVw.ShellBrowserWindow In DirectCast(exShell.Windows, SHDocVw.IShellWindows)If TypeName(window.Document) Like "IShellFolderViewDual*" 然后对于 DirectCast(window.Document, ShellFolderView).SelectedItems 中的每个 fi As FolderItemExplorerFiles.Add(fi.Path)下一个万一下一个返回 ExplorerFiles.ToArray结束函数
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.
I ran the query Microsoft.VisualBasic.Information.TypeName(window.document)
and it returns "IShellFolderViewDual3".
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
这篇关于从 ShellBrowserWindow 对象到 ShellFolderView 对象的类型转换异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!