以编程方式更改桌面文件夹位置的最快方法

时间:2016-12-10 15:45:48

标签: winapi windows-10 desktop explorer virtual-desktop

我想创建一个允许用户在不同的Windows 10桌面上拥有不同图标的应用程序。我可以使用Window Station and Desktop functionsVirtual Desktop Shell Interface来处理虚拟桌面的切换。所以现在我知道如何检测桌面已经切换,我需要尽快更改桌面用户文件夹的位置。

我知道在用户界面中有两种方法:

A)通过用户文件夹'特性

  1. 在资源管理器中打开%HomePath%/Desktop
  2. 右键单击背景,打开属性
  3. 在标签位置中输入新路径
  4. 点击OK,然后点击No(因为你不想移动文件)
  5. 有时需要:点击桌面,按F2
  6. B)通过注册表

    1. Desktop中的HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders更改为新地址
    2. 重新登录
    3. 如果对于重新编写部分,B选项对于程序设计解决方案是理想的选择。正如你当然可以理解的那样,这是一个破坏者。

1 个答案:

答案 0 :(得分:0)

下面的VB.Net代码将保存Windows注册表中所有打开的桌面文件夹位置和大小,并根据需要进行恢复。从命令行或批处理文件运行。要保存文件夹属性,请添加“设置”(无引号)参数,以便还原,无参数。

Option Explicit On
Imports System.Text
Public Class FixFolders
   Structure RECT
      Dim Left As Integer
      Dim Top As Integer
      Dim Right As Integer
      Dim Bottom As Integer
   End Structure
   Structure POINTAPI
      Dim x As Integer
      Dim y As Integer
   End Structure
   Structure WINDOWPLACEMENT
      Dim length As Integer
      Dim flags As Integer
      Dim showCmd As Integer
      Dim ptMinPosition As POINTAPI
      Dim ptMaxPosition As POINTAPI
      Dim rcNormalPosition As RECT
   End Structure
   Private Structure TDeskTopWindow
      Dim lhwnd As Integer
      Dim WinTitle As String
      Dim WinRect As RECT
   End Structure

   Private Declare Function GetWindowRect Lib "user32" Alias "GetWindowRect" (ByVal hwnd As Integer, ByRef lpRect As RECT) As Integer
   Declare Function MoveWindow Lib "user32" (ByVal hwnd As Int32, ByVal x As Int32, ByVal y As Int32, ByVal nWidth As Int32, ByVal nHeight As Int32, ByVal bRepaint As Int32) As Int32
   Declare Function GetDesktopWindow Lib "user32" () As Int32
   Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Int32, ByVal lpClassName As String, ByVal nMaxCount As Int32) As Int32
   Private Delegate Function EnumChildWindowsCallback(ByVal hWnd As IntPtr, ByVal lParam As IntPtr) As Boolean
   Private Declare Function EnumChildWindows Lib "user32" (ByVal hWnd As IntPtr, ByVal lpEnumFunc As EnumChildWindowsCallback, ByVal lParam As IntPtr) As Boolean
   Private Delegate Function EnumWindowsProcDelegate(ByVal hWnd As IntPtr, ByVal lParam As IntPtr) As Boolean
   Private Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As EnumWindowsProcDelegate, ByVal lParam As IntPtr) As Boolean
   Private Declare Auto Function GetWindowText Lib "user32" (ByVal hWnd As IntPtr, ByVal lpString As StringBuilder, ByVal nMaxCount As Integer) As Integer
   Private Declare Function SetFocusAPI Lib "user32" Alias "SetFocus" (ByVal hwnd As Int32) As Int32
   Private Declare Function SetWindowPlacement Lib "user32" (ByVal hwnd As Integer, ByRef lpwndpl As WINDOWPLACEMENT) As Integer
   Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwbd As Int32) As Int32
   'Private Declare Function FlashWindow Lib "User32" (ByVal hWnd As Int32, ByVal Invert As Int32) As Int32
   Private Declare Function SetActiveWindow Lib "User32" (ByVal hWnd As Int32) As Int32

   Private Shared lpwndplNew As WINDOWPLACEMENT
   Private Const SW_SHOWMINIMIZED As Short = 2
   Private Const SW_SHOWMAXIMIZED As Short = 3
   Private Const SW_SHOWNORMAL As Short = 1

   Private Shared Mode As String

   Private WindowArray() As String
   Private Shared DeskTopWindows() As TDeskTopWindow, DTWinIndex As Integer

   Public Shared Sub Main()
      Dim left, Right, Top, Bottom As Integer
      Dim DTWinIndex As Integer
      Dim RetVal1, RetVal2, RetVal3, TimeOut As Integer

      Mode = Command()
      GetDeskTopFolderWindows()

      For DTWinIndex = 0 To DeskTopWindows.GetUpperBound(0)
         Select Case Mode
            Case ""
               With DeskTopWindows(DTWinIndex)
                  'If it' s not there, put it in
                  If GetSetting("FixFolders", .WinTitle, "Left") = "" Then
                     SaveSetting("FixFolders", .WinTitle, "Left", .WinRect.Left.ToString)
                     SaveSetting("FixFolders", .WinTitle, "Right", .WinRect.Right.ToString)
                     SaveSetting("FixFolders", .WinTitle, "Top", .WinRect.Top.ToString)
                     SaveSetting("FixFolders", .WinTitle, "Bottom", .WinRect.Bottom.ToString)
                  End If

                  left = Val(GetSetting("FixFolders", .WinTitle, "Left"))
                  Right = Val(GetSetting("FixFolders", .WinTitle, "Right"))
                  Top = Val(GetSetting("FixFolders", .WinTitle, "Top"))
                  Bottom = Val(GetSetting("FixFolders", .WinTitle, "Bottom"))
                  While .WinRect.Bottom <> Bottom Or .WinRect.Left <> left Or .WinRect.Right <> Right Or .WinRect.Top <> Top
                     'RetVal1 = SetForegroundWindow(lhWnd)
                     RetVal2 = SetWindowPlacement(.lhwnd, lpwndplNew)          'This 'restores' the window if minimized
                     RetVal3 = MoveWindow(.lhwnd, left, Top, Right - left, Bottom - Top, True)
                     ' Log.WriteLine(Now.TimeOfDay.ToString.Substring(0, 8) & " Set " & .WinTitle)
                     RetVal1 = GetWindowRect(.lhwnd, .WinRect)  ' get current size
                     TimeOut += 1
                     If TimeOut > 1 And TimeOut < 10 Then Threading.Thread.Sleep(1000)
                  End While
               End With
            Case "Set"
               With DeskTopWindows(DTWinIndex)
                  SaveSetting("FixFolders", .WinTitle, "Left", .WinRect.Left.ToString)
                  SaveSetting("FixFolders", .WinTitle, "Right", .WinRect.Right.ToString)
                  SaveSetting("FixFolders", .WinTitle, "Top", .WinRect.Top.ToString)
                  SaveSetting("FixFolders", .WinTitle, "Bottom", .WinRect.Bottom.ToString)
               End With
         End Select
      Next
   End Sub

   Private Shared Sub GetDeskTopFolderWindows()
      Dim lhwnd As Integer, lParam As IntPtr
      DTWinIndex = -1
      lhwnd = GetDesktopWindow()  ' Find the Desktop's Child Windows
      EnumChildWindows(lhwnd, AddressOf EnumChildProc, lParam)
   End Sub
   Shared Function EnumChildProc(ByVal lhWnd As IntPtr, ByVal lParam As IntPtr) As Boolean
      Dim RetVal1 As Int32
      Dim WinClassBuf As String
      Dim WinTitleBuf As New StringBuilder(256)
      Dim WinClass As String
      Dim WinRect As RECT

      WinClassBuf = New String(Chr(0), 256)
      WinTitleBuf.Append(Chr(0), 256)
      RetVal1 = GetClassName(lhWnd, WinClassBuf, WinClassBuf.Length)
      WinClass = WinClassBuf.ToString
      WinClass = StripNulls(WinClassBuf)  ' remove extra Nulls & spaces
      If WinClass = "CabinetWClass" Or WinClass = "ExploreWClass" Then   ' TextBox Window
         DTWinIndex += 1
         ReDim Preserve DeskTopWindows(DTWinIndex)
         DeskTopWindows(DTWinIndex).lhwnd = lhWnd
         GetWindowText(lhWnd, WinTitleBuf, WinTitleBuf.Capacity)
         DeskTopWindows(DTWinIndex).WinTitle = WinTitleBuf.ToString
         RetVal1 = GetWindowRect(lhWnd, WinRect)  ' get current size
         DeskTopWindows(DTWinIndex).WinRect = WinRect
      End If
      EnumChildProc = True
   End Function

   Public Shared Function StripNulls(ByVal OriginalStr As String) As String
      ' This removes the extra Nulls so String comparisons will work
      If (InStr(OriginalStr, Chr(0)) > 0) Then
         'OriginalStr = Left(OriginalStr, InStr(OriginalStr, Chr(0)) - 1)
         OriginalStr = OriginalStr.Substring(0, OriginalStr.IndexOf(Chr(0)))
      End If
      StripNulls = OriginalStr
   End Function
End Class