-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathOnDock Display Installer.bat
296 lines (247 loc) · 10.9 KB
/
OnDock Display Installer.bat
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
powershell.exe "Get-ExecutionPolicy -Scope 'CurrentUser' | Out-File -FilePath '%TEMP%\executionpolicy.txt' -Force; Set-ExecutionPolicy -Scope 'CurrentUser' -ExecutionPolicy 'Unrestricted'; $script = Get-Content '%~dpnx0'; $script -notmatch 'supercalifragilisticexpialidocious' | Out-File -FilePath '%TEMP%\%~n0.ps1' -Force; Start-Process powershell.exe \"Set-Location -Path '%~dp0'; ^& '%TEMP%\%~n0.ps1'\" -verb RunAs" && exit
<#
////////////////////////////////////////////////
// OnDock Display Installer by Lulech23 //
////////////////////////////////////////////////
Perform any action when connecting and disconnecting to external displays
What's new:
* Initial release
To-do:
*
Notes:
*
#>
<#
INITIALIZATION
#>
# Version... obviously
$version = "1.0"
# OnDock data path
$path = "$env:AppData\OnDock"
<#
SHOW VERSION
#>
# Ooo, shiny!
Write-Host "`n " -BackgroundColor White -NoNewline
Write-Host "`n OnDock Display Installer [v$version] by Lulech23 " -NoNewline -BackgroundColor White -ForegroundColor DarkBlue
Write-Host "`n " -BackgroundColor White
# About
Write-Host "`nThis script will generate separate PowerShell scripts and Windows scheduled tasks to"
Write-Host "automatically perform actions when an external display is connected and disconnected."
Write-Host "Actions will be performed from folders added to the Start menu, where you can place any"
Write-Host "shortcuts to commands and applications that you wish."
Write-Host "`nIf you don't like something, running this script again will undo all changes to the"
Write-Host "system."
# Current installation
Write-Host "`nOnDock is currently: " -NoNewline
if (Test-Path "$path\OnDock.ps1") {
Write-Host "Installed" -ForegroundColor Cyan
Write-Host " * User actions will be performed upon connecting to an external display" -ForegroundColor Gray
$task = "Remove OnDock"
} else {
Write-Host "Uninstalled" -ForegroundColor Magenta
Write-Host " * No actions will be performed upon connecting to an external display" -ForegroundColor Gray
$task = "Install OnDock"
}
# Setup Info
Write-Host "`nSetup will: " -NoNewline
Write-Host "$task`n" -ForegroundColor Cyan
for ($s = 10; $s -ge 0; $s--) {
$p = if ($s -eq 1) { "" } else { "s" }
Write-Host "`rPlease wait $s second$p to continue, or close now (Ctrl + C) to exit..." -NoNewLine -ForegroundColor Yellow
Start-Sleep -Seconds 1
}
Write-Host
<#
INSTALL ONDOCK
#>
if ($task.contains("Install")) {
# Ensure OnDock directories exists
if (!(Test-Path -Path "$path")) {
New-Item -ItemType Directory -Path "$path" -Force | Out-Null
}
if (!(Test-Path -Path "$env:AppData\Microsoft\Windows\Start Menu\Programs\OnDock\Connect")) {
New-Item -ItemType Directory -Path "$env:AppData\Microsoft\Windows\Start Menu\Programs\OnDock\Connect" -Force | Out-Null
}
if (!(Test-Path -Path "$env:AppData\Microsoft\Windows\Start Menu\Programs\OnDock\Disconnect")) {
New-Item -ItemType Directory -Path "$env:AppData\Microsoft\Windows\Start Menu\Programs\OnDock\Disconnect" -Force | Out-Null
}
# Create shortcut to OnDock directory
$shell = New-Object -ComObject WScript.Shell
$shortcut = $shell.CreateShortcut("$env:AppData\Microsoft\Windows\Start Menu\Programs\OnDock\Open OnDock Directory.lnk")
$shortcut.TargetPath = "$env:AppData\Microsoft\Windows\Start Menu\Programs\OnDock\"
$shortcut.Save()
<#
CREATE SCRIPT
#>
Write-Host "`nGenerating OnDock script..."
Start-Sleep -Seconds 1
# Get initial monitor count
Set-Content -Path "$path\pnp.txt" -Value (Get-PnpDevice | Where-Object {($_.Class) -like "Monitor" -and ($_.Status) -like "Ok"}).count
# Write scheduled task to folder
Set-Content -Path "$path\OnDock.ps1" -Value @"
<#
//////////////////////////////
// OnDock by Lulech23 //
//////////////////////////////
#>
Register-WmiEvent -Class Win32_DeviceChangeEvent -SourceIdentifier DockStateChanged
do {
`$path = "`$env:AppData\OnDock"
`$event = Wait-Event -SourceIdentifier DockStateChanged
`$eventType = `$event.SourceEventArgs.NewEvent.EventType
`$eventCount = (Get-PnpDevice | Where-Object {(`$_.Class) -like "Monitor" -and (`$_.Status) -like "Ok"}).count
if (`$eventCount.length -eq 0) {
`$eventCount = 1
}
if (`$eventCount -ne (Get-Content "`$path\pnp.txt")) {
# OnDock Connect
if (`$eventCount -gt (Get-Content "`$path\pnp.txt")) {
# Run user actions
Get-ChildItem "`$env:AppData\Microsoft\Windows\Start Menu\Programs\OnDock\Connect" |
ForEach-Object {
Start-Process -FilePath "`$(`$_.FullName)"
}
# OnDock Disconnect
} else {
# Run user actions
Get-ChildItem "`$env:AppData\Microsoft\Windows\Start Menu\Programs\OnDock\Disconnect" |
ForEach-Object {
Start-Process -FilePath "`$(`$_.FullName)"
}
}
# Update display count
Set-Content -Path "`$path\pnp.txt" -Value "`$eventCount"
}
Remove-Event -SourceIdentifier DockStateChanged
} while (1 -eq 1) # Loop until next event
Unregister-Event -SourceIdentifier DockStateChanged
"@
<#
CREATE SCHEDULED TASK
#>
Write-Host "`nGenerating scheduled task..."
# Write scheduled task to folder
Set-Content -Path "$path\OnDock.xml" -Value @"
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>
<Date>2021-07-13T12:18:54.2929428</Date>
<Author>BUILTIN\Administrators</Author>
<Description>Perform any action when connecting and disconnecting to external displays</Description>
<URI>\OnDock Service</URI>
</RegistrationInfo>
<Triggers>
<LogonTrigger>
<Enabled>true</Enabled>
</LogonTrigger>
</Triggers>
<Principals>
<Principal id="Author">
<GroupId>S-1-5-32-544</GroupId>
<RunLevel>HighestAvailable</RunLevel>
</Principal>
</Principals>
<Settings>
<MultipleInstancesPolicy>StopExisting</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
<AllowHardTerminate>false</AllowHardTerminate>
<StartWhenAvailable>true</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
<IdleSettings>
<StopOnIdleEnd>false</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>false</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<DisallowStartOnRemoteAppSession>false</DisallowStartOnRemoteAppSession>
<UseUnifiedSchedulingEngine>true</UseUnifiedSchedulingEngine>
<WakeToRun>false</WakeToRun>
<ExecutionTimeLimit>PT0S</ExecutionTimeLimit>
<Priority>7</Priority>
</Settings>
<Actions Context="Author">
<Exec>
<Command>powershell</Command>
<Arguments>-NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File "$path\OnDock.ps1"</Arguments>
</Exec>
</Actions>
</Task>
"@
# Import task to Windows scheduler
$schtask = (Get-ScheduledTask "OnDock Service" -ErrorAction "SilentlyContinue" | Out-String)
if ($schtask.length -gt 0) {
# Delete old task, if any
Unregister-ScheduledTask -TaskName "OnDock Service" -Confirm:$False -ErrorAction "SilentlyContinue"
}
Register-ScheduledTask -TaskName "OnDock Service" -Xml (Get-Content "$env:AppData\OnDock\OnDock.xml" | Out-String)
# Run imported task
Enable-ScheduledTask -TaskName "OnDock Service" | Out-Null
Start-ScheduledTask -TaskName "OnDock Service"
# Ensure task creation succeeded
$schtask = (Get-ScheduledTask "OnDock Service" -ErrorAction "SilentlyContinue" | Out-String)
# End process, we're done!
if ($schtask.length -gt 0) {
Write-Host "`nProcess complete! " -NoNewline -ForegroundColor Green
Write-Host "OnDock installed successfully. You may now add actions to the " -NoNewLine
Write-Host "OnDock > Connect " -ForegroundColor Yellow
Write-Host "and " -NoNewline
Write-Host "OnDock > Disconnect " -NoNewline -ForegroundColor Yellow
Write-Host "folders of your Windows Start menu. Enjoy!"
Write-Host "`nIf you liked this, stop by my website at " -NoNewline
Write-Host "https://lucasc.me" -NoNewline -ForegroundColor Yellow
Write-Host "!"
} else {
# Show error if service creation failed
Write-Host "`nCreating OnDock service failed!" -ForegroundColor Magenta
Write-Host "`nPlease import `"$env:AppData\OnDock\OnDock.xml`" to Task Scheduler"
Write-Host "manually, if it exists."
}
}
<#
REMOVE ONDOCK
#>
if ($task.contains("Remove")) {
# Get user action removal preference
Write-Host
$purge = (Read-Host "Also remove user actions? (Y/N)").ToUpper()
Write-Host "`nRemoving OnDock..."
Start-Sleep -Seconds 1
# Remove user actions, if enabled
if ($purge -eq "Y") {
Remove-Item -Path "$env:AppData\Microsoft\Windows\Start Menu\Programs\OnDock" -Force -Recurse -ErrorAction SilentlyContinue
}
# Unregister OnDock service
Stop-ScheduledTask -TaskName "OnDock Service" | Out-Null
Unregister-ScheduledTask -TaskName "OnDock Service" -Confirm:$False -ErrorAction "SilentlyContinue"
Remove-Item "$env:AppData\OnDock\*"
# End process, we're done!
Write-Host "`nProcess complete! " -NoNewline -ForegroundColor Green
if ($purge -eq "Y") {
Write-Host "OnDock and all user actions have been removed. Enjoy, I guess..."
} else {
Write-Host "OnDock has been removed (user actions were unaffected). Enjoy, I guess..."
}
}
<#
FINALIZATION
#>
# Exit, we're done!
Write-Host
for ($s = 5; $s -ge 0; $s--) {
$p = if ($s -eq 1) { "" } else { "s" }
Write-Host "`rSetup will cleanup and exit in $s second$p, please wait..." -NoNewLine -ForegroundColor Yellow
Start-Sleep -Seconds 1
}
Write-Host
Write-Host "`nCleaning up..."
Start-Sleep -Seconds 1
# Reset execution policy and delete temporary script file
$policy = "Default"
if (Test-Path -Path "$env:Temp\executionpolicy.txt") {
$policy = [string] (Get-Content -Path "$env:Temp\executionpolicy.txt")
}
Start-Process powershell.exe "Set-ExecutionPolicy -Scope 'CurrentUser' -ExecutionPolicy '$policy'; Remove-Item -Path '$env:Temp\executionpolicy.txt' -Force; Remove-Item -Path '$PSCommandPath' -Force"