2016-12-10 2 views
0

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

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

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

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

.

B) Via Registry

  1. Изменение Desktop в HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders по новому адресу
  2. Relog

.

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

+1

Цвет меня искусно, но безупречный ** прерыватель транзакции ** с вашим вторым вариантом состоит в том, что он опирается на недокументированные детали реализации, которые могут прерываться в любое время без предварительного уведомления. Убедитесь, что вы прочитали [длинную и печальную историю ключа оболочки Folders] (https://blogs.msdn.microsoft.com/oldnewthing/20031103-00/?p=41973). – IInspectable

+2

[SHSetKnownFolderPath] (https://msdn.microsoft.com/en-us/library/windows/desktop/bb762249.aspx) является официальным интерфейсом для перенаправления известной папки (например, рабочего стола) в новое место. @CodyGray: если более десятилетия [The Old New Thing] (https://blogs.msdn.microsoft.com/oldnewthing/) не удалось объяснить разницу между контрактами и деталями реализации (и почему полагаться на последнее опасно), я не знаю, что возможно. – IInspectable

ответ

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 
+0

** Добро пожаловать в StackOverflow! ** Не могли бы вы более подробно объяснить, что делает код? Сохраняет ли он информацию о * открытых окнах *? Хотя это определенно здорово, это не то, что мне нужно - в вопросе я говорю о «папке рабочего стола» (той, где находятся значки на рабочем столе в реальном времени) и изменении адресата (так что на рабочем столе появляются разные значки) , – m93a

Смежные вопросы