Get the Windows Download folder's path

后端 未结 4 1074
失恋的感觉
失恋的感觉 2021-01-05 05:24

I have some Excel VBA code that requires knowing the Downloads folder path. How could I do it?

Since you can move around the Downloads folder (and

相关标签:
4条回答
  • 2021-01-05 05:50

    Found the answer google a little more...

    The way to read the registry is, as per http://vba-corner.livejournal.com/3054.html:

    'reads the value for the registry key i_RegKey
    'if the key cannot be found, the return value is ""
    Function RegKeyRead(i_RegKey As String) As String
    Dim myWS As Object
    
      On Error Resume Next
      'access Windows scripting
      Set myWS = CreateObject("WScript.Shell")
      'read key from registry
      RegKeyRead = myWS.RegRead(i_RegKey)
    End Function
    

    And the GUID for the Downloads folder, as per MSDN's http://msdn.microsoft.com/en-us/library/windows/desktop/dd378457(v=vs.85).aspx:

    {374DE290-123F-4565-9164-39C4925E467B}

    Thus RegKeyRead("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders\{374DE290-123F-4565-9164-39C4925E467B}") yields the current user's Downloads folder path.

    0 讨论(0)
  • 2021-01-05 05:56
    Sub GetDownloadedFolderFiles()
    '
    ' Keep it simple - Paul Seré
    '
    Dim fso  As New FileSystemObject
    Dim flds As Folders
    Dim fls  As Files
    Dim f    As File
    
    'Downloads folder for the actual user!
    
    Set fls = fso.GetFolder("C:\Users\User\Downloads").Files 
    
    For Each f In fls
        Debug.Print f.Name
    Next
    
    End Sub
    
    0 讨论(0)
  • 2021-01-05 06:02

    The supported way to read such paths is to use the SHGetKnownFolderPath function.

    I wrote this VBA code to do that. It has been tested in Excel 2000.

    It won't work in any 64-bit version of Office. I don't know if its Unicode shenanigans will work in versions of Office more recent than 2000. It's not pretty.

    Option Explicit
    
    Private Type GuidType
      data1 As Long
      data2 As Long
      data3 As Long
      data4 As Long
    End Type
    
    Declare Function SHGetKnownFolderPath Lib "shell32.dll" (ByRef guid As GuidType, ByVal flags As Long, ByVal token As Long, ByRef hPath As Long) As Long
    Declare Function lstrlenW Lib "kernel32.dll" (ByVal hString As Long) As Long
    Declare Sub CoTaskMemFree Lib "ole32.dll" (ByVal hMemory As Long)
    Declare Sub RtlMoveMemory Lib "ntdll.dll" (ByVal dest As String, ByVal source As Long, ByVal count As Long)
    
    'Read the location of the user's "Downloads" folder
    Function DownloadsFolder() As String
    
    ' {374DE290-123F-4565-9164-39C4925E467B}
    Dim FOLDERID_Downloads As GuidType
        FOLDERID_Downloads.data1 = &H374DE290
        FOLDERID_Downloads.data2 = &H4565123F
        FOLDERID_Downloads.data3 = &HC4396491
        FOLDERID_Downloads.data4 = &H7B465E92
    Dim result As Long
    Dim hPath As Long
    Dim converted As String
    Dim length As Long
        'A buffer for the string
        converted = String$(260, "*")
        'Convert it to UNICODE
        converted = StrConv(converted, vbUnicode)
        'Get the path
        result = SHGetKnownFolderPath(FOLDERID_Downloads, 0, 0, hPath)
        If result = 0 Then
            'Get its length
            length = lstrlenW(hPath)
            'Copy the allocated string over the VB string
            RtlMoveMemory converted, hPath, (length + 1) * 2
            'Truncate it
            converted = Mid$(converted, 1, length * 2)
            'Convert it to ANSI
            converted = StrConv(converted, vbFromUnicode)
            'Free the memory
            CoTaskMemFree hPath
            'Return the value
            DownloadsFolder = converted
        Else
            Error 1
        End If
    End Function
    
    0 讨论(0)
  • 2021-01-05 06:07

    Simple Solution - usually works

    This is from a comment by @assylias. As others have mentioned it will provide the wrong folder path if the user has changed the default "Downloads" location - but it's simple.

    Function GetDownloadsPath() As String
        GetDownloadsPath = Environ$("USERPROFILE") & "\Downloads"
    End Function
    

    Best Solution

    The posted answer was returning "%USERPROFILE%\Downloads". I didn't know what to do with it so I created the function below. This turns it into a function and returns the actual path. Call it like this: Debug.Print GetCurrentUserDownloadsPath or Debug.Print GetCurrentUserDownloadsPath. Thanks to @s_a for showing how to read a registry key and finding the registry key with the folder path.

    ' Downloads Folder Registry Key
    Private Const GUID_WIN_DOWNLOADS_FOLDER As String = "{374DE290-123F-4565-9164-39C4925E467B}"
    Private Const KEY_PATH As String = "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders\"
    '
    Public Function GetCurrentUserDownloadsPath()
        Dim pathTmp As String
    
        On Error Resume Next
        pathTmp = RegKeyRead(KEY_PATH & GUID_WIN_DOWNLOADS_FOLDER)
        pathTmp = Replace$(pathTmp, "%USERPROFILE%", Environ$("USERPROFILE"))
        On Error GoTo 0
    
        GetCurrentUserDownloadsPath = pathTmp
    End Function
    '
    Private Function RegKeyRead(registryKey As String) As String
    ' Returns the value of a windows registry key.
        Dim winScriptShell As Object
    
        On Error Resume Next
        Set winScriptShell = VBA.CreateObject("WScript.Shell")  ' access Windows scripting
        RegKeyRead = winScriptShell.RegRead(registryKey)    ' read key from registry
    End Function
    
    0 讨论(0)
提交回复
热议问题