Скрипт Powershell из ярлыка для смены рабочего стола

Любые идеи и предложения о том, почему это работает при запуске из ж / в PS, но не при запуске из ярлыка, определенного как:

%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -File "C:\Users\bin\ChangeDesktop.ps1"

Содержимое ChangeDesktop.ps1:

set-itemproperty -path "HKCU:Control Panel\Desktop" -name WallPaper -value ""
rundll32.exe user32.dll, UpdatePerUserSystemParameters

Если я нахожусь в среде «командной строки» PS, фон рабочего стола автоматически удаляется и обновляется, за исключением того, что я должен вручную обновить рабочий стол, чтобы изменения вступили в силу.

Система Windows Server 2008 R2 - новая установка. Политика выполнения сценария установлена на RemoteSigned, и я не вижу ошибок PS. Я просто не вижу автоматического обновления рабочего стола при запуске с ярлыка на рабочем столе.

царапает голову

 Roelof Briers12 сент. 2018 г., 09:18
Нужно использовать одинарные кавычки в скрипте powershell. Сделал это, и это сработало как шарм. Спасибо за сценарий.
 Jay Bazuzi26 февр. 2012 г., 02:27
ярлыки во многом похожи на приглашение CMD, поэтому тестируйте командные строки ярлыков там, а не в приглашении PowerShell.

Ответы на вопрос(4)

Энди Арисменди является удивительным!

Я использовал это, чтобы сделать забавный проект -установить случайные обои соскобленные с сети.

Я публикую это здесь для всех, кто заинтересован. Перед его использованием необходимо изменить несколько констант в верхней части исходного кода скрипта. Вам также необходимо скачатьHtmlAgilityPack.dll библиотека (есть инструкции в комментариях к скрипту).

Наслаждайтесь!

Постскриптум Если сайт обоев, который я использую, выйдет из строя или изменит свой макет, очистка скрипта пойдет в ад, но, тем не менее, с моим сценарием в качестве примера, держу пари, вы сможете создать еще один скребок для обоев.

############## CONSTANTS ##############

# add the library for parsing html - HtmlAgilityPack - download it with nuget from https://www.nuget.org/packages/HtmlAgilityPack
# download nuget command line from https://dist.nuget.org/index.html and install HtmlAgilityPack with "nuget install HtmlAgilityPack" from the cmd

# enter the path to HtmlAgilityPack.dll library used for html parsing
$html_parser_path = "C:\Users\username\Documents\htmlagilitypack\HtmlAgilityPack.1.4.9.5\lib\Net20\HtmlAgilityPack.dll"

# choose where your wallpapers will be downloaded
$wallpaper_dir_path = "C:\Users\username\Pictures\"

# get random wallpaper category from wallpaperscraft.com - the ones below are my favourite categories, edit it if you want to get other categories

<#
you can choose your favorite wallpaper categories from the list below
    3D
    Abstract
    Animals
    Anime
    Brands
    Cars
    City
    Fantasy
    Flowers
    Food
    Games
    Girls
    Hi-Tech
    Holidays
    Macro
    Men
    Movies
    Music
    Nature
    Other
    Space
    Sport
    Textures
    TV Series
    Vector
#>

$categories = @("animals","flowers","macro","nature","space") 



# I download my wallpapers from the site below - real quality wallpapers
# don't forget to change your resolution - I'm using a 1920x1080 monitor

<#
A list of resolutions to choose from:

    1600x1200
    1400x1050
    1280x1024
    1280x960
    1152x864
    1024x768
    3840x2400
    3840x2160
    3840x1200
    2560x1600
    2560x1440
    2560x1080
    2560x1024
    2048x1152
    1920x1200
    1920x1080
    1680x1050
    1600x900
    1440x900
    1280x800
    1280x720
    2160x3840
    1440x2560
    1366x768
    1080x1920
    1024x600
    960x544
    800x1280
    800x600
    720x1280
    540x960
    480x854
    480x800
    400x480
    360x640
    320x480
    320x240
    240x400
    240x320
    2732x2732
    2048x2048
    1080x1920
    1024x1024
    750x1334
    640x1136
    640x960
    320x480
    1366x768
    1920x1080
    360x640
    1024x768
    1600x900
    1280x900
    1440x900
    1280x1024
    800x600
    1680x1050
    2560x1440
    320x480
    1920x1200
    480x800
    720x1280
#>

$resolution = "1920x1080" # default resolution
$url = "https://wallpaperscraft.com/catalog/category/$resolution" # category is a placeholder

############## END OF CONSTANT DECLARATIONS ##############

Add-Type @"
using System;
using System.Runtime.InteropServices;
using Microsoft.Win32;
namespace Wallpaper
{
   public enum Style : int
   {
       Tile, Center, Stretch, NoChange
   }
   public class Setter {
      public const int SetDesktopWallpaper = 20;
      public const int UpdateIniFile = 0x01;
      public const int SendWinIniChange = 0x02;
      [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
      private static extern int SystemParametersInfo (int uAction, int uParam, string lpvParam, int fuWinIni);
      public static void SetWallpaper ( string path, Wallpaper.Style style ) {
         SystemParametersInfo( SetDesktopWallpaper, 0, path, UpdateIniFile | SendWinIniChange );
         RegistryKey key = Registry.CurrentUser.OpenSubKey("Control Panel\\Desktop", true);
         switch( style )
         {
            case Style.Stretch :
               key.SetValue(@"WallpaperStyle", "2") ; 
               key.SetValue(@"TileWallpaper", "0") ;
               break;
            case Style.Center :
               key.SetValue(@"WallpaperStyle", "1") ; 
               key.SetValue(@"TileWallpaper", "0") ; 
               break;
            case Style.Tile :
               key.SetValue(@"WallpaperStyle", "1") ; 
               key.SetValue(@"TileWallpaper", "1") ;
               break;
            case Style.NoChange :
               break;
         }
         key.Close();
      }
   }
}
"@





Add-Type -Path $html_parser_path 

$rand_index = Get-Random -minimum 0 -maximum $categories.Length
$random_category = $categories[$rand_index]

# replace the placeholder "category" with the random category chosen above

$url = $url -replace "category", $random_category

$doc = New-Object HtmlAgilityPack.HtmlDocument
$doc.LoadHtml((New-Object System.Net.WebClient).DownloadString($url))

# NOTE: the html parser I'm using locates elements by XPath only
$page_links = $doc.DocumentNode.SelectSingleNode("//div[contains(@class, 'pages')]").SelectNodes("a")

# get last page link
$last_page_link = $page_links[$page_links.Count - 1].GetAttributeValue("href", "")

# get last page number 
$last_page_number = [regex]::match($last_page_link,'.*page(\d+)').Groups[1].Value

$random_page_number = Get-Random -minimum 0 -maximum $last_page_number
$random_page_addr = ""

# page 1 doesn't add anything to the url

if ($random_page_number -gt 0){
    $random_page_addr = "/page$random_page_number"
}

$doc.LoadHtml((New-Object System.Net.WebClient).DownloadString("$url$random_page_addr"))

# get wallpaper divs
$wallpaper_divs = $doc.DocumentNode.SelectNodes("//div[contains(@class, 'wallpaper_pre')]")

$random_wallpaper_div = Get-Random -minimum 0 -maximum 15 # there are 15 wallpapers on a page

# get a sample wallpaper link which has to be substituted later
$sample_wallpaper_link = $wallpaper_divs[$random_wallpaper_div].SelectNodes("a")[0].GetAttributeValue("href", "")

# substitute the above link to get the image link itself

$sample_wallpaper_link = $sample_wallpaper_link -replace "download", "image"
$sample_wallpaper_link = $sample_wallpaper_link -replace "/$resolution", "_$resolution.jpg"
$sample_wallpaper_link = $sample_wallpaper_link -replace "//", "https://"

$wallpaper_image_name = [regex]::match($sample_wallpaper_link,'.*image/(\w+)').Groups[1].Value
$wallpaper_image_name = "$wallpaper_image_name.jpg"

$wc = New-Object System.Net.WebClient

$save_location = "$wallpaper_dir_path$wallpaper_image_name"
$wc.DownloadFile($sample_wallpaper_link, "$save_location")

[Wallpaper.Setter]::SetWallpaper($save_location, 1 )

но для меня сработало использование одинарных кавычек вместо двойных. Так это будет выглядеть так:

Set-ItemProperty -path "HKCU:Control Panel\Desktop" -name 'wallpaper' -value 'some value'
rundll32.exe user32.dll, UpdatePerUserSystemParameters

чтобы он постоянно менял фон при каждом входе пользователя в систему.

Я внес следующие изменения, чтобы проверить, существует ли фон на компьютере в нужном месте, если он существует, а затем выйти, если не нужно копировать файл и задавать фон.

сначала он отображает скрытый общий ресурс, копирует файл в нужный каталог, устанавливает обои, а затем отключает скрытый общий ресурс. если "X" уже используется вашей компанией, введите другую букву диска. : D

$strFileName="C:\Users\Public\Pictures\background.jpg"
If (Test-Path $strFileName){
  # // File exists
  Exit-PSSession
}Else{
  # // File does not exist 
New-PSDrive -Name X -PSProvider Filesystem -Root   \\hiddenfileshare\wallpapers
Copy-Item X:\background.jpg C:\Users\Public\Pictures
[Wallpaper.Setter]::SetWallpaper( 'C:\Users\Public\Pictures\background.jpg',       0 )
Remove-PSDrive X
}
Решение Вопроса

rundll32.exe user32.dll, UpdatePerUserSystemParameters на самом деле не менял обои на коробке с x64 2008 года. Это действительно сделал, хотя ... Он вызывает Win32 API, чтобы вызвать изменение обоев. Если вы сохраните это как скрипт ChangeDesktop.ps1, он должен работать. Как это ниже, он удалит любые обои для рабочего стола. Однако, если вы хотите установить его, вы можете отредактировать последнюю строку с путем к поддерживаемому файлу изображения следующим образом:

[Wallpaper..bmp', 0 )

Второй аргумент для стиля:

0: плитка 1: центр 2: растяжение 3: без изменений

Сценарий:

Add-Type @"
using System;
using System.Runtime.InteropServices;
using Microsoft.Win32;
namespace Wallpaper
{
   public enum Style : int
   {
       Tile, Center, Stretch, NoChange
   }
   public class Setter {
      public const int SetDesktopWallpaper = 20;
      public const int UpdateIniFile = 0x01;
      public const int SendWinIniChange = 0x02;
      [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
      private static extern int SystemParametersInfo (int uAction, int uParam, string lpvParam, int fuWinIni);
      public static void SetWallpaper ( string path, Wallpaper.Style style ) {
         SystemParametersInfo( SetDesktopWallpaper, 0, path, UpdateIniFile | SendWinIniChange );
         RegistryKey key = Registry.CurrentUser.OpenSubKey("Control Panel\\Desktop", true);
         switch( style )
         {
            case Style.Stretch :
               key.SetValue(@"WallpaperStyle", "2") ; 
               key.SetValue(@"TileWallpaper", "0") ;
               break;
            case Style.Center :
               key.SetValue(@"WallpaperStyle", "1") ; 
               key.SetValue(@"TileWallpaper", "0") ; 
               break;
            case Style.Tile :
               key.SetValue(@"WallpaperStyle", "1") ; 
               key.SetValue(@"TileWallpaper", "1") ;
               break;
            case Style.NoChange :
               break;
         }
         key.Close();
      }
   }
}
"@

[Wallpaper.Setter]::SetWallpaper( '', 0 )

Первоначально из PoshCode:http://poshcode.org/491

 sanepete02 окт. 2015 г., 09:19
Я не могу заставить это сделать сплошной цвет, хотя.
 Andy Arismendi26 февр. 2012 г., 02:40
@JoeBaltimore У меня были странные результаты при использованииrundll32.exe, Иногда это будет работать из консоли, введенной вручную, иногда нет, иногда это будет работать из сценария, вызванного с помощью ярлыка, иногда нет ... По крайней мере, этот подход работает постоянно :-) Похоже,другие люди была та же проблема обновления обоев сrundll32 также.
 joebalt26 февр. 2012 г., 02:13
Большое спасибо, Энди. Это действительно работает. Я собираюсь по-прежнему интересоваться, почему другой метод, который я впервые попробовал, не работает при запуске из ярлыка. Windows Powershell порой странный зверь - по крайней мере, для меня это все еще так.
 Kolob Canyon09 нояб. 2016 г., 20:46
Может кто-нибудь, пожалуйста, объясните, чтоrundll32.exe является?
 Jente07 окт. 2014 г., 10:51
Спасибо. Я часами боролся с этим.

Ваш ответ на вопрос