none
How to I change the Custom Properties of a Directory to optomize for Pictures? RRS feed

  • Question

  • I need to build a routine to change the properties of Directories to Optimize for Pictures.

    I can't seem to find an attribute in System.IO.DirectoryInfo(foundDirectory) that can help me set that property.

    Here is my code so far:

        Private Sub btnSetFolderProerties_Click(sender As Object, e As EventArgs) Handles btnSetFolderProerties.Click
            'Testing setting folder properties to optomize folder for pictures
            'txtbxFolderPath
            Dim foundDirectoryName As String
    
    
            For Each foundDirectory In My.Computer.FileSystem.GetDirectories(txtbxFolderPath.Text)
                Dim directoryStats As New System.IO.DirectoryInfo(foundDirectory)
                foundDirectoryName = directoryStats.Name
                foundDirectoryName = directoryStats.Attributes
            Next
    
        End Sub
    
    Does anyone have a suggestion as to how I can accomplish this?

    Wednesday, September 4, 2019 7:42 PM

All replies

  • Try executing these lines inside the loop:

    Dim f = Path.Combine(foundDirectoryName, "desktop.ini")
    Try
        File.SetAttributes(f, File.GetAttributes(f) And Not (FileAttributes.System Or FileAttributes.Hidden))
    Catch
        ' ignore
    End Try
    File.WriteAllLines(f, {"[ViewState]", "FolderType=Pictures"})
    File.SetAttributes(f, File.GetAttributes(f) Or FileAttributes.Hidden Or FileAttributes.System)


    It assumes that the optimisation is the only customisation.





    • Edited by Viorel_MVP Wednesday, September 4, 2019 8:10 PM
    Wednesday, September 4, 2019 8:00 PM
  • Ok I tried that but had to modify it to:

        Private Sub btnSetFolderProerties_Click(sender As Object, e As EventArgs) Handles btnSetFolderProerties.Click
            'Testing setting folder properties to optomize folder for pictures
            'txtbxFolderPath
            Dim foundDirectoryName As String
            Try
                For Each foundDirectory In My.Computer.FileSystem.GetDirectories(txtbxFolderPath.Text)
                    Dim directoryStats As New System.IO.DirectoryInfo(foundDirectory)
                    foundDirectoryName = directoryStats.Name
                    Dim f = Path.Combine(foundDirectory, "desktop.ini")
                    File.WriteAllLines(f, {"[ViewState]", "FolderType=Pictures"})
                    File.SetAttributes(f, File.GetAttributes(f) Or FileAttributes.Hidden Or FileAttributes.System)
                Next
            Catch ex As Exception
                MsgBox("Error: " & ex.Message)
            End Try
    
        End Sub


    I had to change your:

    Dim f = Path.Combine(foundDirectoryName, "desktop.ini")

    To:

    Dim f = Path.Combine(foundDirectory, "desktop.ini")

    In order to point to the correct Directory.

    I get an error on the line:

                File.WriteAllLines(f, {"[ViewState]", "FolderType=Pictures"})

    The error message reads:

    Access to the path 'F:\ZZTestn\!Other\!Backup\Rolling Stock\desktop.ini' is denied.


    Any ideas?  And yes I am running as admin on my computer but more important I have to distribute this code so people will not be running as admin.



    • Edited by TJBlues Wednesday, September 4, 2019 9:22 PM
    Wednesday, September 4, 2019 8:27 PM
  • Ok I now modified my code to be:

        Private Sub btnSetFolderProerties_Click(sender As Object, e As EventArgs) Handles btnSetFolderProerties.Click
            'Testing setting folder properties to optomize folder for pictures
            'txtbxFolderPath
            Dim foundDirectoryName As String
            Try
                For Each foundDirectory In My.Computer.FileSystem.GetDirectories(txtbxFolderPath.Text)
                    Dim directoryStats As New System.IO.DirectoryInfo(foundDirectory)
                    foundDirectoryName = directoryStats.Name
                    Dim f = Path.Combine(foundDirectory, "desktop.ini")
                    Try
                        File.SetAttributes(f, File.GetAttributes(f) And Not (FileAttributes.System Or FileAttributes.Hidden))
                    Catch
                        ' ignore
                    End Try
                    File.WriteAllLines(f, {"[ViewState]", "FolderType=Pictures"})
                    File.SetAttributes(f, File.GetAttributes(f) Or FileAttributes.Hidden Or FileAttributes.System)
                Next
            Catch ex As Exception
                MsgBox("Error: " & ex.Message)
            End Try
    
        End Sub
    

    But it does nothing. The folder does not optimize for "Pictures".  It is still optimized as a general folder.

    What I am looking for is the way to change the "Optimize this folder" in the properties from "General Items" to "Pictures"

    I want to change this:

    To this:

    In order to automatically view the directory contents as Pictures in the form of large icons when I open it.

    Wednesday, September 4, 2019 9:42 PM
  • Did you try to wait a minute and maybe close and reopen File Explorer before checking the new properties of the folders that include this “desktop.ini” file?

    Thursday, September 5, 2019 4:48 AM
  • Yes. I also opened the desktop.ini file and it shows:

    [ViewState]
    FolderType=Pictures

    • Edited by TJBlues Thursday, September 5, 2019 5:46 AM
    Thursday, September 5, 2019 5:41 AM
  • Hi,

    You can create a desktop.ini and modify the desktop.ini according to the link below.

    https://docs.microsoft.com/en-us/windows/win32/shell/how-to-customize-folders-with-desktop-ini

    Best Regards,

    Alex


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, September 6, 2019 2:42 AM
  • It is done with 

    SHGetViewStatePropertyBag

    then

    IPropertyBag.Write

    (tested on Windows 10)


    • Edited by Castorix31 Friday, September 6, 2019 4:54 AM
    Friday, September 6, 2019 4:52 AM
  • Alex, as you can see above I did create a desktop.ini file and listed its contents.  It does not work.
    Friday, September 6, 2019 5:11 PM
  • Ok thanks for the tip BUT do you have the code you used and the attributes or contents that you changed to make the directory work as described above (files shown as Large Icons with thumbnails for image files).  Also where can I learn more about those two functions SHGetViewStatePropertyBag and IPropertyBag.Write?  I have clicked the Hyperlinks and read  about the functions but really can't figure out how to implement them in my SW. 

    Also I am using windows 7 pro not windows 10.

    Friday, September 6, 2019 5:17 PM
  • A test by changing a directory "E:\test" to Pictures or Music =>

    (most of declarations are for refreshing the Explorer windows)

    Dim pItemIDL As IntPtr = ILCreateFromPath("E:\Test")
    If (pItemIDL <> IntPtr.Zero) Then
        Dim pPropertyBag As IPropertyBag = Nothing
        Dim IID_IPropertyBag As Guid = New Guid("{55272A00-42CB-11CE-8135-00AA004BB851}")
        Dim hr As HRESULT = SHGetViewStatePropertyBag(pItemIDL, "Shell", SHGVSPB_PERUSER Or SHGVSPB_PERFOLDER, IID_IPropertyBag, pPropertyBag)
        If (hr = HRESULT.S_OK) Then              
            Dim oVariant As Object = "Pictures"
            ' Dim oVariant As Object = "Music"
            hr = pPropertyBag.Write("FolderType", oVariant)
            
            'Add reference to "C:\Windows\System32\SHDocVw.dll" 
            Dim shellWindows As SHDocVw.ShellWindows = New SHDocVw.ShellWindows()
            Try
                 For Each window As SHDocVw.ShellBrowserWindow In shellWindows
                    Dim pShellBrowser As IShellBrowser = Nothing
                    Dim pInt As IntPtr = Marshal.GetIUnknownForObject(window)
                    Dim IID_IShellBrowser As Guid = New Guid("{000214E2-0000-0000-C000-000000000046}")
                    Dim SID_STopLevelBrowser As Guid = New Guid("{4C96BE40-915C-11CF-99D3-00AA004AE837}")
                    Dim pShellBrowserPtr As IntPtr = IntPtr.Zero
                    hr = IUnknown_QueryService(pInt, SID_STopLevelBrowser, IID_IShellBrowser, pShellBrowserPtr)
                    If (hr = HRESULT.S_OK) Then
                        pShellBrowser = TryCast(Marshal.GetObjectForIUnknown(pShellBrowserPtr), IShellBrowser)
                        Dim pShellView As IShellView = Nothing
                        hr = pShellBrowser.QueryActiveShellView(pShellView)
                        If (hr = HRESULT.S_OK) Then
                            Dim hWndShellView As IntPtr = IntPtr.Zero
                            pShellView.GetWindow(hWndShellView)
                            PostMessage(hWndShellView, WM_COMMAND, &H7104, IntPtr.Zero)
                            Marshal.ReleaseComObject(pShellView)
                        End If
                        Marshal.ReleaseComObject(pShellBrowser)
                    End If                       
                Next window
            Catch ex As Exception
                MessageBox.Show(String.Format("An error occurred:{0}{0}{1}", vbCrLf, ex.Message), "Exception Thrown", MessageBoxButtons.OK, MessageBoxIcon.Warning)
            End Try
            Marshal.ReleaseComObject(pPropertyBag)
        End If
        ILFree(pItemIDL)
    End If

    Declarations :

    		Public Enum HRESULT As Integer
            S_OK = 0
            S_FALSE = 1
            E_NOINTERFACE = &H80004002
            E_NOTIMPL = &H80004001
            E_FAIL = &H80004005
            E_UNEXPECTED = &H8000FFFF
            E_OUTOFMEMORY = &H8007000E
        End Enum
    
        <DllImport("Shell32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
        Public Shared Function ILCreateFromPath(<MarshalAs(UnmanagedType.LPWStr)> pszPath As String) As IntPtr
        End Function
    
        <DllImport("Shell32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
        Public Shared Sub ILFree(ByVal pidl As IntPtr)
        End Sub
    
        <DllImport("Shlwapi.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
        Public Shared Function SHGetViewStatePropertyBag(pidl As IntPtr, pszBagName As String, dwFlags As Integer, ByRef riid As Guid, ByRef ppv As IPropertyBag) As HRESULT
        End Function
    
        Public Const SHGVSPB_PERUSER = &H1 ' must have one of PERUSER or ALLUSERS
        Public Const SHGVSPB_ALLUSERS = &H2
        Public Const SHGVSPB_PERFOLDER = &H4 ' must have one of PERFOLDER ALLFOLDERS or INHERIT
        Public Const SHGVSPB_ALLFOLDERS = &H8
        Public Const SHGVSPB_INHERIT = &H10
        Public Const SHGVSPB_ROAM = &H20 ' modifies the above
        Public Const SHGVSPB_NOAUTODEFAULTS = &H80000000 ' turns off read delegation to more general property bags
    
        Public Const SHGVSPB_FOLDER = (SHGVSPB_PERUSER Or SHGVSPB_PERFOLDER)
        Public Const SHGVSPB_FOLDERNODEFAULTS = (SHGVSPB_PERUSER Or SHGVSPB_PERFOLDER Or SHGVSPB_NOAUTODEFAULTS)
        Public Const SHGVSPB_USERDEFAULTS = (SHGVSPB_PERUSER Or SHGVSPB_ALLFOLDERS)
        Public Const SHGVSPB_GLOBALDEFAULTS = (SHGVSPB_ALLUSERS Or SHGVSPB_ALLFOLDERS)
    
        <DllImport("Shlwapi.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
        Public Shared Function IUnknown_QueryService(punk As IntPtr, ByRef guidService As Guid, ByRef riid As Guid, ByRef ppv As IntPtr) As HRESULT
        End Function
    
        <ComImport()>
        <Guid("55272A00-42CB-11CE-8135-00AA004BB851")>
        <InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>
        Interface IPropertyBag
            <PreserveSig>
            Function Read(<[In], MarshalAs(UnmanagedType.LPWStr)> ByVal pszPropName As String, <[In], Out> ByRef pVar As Object, <[In]> ByVal pErrorLog As IntPtr) As HRESULT
            <PreserveSig>
            Function Write(<[In], MarshalAs(UnmanagedType.LPWStr)> ByVal pszPropName As String, <[In]> ByRef pVar As Object) As HRESULT
        End Interface
    
        <DllImport("User32.dll", EntryPoint:="PostMessageW", SetLastError:=True)>
        Public Shared Function PostMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As IntPtr) As Integer
        End Function
    
        Public Const WM_COMMAND = &H111
    
        <ComImport>
        <Guid("000214E2-0000-0000-C000-000000000046")>
        <InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>
        Interface IShellBrowser
            Inherits IOleWindow
            Overloads Function GetWindow(<Out> ByRef phwnd As IntPtr) As HRESULT
            Overloads Function ContextSensitiveHelp(ByVal fEnterMode As Boolean) As HRESULT
            Function InsertMenusSB(ByVal IntPtrShared As IntPtr, ByRef lpMenuWidths As OLEMENUGROUPWIDTHS) As HRESULT
            Function SetMenuSB(ByVal IntPtrShared As IntPtr, ByVal holemenuRes As IntPtr, ByVal IntPtrActiveObject As IntPtr) As HRESULT
            Function RemoveMenusSB(ByVal IntPtrShared As IntPtr) As HRESULT
            Function SetStatusTextSB(ByVal pszStatusText As String) As HRESULT
            Function EnableModelessSB(ByVal fEnable As Boolean) As HRESULT
            Function TranslateAcceleratorSB(ByVal pmsg As MSG, ByVal wID As UInt16) As HRESULT
            Function BrowseObject(ByVal pidl As IntPtr, ByVal wFlags As UInteger) As HRESULT
            Function GetViewStateStream(ByVal grfMode As UInteger, <Out> ByRef ppStrm As ComTypes.IStream) As HRESULT
            Function GetControlWindow(ByVal id As UInteger, <Out> ByRef pIntPtr As IntPtr) As HRESULT
            Function SendControlMsg(ByVal id As UInteger, ByVal uMsg As UInteger, ByVal wParam As Integer, ByVal lParam As IntPtr, <Out> ByRef pret As IntPtr) As HRESULT
            Function QueryActiveShellView(<Out> ByRef ppshv As IShellView) As HRESULT
            Function OnViewWindowActive(ByVal pshv As IShellView) As HRESULT
            Function SetToolbarItems(ByVal lpButtons As TBBUTTON, ByVal nButtons As UInteger, ByVal uFlags As UInteger) As HRESULT
        End Interface
    
        <ComImport>
        <Guid("00000114-0000-0000-C000-000000000046")>
        <InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>
        Interface IOleWindow
            Function GetWindow(<Out> ByRef phwnd As IntPtr) As HRESULT
            Function ContextSensitiveHelp(ByVal fEnterMode As Boolean) As HRESULT
        End Interface
    
        <StructLayout(LayoutKind.Sequential)>
        Public Structure OLEMENUGROUPWIDTHS
            <MarshalAs(UnmanagedType.U2, SizeConst:=6)>
            Public width As Integer()
        End Structure
    
        <StructLayout(LayoutKind.Sequential, Pack:=1)>
        Public Structure TBBUTTON
            Public iBitmap As Integer
            Public idCommand As Integer
            Public fsState As Byte
            Public fsStyle As Byte
            Public bReserved0 As Byte
            Public bReserved1 As Byte
            Public dwData As Integer
            Public iString As IntPtr
        End Structure
    
        <StructLayout(LayoutKind.Sequential)>
        Public Structure MSG
            Public hwnd As IntPtr
            Public message As UInteger
            Public wParam As Integer
            Public lParam As IntPtr
            Public time As Integer
            Public pt As Point
        End Structure
    
        <ComImport>
        <Guid("000214E3-0000-0000-C000-000000000046")>
        <InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>
        Interface IShellView
            Inherits IOleWindow
            Overloads Function GetWindow(<Out> ByRef phwnd As IntPtr) As HRESULT
            Overloads Function ContextSensitiveHelp(ByVal fEnterMode As Boolean) As HRESULT
            Function TranslateAccelerator(ByVal pmsg As MSG) As HRESULT
            Function EnableModeless(ByVal fEnable As Boolean) As HRESULT
            Function UIActivate(ByVal uState As UInteger) As HRESULT
            Function Refresh() As HRESULT
            Function CreateViewWindow(ByVal psvPrevious As IShellView, ByVal pfs As FOLDERSETTINGS, ByVal psb As IShellBrowser, ByVal prcView As RECT, <Out> ByRef pIntPtr As IntPtr) As HRESULT
            Function DestroyViewWindow() As HRESULT
            Function GetCurrentInfo(<Out> ByRef pfs As FOLDERSETTINGS) As HRESULT
            Function AddPropertySheetPages(ByVal dwReserved As Integer, ByVal pfn As IntPtr, ByVal lparam As IntPtr) As HRESULT
            Function SaveViewState() As HRESULT
            Function SelectItem(ByVal pidlItem As IntPtr, ByVal uFlags As SVSIF) As HRESULT
            Function GetItemObject(ByVal uItem As UInteger, ByRef riid As Guid, <Out> ByRef ppv As IntPtr) As HRESULT
        End Interface
    
        <StructLayout(LayoutKind.Sequential)>
        Public Structure FOLDERSETTINGS
            Public ViewMode As UInteger
            Public fFlags As UInteger
        End Structure
    
        <StructLayout(LayoutKind.Sequential)>
        Public Structure RECT
            Public left As Integer
            Public top As Integer
            Public right As Integer
            Public bottom As Integer
            Public Sub New(ByVal left As Integer, ByVal top As Integer, ByVal right As Integer, ByVal bottom As Integer)
                Me.left = left
                Me.top = top
                Me.right = right
                Me.bottom = bottom
            End Sub
        End Structure
    
        Public Enum SVSIF
            SVSI_DESELECT = 0
            SVSI_SELECT = &H1
            SVSI_EDIT = &H3
            SVSI_DESELECTOTHERS = &H4
            SVSI_ENSUREVISIBLE = &H8
            SVSI_FOCUSED = &H10
            SVSI_TRANSLATEPT = &H20
            SVSI_SELECTIONMARK = &H40
            SVSI_POSITIONITEM = &H80
            SVSI_CHECK = &H100
            SVSI_CHECK2 = &H200
            SVSI_KEYBOARDSELECT = &H401
            SVSI_NOTAKEFOCUS = &H40000000
        End Enum

    Friday, September 6, 2019 10:01 PM