SHOW:
|
|
- or go back to the newest paste.
1 | <# :: Note that you can skip a program if you manually set another flag for it like the Override DPI reddit .com/9t5be1 | |
2 | @set v=2019.09.29 ||: run admin rights required section as scriptblock - should now work on systems it previously failed | |
3 | @title Automatically Disable Fullscreen Optimizations and DPI Override - AveYo - v%v% | |
4 | @color 1e & echo off & echo. & powershell -nop -c "iex ([System.IO.File]::ReadAllText('%~f0'));" &exit/b | |
5 | #>$main = { | |
6 | # CHOICE TEXT - &X IS OPTIONAL TO ACTIVATE KEYBOARD SHORTCUTS # CHOICE VALUE # DEFAULT:1 #> | |
7 | $t = @() ; $v = @() ; $d = @() | |
8 | $t += '&1 Disable Fullscreen optimizations '; $v += 'DISABLEDXMAXIMIZEDWINDOWEDMODE'; $d += 1 | |
9 | $t += '&2 Program DPI from main display when I signed in to Windows'; $v += 'PERPROCESSSYSTEMDPIFORCEOFF' ; $d += 0 | |
10 | $t += '&3 Program DPI from main display when I open this program '; $v += 'PERPROCESSSYSTEMDPIFORCEON' ; $d += 0 | |
11 | $t += '&4 High DPI scaling override by Application '; $v += 'HIGHDPIAWARE' ; $d += 0 | |
12 | $t += '&5 High DPI scaling override by System '; $v += 'DPIUNAWARE' ; $d += 0 | |
13 | $t += '&6 High DPI scaling override by System [Enhanced] '; $v += 'GDIDPISCALING DPIUNAWARE' ; $d += 0 | |
14 | $t += '&7 CLEAR MANUAL DEFINITIONS '; $v += '' ; $d += 0 | |
15 | $t += '&8 UNINSTALL '; $v += '' ; $d += 0 | |
16 | ||
17 | # SHOW CHOICES DIALOG FROM EXTENDED TEXT $t (INSTEAD OF VALUES $v) WITH DEFAULTS $d SELECTED - OUTPUTS INDEXES LIKE '1,3,4' | |
18 | $all = $t -join ','; $def = (($d -split "`n") | Select-String 1).LineNumber -join ','; $selected = @($false) * $t.length | |
19 | $result = Choices $all $def 'GlobalAppCompatFlags'; if($result){ $result -split ',' | % { $selected[[int]$_ - 1] = $true } } | |
20 | ||
21 | # QUIT IF NO CHOICE MADE | |
22 | if(!$result){ write-host -fore Red "`n No choice selected, exiting.. "; timeout /t 3 >$null; exit } | |
23 | ||
24 | # VALIDATE SELECTION WITH RULES LIKE 'IF GDIDPISCALING SELECTED THEN HIGHDPIAWARE MUST BE UNSELECTED' ETC. | |
25 | $uninstall=$false; $clear=$false | |
26 | if($selected[2]){$selected[1]=$false} <# SINGLE CHOICE FOR Program DPI (2 OR 3) AND High DPI (4 OR 5 OR 6) #> | |
27 | if($selected[5]){$selected[3]=$false; $selected[4]=$false}; if($selected[4]){$selected[3]=$false; $selected[5]=$false} | |
28 | if($selected[6] -and $selected[7]){$clear=$true; $uninstall=$true; $selected=@($false) * $t.length} <# CLEAR, UNINSTALL #> | |
29 | if($selected[6]){$clear=$true; $selected[6]=$false}; if($selected[7]){$uninstall=$true; $selected=@($false) * $t.length} | |
30 | ||
31 | # COMPUTE THE FLAGS VARIABLE APPLIED AUTOMATICALLY TO HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers | |
32 | $values = @(); (($selected -split "`n") | Select-String $true).LineNumber | % { if([int]$_){$values += $v[[int]$_ - 1]} } | |
33 | $flags = '~ ' + $values -join ' ' | |
34 | #if ($flags -eq '~ ') { $uninstall=$true } | |
35 | ||
36 | # IF SELECTED, CLEAR PREVIOUS FLAGS FOR ALL PROGRAMS ONCE - FIY: AUTOMATIC HANDLER DOES NOT OVERRIDE EXISTING ENTRIES | |
37 | if($clear){ | |
38 | write-host -fore Red "`n Clearing existing flags in registry for all programs.. "; timeout /t 3 >$null | |
39 | Remove-Item -Path 'HKCU:\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers' -EA 'silentlycontinue' -Force | |
40 | } | |
41 | ||
42 | # INSTALLING AND UNINSTALLING THE PERSISTENT WMI HANDLER REQUIRES ADMIN RIGHTS | |
43 | if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(544)) { | |
44 | write-host -fore Black -back Yellow "`n PERMISSION DENIED! Asking for admin rights.. "; timeout /t 3 >$null | |
45 | start powershell -Verb RunAs -ArgumentList "-nop -NoExit -C & { $($RunAsAdmin -replace '"', '\"') } '$flags' '$uninstall'"; exit | |
46 | } else { & $RunAsAdmin "$flags" "$uninstall" } | |
47 | ||
48 | } # $main Done! | |
49 | ||
50 | $RunAsAdmin = { param($Flags, $Uninstall) | |
51 | $script = { | |
52 | cmd /c color 1e; write-host -Fore Black -Back Gray "`n Flags: $flags " | |
53 | # UNINSTALL PERSISTENT WMI HANDLER IF SELECTED | |
54 | if($Uninstall -eq [bool]::TrueString){ | |
55 | write-host -Fore Red "`n Uninstalling GlobalAppCompatFlags.. " | |
56 | RemoveGlobalAppCompatFlags; timeout /t -1; exit | |
57 | } | |
58 | # INSTALL PERSISTENT, NON-PULLING, HIGH PERFORMANCE FILTERED WMI HANDLER TO ADD FLAGS FOR USER PROGRAMS ON SECOND LAUNCH | |
59 | write-host -Fore Red "`n Installing GlobalAppCompatFlags.. " #timeout /t 3 >$null | |
60 | AddGlobalAppCompatFlags $Flags | |
61 | write-host "`n DONE! All programs - old and new - will have above flags applied after being run once " | |
62 | write-host "`n INFO: To prevent this for a program, manually adjust another flag like Override DPI for it " | |
63 | write-host "`n INFO: If only CLEAR MANUAL DEFINITIONS is selected then flags are cleared automatically instead " | |
64 | timeout /t -1; exit | |
65 | } | |
66 | function RemoveGlobalAppCompatFlags(){ | |
67 | $ns = 'root\subscription' | |
68 | gwmi __eventFilter -Namespace $ns -filter "name='GlobalAppCompatFlags'"| Remove-WmiObject | |
69 | gwmi activeScriptEventConsumer -Namespace $ns -filter "name='GlobalAppCompatFlags'" | Remove-WmiObject | |
70 | gwmi __filtertoconsumerbinding -Namespace $ns -filter "Filter = ""__eventfilter.name='GlobalAppCompatFlags'"""| Remove-WmiObject | |
71 | } | |
72 | function AddGlobalAppCompatFlags($newflags){ | |
73 | $GlobalAppCompatFlags_script_embedded_in_WMI_database = @" | |
74 | ' Add GlobalAppCompatFlags automatically after launching user processes - applies on the second launch of the same program | |
75 | ' Yes it does it via the "infamous" WMI persistence - but are we really not gonna use legit super light methods out of fear now? | |
76 | ' Why vbs, though? For no other reason than shitty lazy AVs going indiscriminately ham on any js because it can run on the web.. | |
77 | Dim oldflags : newflags = "$newflags" | |
78 | Const HKU = 2147483651 : Const SEMISYNCHRONOUS = 48 | |
79 | layerskey = "Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers" | |
80 | querytext = "SELECT ExecutablePath FROM Win32_Process WHERE ProcessID=" & TargetEvent.ProcessID | |
81 | Set mExec = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\CIMv2").ExecQuery(querytext,,SEMISYNCHRONOUS) | |
82 | Set rProv = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv") | |
83 | Set regEx = New RegExp : regEx.Global = False : regEx.IgnoreCase = True | |
84 | filterprg = "^.:\\Program Files(?:\\| \(x86\)\\)(Common |dotnet|Microsoft |Windows |WindowsApps|MSBuild)" | |
85 | regEx.Pattern = "^.:\\Windows\\|^.\\ProgramData\\Package |\\AppData\\Local\\Temp\\|\\AppData\\Local\\Microsoft\\|" & filterprg | |
86 | For Each process in mExec | |
87 | If Not IsNull(process.ExecutablePath) And Not regEx.Test(process.ExecutablePath) Then | |
88 | process.GetOwnerSid sid : compatkey = sid & "\\" & layerskey | |
89 | ret = rProv.GetStringValue(HKU, compatkey, process.ExecutablePath, oldflags) | |
90 | If (ret <> 0) Then | |
91 | rProv.CreateKey HKU, compatkey : rProv.SetStringValue HKU, compatkey, process.ExecutablePath, newflags | |
92 | ElseIf (newflags = "~ ") Then | |
93 | rProv.DeleteValue HKU, compatkey, process.ExecutablePath | |
94 | End If | |
95 | End If | |
96 | Next | |
97 | "@ | |
98 | $EvtQuery = "SELECT * from Win32_ProcessStartTrace WHERE SessionID!=0" | |
99 | $nospam = @('cvtres','csc','svchost','DllHost','RuntimeBroker','backgroundTaskHost','rundll32','find','findstr','reg', | |
100 | 'PING','timeout','taskkill','Conhost','cmd','cscript','wscript','powershell','explorer','OpenWith','SearchProtocolHost', | |
101 | 'SpeechRuntime','browser_broker','MicrosoftEdgeCP','firefox','chrome','steamwebhelper') | |
102 | foreach ($n in $nospam){ $EvtQuery += " AND ProcessName!='"+$n+".exe'" } | |
103 | RemoveGlobalAppCompatFlags # Clear previous before new event subscription | |
104 | $EvtFilter = Set-WmiInstance -Class __EventFilter -NameSpace 'root\subscription' -Arguments @{ | |
105 | Name='GlobalAppCompatFlags';EventNameSpace='root\cimv2';QueryLanguage='WQL';Query=$EvtQuery } -ErrorAction Stop | |
106 | $EvtCon = Set-WmiInstance -Class ActiveScriptEventConsumer -Namespace 'root\subscription' -Arguments @{ | |
107 | Name='GlobalAppCompatFlags';ScriptingEngine='VBScript';ScriptText=$GlobalAppCompatFlags_script_embedded_in_WMI_database } | |
108 | Set-WmiInstance -Class __FilterToConsumerBinding -Namespace 'root\subscription' -Arguments @{Filter=$EvtFilter;Consumer=$EvtCon} | |
109 | } | |
110 | & $script } # $RunAsAdmin Done! | |
111 | ||
112 | # Choices dialog snippet - parameters: 1=allchoices, 2=default; [optional] 3=title, 4=textsize, 5=backcolor, 6=textcolor | |
113 | function Choices($all, $def, $n='Choices', [byte]$sz=12, $bc='MidnightBlue', $fc='Snow', $saved='HKCU:\Environment'){ | |
114 | [void][System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms'); $f=New-Object System.Windows.Forms.Form | |
115 | $a=$all.split(','); $s=$def.split(','); $reg=(Get-ItemProperty $saved).$n; if($reg.length){ $s=$reg.split(',') }; | |
116 | function rst(){ $cb | %{ $_.Checked=0; if($s -contains $_.Name){ $_.Checked=1 } } }; $f.Add_Shown({rst; $f.Activate()}) | |
117 | $cb=@(); $i=1; $a | %{ $c=New-Object System.Windows.Forms.CheckBox; $cb+=$c; $c.Text=$_; $c.AutoSize=1; | |
118 | $c.Margin='8,4,8,4'; $c.Location='64,'+($sz*3*$i-$sz); $c.Font='Tahoma,'+$sz; $c.Name=$i; $f.Controls.Add($c); $i++} | |
119 | $bt=@(); $j=1; @('OK','Reset','Cancel') | %{ $b=New-Object System.Windows.Forms.Button; $bt+=$b; $b.Text=$_; $b.AutoSize=1; | |
120 | $b.Margin='0,0,72,20'; $b.Location=''+(64*$j)+','+(($sz+1)*3*$i-$sz); $b.Font='Tahoma,'+$sz; $f.Controls.Add($b); $j+=2 } | |
121 | $v=@(); $f.AcceptButton=$bt[0]; $f.CancelButton=$bt[2]; $bt[0].DialogResult=1; $bt[1].add_Click({$s=$def.split(',');rst}); | |
122 | $f.Text=$n; $f.BackColor=$bc; $f.ForeColor=$fc; $f.StartPosition=4; $f.AutoSize=1; $f.AutoSizeMode=0; $f.FormBorderStyle=3; | |
123 | $f.MaximizeBox=0; $r=$f.ShowDialog(); if($r -eq 1){$cb | %{if($_.Checked){$v+=$_.Name}}; $val=$v -join ','; | |
124 | $null=New-ItemProperty -Path $saved -Name $n -Value $val -Force; return $val } | |
125 | } # Let's Make Console Scripts Friendlier Initiative by AveYo - MIT License - Choices '&one, two, th&ree' '2,3' 'Usage' | |
126 | & $main | |
127 | <#_#> |