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

All replies

  • What do you mean with "closing a folder" ?

    PiekenPuil

    Monday, January 27, 2014 12:09 PM
  • 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!!


    • Edited by Jessybo Tuesday, January 28, 2014 1:35 AM
    Tuesday, January 28, 2014 12:40 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 7:08 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 8:25 AM
  • 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

    • Proposed as answer by Cor Ligthert Tuesday, January 28, 2014 9:08 AM
    • Unproposed as answer by Cor Ligthert Tuesday, January 28, 2014 9:08 AM
    Tuesday, January 28, 2014 9:04 AM
  • 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

    Tuesday, January 28, 2014 9:09 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 1:23 AM
  • 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 3:55 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 6:11 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

    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

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

    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:46 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

    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 3:14 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.

    Friday, January 31, 2014 10:22 PM
  • lapheal, you are a champion my friend. Thank you very much for your grate answer to this issue! 
    Saturday, August 12, 2017 1:01 PM