0

所以这是我在 Hyper-V 上创建新 VM 时作为操作系统设置脚本的一部分运行的 PowerShell 函数。我很好奇是否有更好的方法来实现这一点,或者这是否尽可能好?我希望这更简单,更容易实现。

Function Set-ComputerNameOnWallPaper($ComputerName = $env:COMPUTERNAME)
{
#   Pull in the types necesary to manipulate the DesktopWallPaper and the pictures 
#   Information for setting the desktop wallpaper from 
#    https://smulpuru.wordpress.com/2015/04/01/change-wallpaper-using-windows-api-systemparametersinfo-from-user32-dll/
#   Basis for for manipulating the graphic from 
#    http://stackoverflow.com/questions/2067920/can-i-draw-create-an-image-with-a-given-text-with-powershell

$setwallpapersource = @"
using System.Runtime.InteropServices;
public class wallpaper
{
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 )
{
SystemParametersInfo( SetDesktopWallpaper, 0, path, UpdateIniFile | SendWinIniChange );
}
}
"@
    if (-not ([System.Management.Automation.PSTypeName]'wallpaper').Type){
      Add-Type -TypeDefinition $setwallpapersource
    }
    Add-Type -AssemblyName System.Drawing

#   Get the paths to the current bakground Image
#   Generate a path for the modified Image
#   Genarate a path for a temp file in case the modified image already exists

    $imgInPath  = (Get-ItemProperty 'hkcu:\control panel\desktop\' -Name Wallpaper).Wallpaper
    $imgOutPath = Join-Path -Path $(Split-Path $imgInPath -Parent) -ChildPath $('MyComputerName.jpg')
    $imgTemp   = Join-Path -Path $(Split-Path $imgInPath -Parent) -ChildPath $('Temp01.jpg')

#   Clean up any existing modified images that may have been created by this function

    If ($imgInPath -eq $imgOutPath){       
        Remove-Item -Path $imgTemp -ErrorAction SilentlyContinue
        Copy-Item -Path $imgInPath -Destination $imgTemp 
        [wallpaper]::SetWallpaper($imgTemp)
        $imgInPath = $imgTemp
        Remove-Item -Path $imgOutPath -ErrorAction SilentlyContinue
    }

#   Get the current graphic and define where on that graphic to write the comptername
#   Note: Probably need to add a bit more error handling here

    $top = 850
    $left= 1160 
    $bmp = new-object System.Drawing.Bitmap $imgInPath

    if(($bmp.Width -lt $left) -or ($bmp.Height -lt $top)){
      throw("This function is not configured to work with your Desktop Image size.")
      break
    }

#   Manipulate the image here
#   Set up Font properties   

    $font = new-object System.Drawing.Font Calibri,36 
    $brushFg = [System.Drawing.Brushes]::White

#   Get a default color near where we are going to write 
#   Build the brush      

    $bkgColor=$bmp.GetPixel($left-10,$top-10)  
    $brushClr = [System.Drawing.Color]($bkgColor)
    $brushBg = [System.Drawing.SolidBrush]($brushClr)

#    Fill the possible space where the comptuer name will be written with a default color

    $graphics = [System.Drawing.Graphics]::FromImage($bmp) 
    $graphics.FillRectangle($brushBg,$left-3,$top-3,480,60)  

#   Draw the Comptuer Name

    $graphics.DrawString($ComputerName,$font,$brushFg,$left,$top) 
    $graphics.Dispose() 

#   Save the graphic, clean up the object

    $bmp.Save($imgOutPath) 
    $bmp.Dispose()

#   Set the new Wallpaper and clean up and temporary residue

    [wallpaper]::SetWallpaper($imgOutPath)
    Remove-Item -Path $imgTemp -ErrorAction SilentlyContinue    
}
4

1 回答 1

2

如果您想要一些干净且可配置的东西,Koliat 对 Sysinternals 套件中的 BgInfo 的建议可能是最佳途径。不需要重新发明轮子,除非你是为了好玩。看看其他实用程序。很多很棒的东西。

链接:

于 2015-12-31T01:48:59.187 回答