This was a tricky one, and I had a hard time finding a working solution. I finally found the solution by reading comments in differnt forum. I had to mix it together myself - here's the finished soup:
Situation: I had a VB.NET code that was based on VBscript code from "Hey, scripting guy" to programmatically pin shortcuts from the desktop onto the start menu. This line of code created a bit of a headache:
Dim oShell As Shell32.Shell = New Shell32.Shell
Dim oFolder As Shell32.Folder = oShell.NameSpace(0) '0 refers to user desktop
Problem: The code compiled and ran on my Vista computer, but once I moved the .exe file to a Server 2003 computer, it threw a runtime exception stating: Unable to cast COM object of type 'Shell32.ShellClass' to interface type 'Shell32.IShellDispatch5 and then the usual garble (actually, the garble did reveal the line of code in question)
Cause: The Shell32 library comes in a new version in Vista compared to XP/2003 - or that is my conception of what I could find on the subject. The problem is that under XP/2003, the Shell32.ShellClass is not casted to Shell32.IShellDispatch5, but to its predecessor, Shell32.IShellDispatch4. Now I knew the difference, but it meant that the program needs to reference the right one.
Solution: I found the two first lines of code below buried in a comment in a forum - when they replace the first line of code above, voilla: It works on all platforms (the term 'all' referring to XP, Server 2003 and Vista):
Dim ShellAppType As Type = Type.GetTypeFromProgID("Shell.Application")
Dim oShell As Object = Activator.CreateInstance(ShellAppType)
Dim oFolder As Shell32.Folder = oShell.NameSpace(0) '0 refers to user desktop
Nerds like me may be simple to please - it certainly made my day!
14 comments:
This doesn't work for me. It fail on seconds line Activator.CreateInstance with a Com exception.
Development machine=Vista
IDE=VS2005
User machine=XP Sp3
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 '{866738B9-6CF2-4DE8-8767-F794EBE74F4E}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE))."
Thanks!
Here is a c# method I wrote based on the above code:
public Shell32.Folder GetShell32NameSpaceFolder(Object folder)
{
Type shellAppType = Type.GetTypeFromProgID("Shell.Application");
Object shell = Activator.CreateInstance(shellAppType);
return (Shell32.Folder)shellAppType.InvokeMember("NameSpace",
System.Reflection.BindingFlags.InvokeMethod, null, shell, new object[] { folder });
}
Hi all,
Thank you for this. I'm not able to apply this change to my C# function even if the help of the last post.
Here it is, can someone help me?
/// This Zip the content of a given folder using (Microsoft Shell Controls And Automation API)
private void ZipThisFolder(string strSrcFolderPath, string strDestFolderPath)
{
//Create an empty zip file
byte[] arrEmptyZip = new byte[] { 80, 75, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
System.IO.File.WriteAllBytes(strDestFolderPath, arrEmptyZip);
// Init Shell32 Class
Shell32.ShellClass sc = new Shell32.ShellClass();
// The source folder is always the same
Shell32.Folder oSrcFolder = sc.NameSpace(strSrcFolderPath);
// the destination folder is retrieved from above
Shell32.Folder oDestFolder = sc.NameSpace(strDestFolderPath);
// Collect the source items
Shell32.FolderItems oFolderItems = oSrcFolder.Items();
//Copy the items into the empty zip
oDestFolder.CopyHere(oFolderItems, 20);
}
Regards
Benjamin
Thanks,
this solved my problem.
Excellent work, thanx a million!
The c# bypass in the comments is perfect as well.
Allows a working compatibility between all the mentionned windows platforms.
Hmm How can edit That C# code for VB.NET ?? pls Help i cant understand.. Can anybody explait it :(
this line here:
Dim oFolder As Shell32.Folder = oShell.NameSpace(0)
how do you pass in a string instead of 0 to get folders in a particular path?
Thank you much!! I just moved my development platform to Windows 7 and encountered this same problem. It was driving me crazy until I found your solution. Bravo!
-Skip in Portland, Oregon.
Thanks man. Your code really helped me out. It will be useful in the future considering I am moving alot of Windows 7 compiled projects to a Windows XP machine.
Thanks for this!
Alas, I was specifically using Shell32 for its zip File handling, so the work around doesn't actually work for me :(
If anyone finds out how to work around this and keep the zip file stuff working that would be great to know about.
I was actually using a folder path instead of the zero (desktop) and was getting the folder object empty (nothing)... after putting a .tostring it worked... very odd cus the variable was a string type....
Dim oFolder as Shell32.Folder = oShell.Namespace(mypath.ToString)
Similar problem to the last post, but using late binding of Shell32 in VBA. Shell.Namespace returns Nothing for the specified folder:
[code]
Sub VBA()
Dim Shell As Object, Folder As Object, folderPath As String
folderPath = "C:\Path\To\An\Existing\Folder"
Set Shell = CreateObject("Shell.Application")
Set Folder = Shell.Namespace(folderPath)
If Not Folder Is Nothing Then
'...
Else
MsgBox folderPath & " not found"
End If
End Sub[/code]
The solution is to surround the Namespace argument with parentheses to force it to be passed by value:
Shell.Namespace((folderPath))
Oddly, this problem doesn't occur with early binding of Shell32.
I also encounter this prb my prog was working fine in win7 but use to crash on XP when I was extracting file.
So here is solution for the prb hope will help someone. I am using VB.net 2008
'EXTRACT FILE IN BACKGRAOUND
Private Sub ExtractZip(ByVal zipFile As String, ByVal destination As String)
Try
If Not Directory.Exists(destination) Then
My.Computer.FileSystem.CreateDirectory(destination)
End If
Dim ShellAppType As Type = Type.GetTypeFromProgID("Shell.Application")
Dim objShell As Object = Activator.CreateInstance(ShellAppType)
Dim InpurFile = objShell.NameSpace(zipFile.ToString)
Dim OutputFile As Folder = objShell.NameSpace(destination.ToString)
OutputFile.CopyHere(InpurFile.Items, 20)
Catch ex As Exception
DisplayError(ex)
End Try
End Sub
I started to have this issue yesterday. I made the changes suggested here and they work perfect. Thanks,
Post a Comment