הערה
הגישה לדף זה מחייבת הרשאה. באפשרותך לנסות להיכנס או לשנות מדריכי כתובות.
הגישה לדף זה מחייבת הרשאה. באפשרותך לנסות לשנות מדריכי כתובות.
Question
Monday, January 27, 2014 12:12 AM | 1 vote
How can you Programmically Close a windows folder in Visual Basic 2008?
All replies (15)
Monday, January 27, 2014 12:09 PM
What do you mean with "closing a folder" ?
PiekenPuil
Tuesday, January 28, 2014 12:40 AM
I wrote a program for work in VB 2008 that quickly locates a service or operator manual to a specific module to one of our industrial machines. These machines have several sections or modules. The code works ok and the program works good. Some modules have only one manual, so the program will just bring up the manual, which is always a PDF File. If the user decides to choose another machine section with only one manual the previous manual (PDF File) will close automatically and the new manual will appear, unless the user closes the previous file first. In some cases, The machine section has more than one manual, so a windows folder will open, containing the multiple manuals. I am having trouble having the program automatically close the folder if the user forgets to close the folder, before choosing a manual for another section or closing out of the program. If the user forgets to manually close the folder, the windows folder remains on the screen. I was looking for some relatively easy code that can be written into my program that will close a windows folder.
Also, is there a way to limit the same folder to only have one instance open on the screen at a time. If the user keeps selecting the same button to a machine section the same folder will keep opening. If the user hits the same button 10 times there will be 10 of the same folder on the screen.
Please help......Thanks!!
Tuesday, January 28, 2014 7:08 AM
Show some details about how the folder is opened. Do you execute some statements in order to display the folder?
Tuesday, January 28, 2014 8:25 AM
It seems you mix up the program windows explorer (file explorer on windows 8) with a folder. It seems somehow you start that program.
Probably it is better to create your own listview inside your program, then you are able to control it.
Success
Cor
Tuesday, January 28, 2014 9:04 AM | 1 vote
Hi, please add Microsoft Internet Controls(it is a COM reference) to your project, below code will show you how to close folder d:\123
Dim folderPath = "D:\123"
Dim windows = New SHDocVw.ShellWindows()
For Each window As SHDocVw.InternetExplorer In windows
If System.IO.Path.GetFileNameWithoutExtension(window.FullName).ToLower() = "explorer" And window.LocationURL.ToLower().Replace("/", "\").Contains(folderPath.ToLower()) Then
window.Quit()
End If
Next
Tuesday, January 28, 2014 9:09 AM | 1 vote
Hi, please add Microsoft Internet Controls(it is a COM reference) to your project, below code will show you how to close folder d:\123
Dim folderPath = "D:\123" Dim windows = New SHDocVw.ShellWindows() For Each window As SHDocVw.InternetExplorer In windows If System.IO.Path.GetFileNameWithoutExtension(window.FullName).ToLower() = "explorer" And window.LocationURL.ToLower().Replace("/", "\").Contains(folderPath.ToLower()) Then window.Quit() End If Next
He,
I had a very important windows explorer windows open. I lost some money because they are all gone when I tried your code. Do you pay me for that?
Success
Cor
Wednesday, January 29, 2014 1:23 AM
I tried the code and I keep getting: (Type 'SHDocVW.ShellWindows') is not definded for both lines that include this. What am I doing wrong?
Thanks
Wednesday, January 29, 2014 3:55 AM | 1 vote
Hi,
As Viorel asked, how are you opening the explorer windows? If you use the Process class to open the explorer windows then you can keep track of the processes that your app has opened. Then you can check if a specific one is opened already before opening another. Also you could loop threw the list and close each explorer window that your application opened when your app is being closed. That way if the user has 1 or 2 that they opened outside of your app they would not be closed on them.
There is a few ways to do this but, we would need to know how your opening the explorer windows. The above method would be better than this but, here is one way you can find all opened explorer windows and close ones that have a specific word or words in the title text of the window.
Imports System.Runtime.InteropServices
Imports System.Text
Public Class Form1
Public Const WM_CLOSE As Integer = &H10
<DllImport("user32.dll", EntryPoint:="FindWindowExW")> _
Private Shared Function FindWindowExW(ByVal hwndParent As IntPtr, ByVal hwndChildAfter As IntPtr, <InAttribute(), MarshalAs(UnmanagedType.LPTStr)> ByVal lpszClass As String, <InAttribute(), MarshalAs(UnmanagedType.LPTStr)> ByVal lpszWindow As String) As IntPtr
End Function
<DllImport("user32.dll", EntryPoint:="PostMessageW")> _
Private Shared Function PostMessageW(<InAttribute()> ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<DllImport("user32.dll", EntryPoint:="GetWindowTextW")> _
Private Shared Function GetWindowTextW(<InAttribute()> ByVal hWnd As IntPtr, <OutAttribute(), MarshalAs(UnmanagedType.LPWStr)> ByVal lpString As StringBuilder, ByVal nMaxCount As Integer) As Integer
End Function
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'Close all explorer windows that have (My Special Documents) in the title text
CloseExplorer("My Special Documents") 'This is not case sensitive
End Sub
Private Sub CloseExplorer(ByVal strTitle As String)
Dim hWnd As IntPtr = FindWindowExW(IntPtr.Zero, IntPtr.Zero, "CabinetWClass", Nothing)
While Not hWnd.Equals(IntPtr.Zero)
Dim sb As New StringBuilder(255)
GetWindowTextW(hWnd, sb, 255)
If sb.ToString.ToLower.Contains(strTitle.ToLower) Then PostMessageW(hWnd, WM_CLOSE, 0, 0)
hWnd = FindWindowExW(IntPtr.Zero, hWnd, "CabinetWClass", Nothing)
End While
End Sub
End Class
PS - I believe you may need to import a NameSpace and/or add a Reference to something for the example by lapheal.
Wednesday, January 29, 2014 6:11 AM
Dear Cor, sorry about that, I tried it before I posted the code, it worked very well in my Win 7 and Win 8 PC. So maybe I'm lucky:)
Hi Jessybo, you need to add COM: Microsoft Internet Controls, see below:
Wednesday, January 29, 2014 9:22 AM
You did not get it what I meant. Your ""Solution"" closes all open Windows Explorer programs, not only the one meant in the program which is meant.
Success
Cor
Thursday, January 30, 2014 5:37 PM
You did not get it what I meant. Your ""Solution"" closes all open Windows Explorer programs, not only the one meant in the program which is meant.
Success
Cor
Hi, what I tried is, I open 20 folders, one of them is d:\123, and I run the code, only d:\123 was closed, the other 19 folders are still opened.
Friday, January 31, 2014 3:46 AM
You did not get it what I meant. Your ""Solution"" closes all open Windows Explorer programs, not only the one meant in the program which is meant.
Success
CorHi, what I tried is, I open 20 folders, one of them is d:\123, and I run the code, only d:\123 was closed, the other 19 folders are still opened.
Well if you want to know what folders are open in explorer perhaps you can use this code, get the folder names and use the other code to close them. Code does not compile when using Option Strict On and only shows open folders that contain something.
Imports Shell32 ' Add reference browse C:\Windows\System32\Shell32.dll or com Microsoft Shell Controls and Automation
'http://xkom.blogspot.com/2011/06/get-opened-folder-location-in-explorer.html
Public Class Form1
Dim Lb As New ListBox
Dim WithEvents RoutineTimer As New Timer
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Lb.Parent = Me
Lb.Dock = DockStyle.Fill
Me.Text = "Opened Folder by user (explorer)"
RoutineTimer.Interval = 1000
RoutineTimer.Start()
End Sub
Sub GetOpenedFolder()
Dim MShell As New Shell
Dim SFV As ShellFolderView
Lb.Items.Clear()
On Error Resume Next
For Each o In MShell.Windows
If TypeName(o.document) <> "HTMLDocument" Then
SFV = o.Document
If SFV.Folder.Items.Count > 0 Then
Lb.Items.Add(TrimPath(CType(SFV.Folder.Items(0), ShellFolderItem).Path))
End If
End If
Next
End Sub
Sub Timer_Job() Handles RoutineTimer.Tick
GetOpenedFolder()
End Sub
Function TrimPath(ByRef s As String) As String
Return s.Remove(InStrRev(s, "\"))
End Function
End Class
Please BEWARE that I have NO EXPERIENCE and NO EXPERTISE and probably onset of DEMENTIA which may affect my answers! Also, I've been told by an expert, that when you post an image it clutters up the thread and mysteriously, over time, the link to the image will somehow become "unstable" or something to that effect. :) I can only surmise that is due to Global Warming of the threads.
Friday, January 31, 2014 3:14 PM
I tried the code and I keep getting: (Type 'SHDocVW.ShellWindows') is not definded for both lines that include this. What am I doing wrong?
Thanks
I don't know what you are doing wrong. But this code has a class also called "CloseOpenFolders" so you can add a class to a project and rename it from Class1.vb to CloseOpenFolder.vb by right clicking on it in solution explorer and renaming it.
Create a new project.
Add a Form with a Button and a Listbox. Copy and paste the Form code in the Forms code.
Add a class. Rename it. Copy and past the Class code into the class.
Test it out.
Also if necessary and you know how to use String.Replace you can replace file:/// with nothing and %20 (which represents a space in a URL apparently) with a space so your path reflects a normal path instead of a URL. And alter necessary code to use a normal path string.
Form Code
Option Strict On
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.CenterToScreen()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
ListBox1.Items.Clear()
For Each Item In CloseOpenFolders.GetOpenedFolders
ListBox1.Items.Add(Item.ToString)
Next
End Sub
Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox1.SelectedIndexChanged
If ListBox1.Items.Count > 0 Then
CloseOpenFolders.CloseFolders(ListBox1.SelectedItem.ToString)
End If
End Sub
End Class
Class code
' Option Strict On will not let the class compile so don't use it in the class.
Imports Shell32 ' Add reference browse C:\Windows\System32\Shell32.dll or Com Microsoft Shell Controls and Automation
Imports SHDocVw ' Add reference browse C:\Windows\System32\ShDocVw.Dll or Com Microsoft Internet Controls
Public Class CloseOpenFolders
Public Shared Function GetOpenedFolders() As List(Of String)
Dim MShell As New Shell
Dim TempStorage As New List(Of String)
Dim SBW As ShellBrowserWindow
On Error Resume Next
For Each Item In MShell.Windows
SBW = Item
If SBW.LocationURL.ToString.Contains("file:///") Then
Dim Temp As String = SBW.LocationURL.ToString
TempStorage.Add(Temp)
End If
Next
Return TempStorage
End Function
Public Shared Sub CloseFolders(ByRef FolderPath As String)
Dim windows = New SHDocVw.ShellWindows()
For Each window As SHDocVw.InternetExplorer In windows
If window.LocationURL.ToString.Contains(FolderPath) Then
window.Quit()
End If
Next
End Sub
End Class
Please BEWARE that I have NO EXPERIENCE and NO EXPERTISE and probably onset of DEMENTIA which may affect my answers! Also, I've been told by an expert, that when you post an image it clutters up the thread and mysteriously, over time, the link to the image will somehow become "unstable" or something to that effect. :) I can only surmise that is due to Global Warming of the threads.
Friday, January 31, 2014 10:22 PM
I have to agree with Cor. Why open a Windows folder? Just get a list of the .pdf's and let the user choose one. No need to open a Windows folder at all.
If you must close a Windows folder, you would have to find the window handle of that folder. It would probably be a window of explorer.exe. I think you can pinvoke FindWindowEx and search for the window by it's title.
Once you have found it, just post a WM_CLOSE message to it.
Saturday, August 12, 2017 1:01 PM
lapheal, you are a champion my friend. Thank you very much for your grate answer to this issue!