Самый быстрый способ изменить местоположение папки рабочего стола программно

Я хочу создать приложение, которое позволит пользователям иметь разные значки на разных рабочих столах Windows 10. Я могу справиться с переключением виртуальных рабочих столов, используя функции Window Station и Desktop, а также интерфейс оболочки Virtual Desktop. Итак, теперь я знаю, как определить, что рабочий стол был переключен, и мне нужно как можно быстрее изменить местоположение папки пользователя на рабочем столе.

Я знаю, что есть два способа сделать это в пользовательском интерфейсе:

A) Через свойства пользовательских папок

  1. открыто %HomePath%/Desktop в проводнике
  2. Щелкните правой кнопкой мыши на фоне, откройте Свойства
  3. На вкладке Расположение введите новый путь
  4. Нажмите OK, а затем Нет (поскольку вы не хотите перемещать файлы)
  5. Иногда необходимо: нажмите на рабочий стол, нажмите F2

,

Б) через реестр

  1. + Изменить Desktop в HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders на новый адрес
  2. Relog

,

Опция B была бы идеальной для программного решения, если бы не эта часть журнала. Который, как вы, конечно, можете понять, немного нарушает правила.

1 ответ

Приведенный ниже код VB.Net сохранит все открытые папки и размеры папок на рабочем столе в реестре Windows и восстановит их по требованию. Запустите из командной строки или командного файла. Для сохранения атрибутов папки добавьте параметр "Set" (без кавычек), для восстановления - без параметра.

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
Другие вопросы по тегам