-
Notifications
You must be signed in to change notification settings - Fork 0
/
Set-ConsoleIcon.ps1
122 lines (106 loc) · 4.2 KB
/
Set-ConsoleIcon.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
##############################################################################
## Script: Set-ConsoleIcon.ps1
## By: Aaron Lerch, tiny mods by Hanselman
## Website: www.aaronlerch.com/blog
## Set the icon of the current console window to the specified icon
## Dot-Source first, like . .\set-consoleicon.ps1
## Usage: Set-ConsoleIcon [string]
## PS:1 > Set-ConsoleIcon "C:\Icons\special_powershell_icon.ico"
##############################################################################
$WM_SETICON = 0x80
$ICON_SMALL = 0
function Set-ConsoleIcon
{
param(
[string] $iconFile
)
[System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") | out-null
$iconFile
# Verify the file exists
if ([System.IO.File]::Exists($iconFile) -eq $TRUE)
{
$icon = new-object System.Drawing.Icon($iconFile)
if ($icon -ne $null)
{
$consoleHandle = GetConsoleWindow
SendMessage $consoleHandle $WM_SETICON $ICON_SMALL $icon.Handle
}
}
else
{
Write-Host "Icon file not found"
}
}
## Invoke a Win32 P/Invoke call.
## From: Lee Holmes
## http://www.leeholmes.com/blog/GetTheOwnerOfAProcessInPowerShellPInvokeAndRefOutParameters.aspx
function Invoke-Win32([string] $dllName, [Type] $returnType,
[string] $methodName, [Type[]] $parameterTypes, [Object[]] $parameters)
{
## Begin to build the dynamic assembly
$domain = [AppDomain]::CurrentDomain
$name = New-Object Reflection.AssemblyName 'PInvokeAssembly'
$assembly = $domain.DefineDynamicAssembly($name, 'Run')
$module = $assembly.DefineDynamicModule('PInvokeModule')
$type = $module.DefineType('PInvokeType', "Public,BeforeFieldInit")
## Go through all of the parameters passed to us. As we do this,
## we clone the user's inputs into another array that we will use for
## the P/Invoke call.
$inputParameters = @()
$refParameters = @()
for($counter = 1; $counter -le $parameterTypes.Length; $counter++)
{
## If an item is a PSReference, then the user
## wants an [out] parameter.
if($parameterTypes[$counter - 1] -eq [Ref])
{
## Remember which parameters are used for [Out] parameters
$refParameters += $counter
## On the cloned array, we replace the PSReference type with the
## .Net reference type that represents the value of the PSReference,
## and the value with the value held by the PSReference.
$parameterTypes[$counter - 1] =
$parameters[$counter - 1].Value.GetType().MakeByRefType()
$inputParameters += $parameters[$counter - 1].Value
}
else
{
## Otherwise, just add their actual parameter to the
## input array.
$inputParameters += $parameters[$counter - 1]
}
}
## Define the actual P/Invoke method, adding the [Out]
## attribute for any parameters that were originally [Ref]
## parameters.
$method = $type.DefineMethod($methodName, 'Public,HideBySig,Static,PinvokeImpl',
$returnType, $parameterTypes)
foreach($refParameter in $refParameters)
{
$method.DefineParameter($refParameter, "Out", $null)
}
## Apply the P/Invoke constructor
$ctor = [Runtime.InteropServices.DllImportAttribute].GetConstructor([string])
$attr = New-Object Reflection.Emit.CustomAttributeBuilder $ctor, $dllName
$method.SetCustomAttribute($attr)
## Create the temporary type, and invoke the method.
$realType = $type.CreateType()
$realType.InvokeMember($methodName, 'Public,Static,InvokeMethod', $null, $null,
$inputParameters)
## Finally, go through all of the reference parameters, and update the
## values of the PSReference objects that the user passed in.
foreach($refParameter in $refParameters)
{
$parameters[$refParameter - 1].Value = $inputParameters[$refParameter - 1]
}
}
function SendMessage([IntPtr] $hWnd, [Int32] $message, [Int32] $wParam, [Int32] $lParam)
{
$parameterTypes = [IntPtr], [Int32], [Int32], [Int32]
$parameters = $hWnd, $message, $wParam, $lParam
Invoke-Win32 "user32.dll" ([Int32]) "SendMessage" $parameterTypes $parameters
}
function GetConsoleWindow()
{
Invoke-Win32 "kernel32" ([IntPtr]) "GetConsoleWindow"
}