שתף באמצעות


How can you Programmically Close a windows folder in Visual Basic 2008?

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
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.

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!