Automate Windows 7 Ease of Access Setting "Turn off unnecessary animations" - powershell

I'm trying to find a away to automatically enable/disable a setting in Windows 7:
From Category view:
Control Panel\All Control Panel Items\Ease of Access Center\Make the computer easier to see
From Icon view:
Control Panel\All Control Panel Items\Ease of Access Center\Make the computer easier to see
The setting:
Turn off all unnecessary animations (when possible)
Some context:
This seems to be a way to disable the animations on Microsoft Office 2013 which are causing an Excel Add-in I wrote to behave sluggishly (the add-in itself does graph interactivity and animation, which chugs badly in Office 2013 with the new graphics hardware accelerated animations). I've tried the within Office setting to disable the animation, but it didn't have any effect after Office restart or reboot, and others have also reported this. Changing settings in the Ease of Access Center or the visual performance settings (Control Panel\All Control Panel Items\Performance Information and Tools > Adjust Visual Effects > Animate controls and elements inside windows) are the best way to remove the animations. The Ease of Access Center method I'm asking for help with doesn't require elevated privileges and works instantly, so if there is a way to automate it, it should be more seemless.
In the end I'd like to toggle the setting from VBA or VB.Net Microsoft Office Add-Ins, but I don't care what form the solution takes (batch file, Windows API, VBS script, PowerShell, etc.) since it should be easy to implement from the add-in. If it comes down to Auto-It style mouse-click automation, I'd rather just give the user instructions and pop up the explorer window for them.
Thanks for any helpful ideas!

"This stuff is also controlled via the computer properties -> advanced-> performance-> visual effect option. If you set it to best performance, all the stuff you want turned off is turned off.
Unfortunately this changes a whole bunch of registry values but if we
just narrow down on the stuff you want, there are 2 registry values
involved:
HKCU\Control Panel\Desktop\UserPreferencesMask
This is a reg_binary value. Change this value from 9E 2C 07 80 12 00
00 00 to 9E 2C 07 80 10 00 00 00 .
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\VisualEffects\VisualFxSetting
The VisualEffects key doesn't exist by default. There are a bunch of
values that can be defined under here but the only one that really
matters is VisualFxSettings. Set this to 2 to disable a lot of the
animations and also to tick "Turn off all unnecessary animations (when
possible)" ."
Quote from -> HERE
Run the following powershell, reboot, and you'll be good to go.
PS C:\> Push-Location
PS C:\> Set-Location "HKCU:\Control Panel\Desktop\"
PS HKCU\Control Panel\Desktop> Set-ItemProperty . -Name UserPreferencesMask -Value ([byte[]](0x9E,0x2C,0x07,0x80,0x10,0x00,0x00,0x00))
PS HKCU\Control Panel\Desktop> Pop-Location
PS C:\>
PS C:\> Push-Location
PS C:\> Set-Location HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\VisualEffects\
PS HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\VisualEffects> New-ItemProperty . VisualFxSetting -Value 2
PS HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\VisualEffects> Pop-Location

Related

Powershell: Set focus to child window

I am in the processing of Automating Virus Scan Exclusions. Since I cannot write straight to the registry, I am making a macro of sorts using PowerShell. It works pretty well, but I want to ensure that I have the focus of the window I want before I send a slew of key strokes to it.
Using the following code, I get to the VirusScan Exclusions for McAfee.
& 'C:\Program Files (x86)\McAfee\VirusScan Enterprise\mcconsol.exe'
Start-Sleep 5
[void] [System.Reflection.Assembly]::LoadWithPartialName("'Microsoft.VisualBasic")
[Microsoft.VisualBasic.Interaction]::AppActivate("VirusScan Console")
Start-Sleep -m 500
[void] [System.Reflection.Assembly]::LoadWithPartialName("'System.Windows.Forms")
[System.Windows.Forms.SendKeys]::SendWait("{DOWN}{DOWN}{DOWN}%{ENTER}")
start-sleep -m 500
#[Microsoft.VisualBasic.Interaction]::AppActivate("On-Access Scan Properties")
[System.Windows.Forms.SendKeys]::SendWait("{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{DOWN}{TAB}{TAB}{TAB}{RIGHT}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{RIGHT}%E")
start-sleep -m 750
However, there is a chance that focus could not be on the correct window.
Child windows
'On-Access Scan Properties' and then 'Set Exclusions' (as a child of 'On-Access Scan Properties') appear.
Questions:
1) What code can I use to set the focus to a particular subwindow (by title)?
2) What code can I use to test that the window is in fact the focus?
Basically I use and RDP manager to connect to a bunch of different machines. I want to set this script off and forget it. In order to do that, I have to ensure that the proper windows are in focus. It doesn't work well when I am switching between RDP connections.

Powershell - get status of Win 7 slideshow

Quick summary of question: In Windows 7, using Powershell or a little C#, how can we tell if a custom theme is going to leave a single image or do a slideshow in the background?
(Related questions but not quite the same and not answered:
How to resume Windows 7 slideshow after restoring default wallpaper (not answered / separate issue)
https://stackoverflow.com/questions/10556820/programatically-enable-windows-7-desktop-slideshow (not answered / separate issue)
How can I detect wallpaper changing as a result of the Windows 7 slideshow? (answers don't work for win 7 / separate issue)
Related resource, but didn't help:
http://www.heckler.com.br/blog/2011/03/29/desktop-background-slideshow-in-windows-home-basic-with-powershell/
)
The question is pretty much what it sounds like, and I am not sure why it is having so much trouble.
In Win8 I can use technique's based on Andy's post ( Powershell script from shortcut to change desktop ) to get the source image. From there and from what I can tell, slideshow always ends up in TranscodedWallpaper.jpg, and as soon as you drop to a single image it switches to the name of the image. So a bit round-about, but I can tell if slideshow is on
In Win7 I can check WallpaperSource
Get-ItemProperty 'HKCU:\Software\Microsoft\Internet Explorer\Desktop\General' WallpaperSource
but it only gives me the current image if there is a slideshow, and if we are using a 'Custom.theme' then
Get-ItemProperty -path 'HKCU:Control Panel\Desktop' -name 'Wallpaper'
returns TranscodedWallpaper.jpg each time, even if there is only one image left in there and no time interval. (Regardless if I use the above command or Andy's script)
I've tried running Process Monitor to figure out what windows does, and it plays a little in 'C:\Windows\Globalization\MCT\MCT-US\Wallpaper\desktop.ini' but it doesn't seem to leave any marks I can use. It helped me find
Get-ItemProperty -path 'HKCU:Control Panel\Personalization\Desktop Slideshow'
which has a Shuffle and Interval field, but neither changes when we are in a Custom theme - single image vs a Custom theme - slideshow.
I am sure I am missing very obvious (being new to playing on this end of Windows and Powershell).. any thoughts?
Took a while but I figured it out (or figured out a solution). If anyone else runs across this, Win 7 has an ini file:
C:\Users\[...]\AppData\Roaming\Microsoft\Windows\Themes\slideshow.ini
When there is only one picture in the 'slideshow' this file becomes empty, so using .WallpaperSource is the correct background image. When there are multiple images in a slideshow then this file has content (the information on transitioning the background) so even if .WallpaperSource seems like the right image, it will likely change over time based on the interval.
In short, from what I can see (and until I run across the situation that breaks this rule and I go back to the drawing board), to see if you have a slideshow you:
$doesFileExist = Test-Path $PATH_TO_THE_INI_FILE
if ($doesFileExist){
$iniContent = Get_Content $PATH_TO_THE_INI_FILE
if ($iniContent){
# This was a slideshow
}
else {
# This does not seem to be a slideshow
}
}
(This is of course only for the build in Windows 7 functionality, no idea how it would react to all the custom code and apps out there). And the Win 8 solution is up in the initial question

Make AutoHotKey ignore Alt as menu key

I'm trying to use autohotkey to simulate elements of Mac keyboard on a PC (Windows) keyboard. My muscle memory reaches for the Command key for simple tasks like copying and pasting, so I'd like to remap the left alt+letter key combinations to appropriate ctrl+letter.
<!c::Send ^c
Most of the time it works fine, except for part of the time in IE and Office applications. When pressing the left Alt, it screws with the office ribbon/menus (i.e. the menu bar shows in IE, or ribbon letters start appearing in Office 2010), and the ctrl+letter combination fired does not reach destination.
I've read the AHK FAQ + forums, tried a couple of options with UP and $ modifiers to the hotkey, but it did not fix the problem. Any ideas?
This prevents the left-hand side Alt key from activating the menu bar for most applications (under Windows 7 and AutoHotkey 1.1.11.01):
~LAlt Up:: return
It doesn't work with Internet Explorer but I don't use IE often anyway. :)
BTW, I also killed the annoying start menu popup via:
~LWin Up:: return
~RWin Up:: return
Use
LAlt::LCtrl
put it into a ahk file compile it and run .exe with administrator rights
right click -> Run as administrator
I tested it on Windows 7 and it works, LAlt no longer fires anywhere and it is completely replaced with LCtrl.
Just checked this on Win-7 and it works, even with IE.
00 00 00 00 00 00 00 00 03 00 00 00 1d 00 38 00 38 00 1d 00 00 00 00 00 00
Here is the SwapCtrlAlt.reg text.
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]
"Scancode Map"=hex:00,00,00,00,00,00,00,00,03,00,00,00,1d,00,38,00,38,00,1d,00,\
00,00,00,00,00
It sounds like you need the wildcard modifier. This will make it so if your hotkey is pressed in conjunction with another key. The mapping still works. Give the following a try:
*LAlt::LCtrl
This will make Alt fire Ctrl for any Alt+Key combination.
Use
LAlt::LCtrl
this will replace LAlt with LCtrl
you could also swap the two buttons.
Something like:
LAlt::LCtrl
LCtrl::LAlt
In the limited testing I did, it works, but you might need to relearn some of your window key shortcuts. It basically just swaps the two buttons.
I am afraid that IE behaves differently from most other applications.
You could try the instructions below. This is NOT autoHotKey but regedit changes.
B.t.w. I had checked to see if ScanCodes would work (SC38 for LAlt), but IE still ignores that.
Not sure if this works in Vista/Win7/8, but worth a look.
http://www.designcodeexecute.com/2006/11/04/swap-alt-and-ctrl-keys-in-windows-xp/

Is it possible to change the default value of $profile to a new value?

So I would rather not create my profile file here:
C:\Users\fmerrow\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
I mean don't get me wrong, this isn't the end of the world and I can live with it. However, I like to keep root "My Documents" reasonably lean and I really would rather not create a directory there every time I start using a new application.
I've nosed around looking to where this setting might be hidden, but so far no luck. It doesn't seem to be in the registry or any of the $PsHome files.
Do I just have to learn to live with this? . . . or is there a way to change the value of $profile that will "stick" on this system for all time? That is, to change the "default value" of $profile?
The best I've thought of so far, is to ignore $profile and instead put some code in $profile.AllUsersAllHosts to source/execute my file from where I want to put it instead of from the default $profile location.
Comments and/or other suggestions welcomed.
Frank
The only thing I can think of is "dot sourcing" your profile at the powershell invocation.
For example:
powershell -noprofile -noexit -command "invoke-expression '. ''C:\My profile location\profile.ps1''' "
By changing the script that invoke-expression command points to you can place your "profile" anywhere you'd like. Then, create shortcut that launches PowerShell and set the target to the above command.
You can change your $Profile.CurrentUser* paths by changing your personal folder path Environment.GetFolderPath(Environment.SpecialFolder.Personal)
Either via regedit
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
Under the Name column select Personal and chage the value to where you want your profile.
Or via PowerShell
New-ItemProperty
'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders'
Personal -Value 'Your New Path Here' -Type ExpandString -Force
You have to reboot for this to take effect.
You can also put your profile file here
C:\Windows\System32\WindowsPowerShell\v1.0\profile.ps1
If you want to have a separated location for all your profiles and scripts, you can modify your profile.ps1 file above as
$profile = "NewLocation\profile.ps1"
. $profile
Make sure what type of profile you use, see details here
https://technet.microsoft.com/en-ca/library/dd819434.aspx
Try junctions by running this command in powershell:
cmd /c mklink /J c:\Users\Name\Documents\WindowsPowerShell\ d:\Powershell\Engine\Profile\
For more information about junctions see here.
I think your solution to source your "new" profile in the existing profile is probably as good as you're going to get.
This solution is inspired by RootLoop's answer:
Access your profile by navigating to its location defined by $PROFILE. (For me, that location happened to be C:\Users\<username>\Documents\PowerShell\Microsoft.PowerShell_profile.ps1. Then, go ahead and move the contents of your customized profile to wherever you want it to be, (C:/NewLocation/profile.ps1, let's suppose). Replace the original profile's contents (the file C:\Users\<username>\Documents\PowerShell\Microsoft.PowerShell_profile.ps1) with the text:
$profile = "C:\NewLocation\profile.ps1"
. $profile
Remember that the profile is just a script that is run as soon as you open powershell. This script above will first set $profile to the new location, so any references to the $profile variable will still work as if you moved it. The next line of code will invoke the new profile with syntax that is called dot sourcing. Effectively, the . $profile line is just running your new profile code.
Before that will work on your system, you may have to loosen your execution policy. See https://superuser.com/questions/106360/how-to-enable-execution-of-powershell-scripts for details on that.
Next, you can reduce the clutter in your My Documents directory by hiding the Powershell folder. Simply right click on the folder, select "properties", and under the general tab, select "hidden". And voila! - You have effectively created the illusion that you moved your profile location, without having to do much tinkering with system settings!
According to Scripting Guy article Understanding the Six PowerShell Profiles, $profile is expanded from $PsHome\Microsoft.PowerShell_profile.ps1; $pshome is the powershell installation directory and a read-only variable; according to a post on this thread, Microsoft tells us this cannot be changed.
This might be more of a workaround, but what I did was create a symbolic link copy of the WindowsPowerShell directory in the location PowerShell was looking at. This is more of a bandaid technique though.

How can I control a window's 'state' (maximize, minimize, restore) with a powershell script?

I need to be able to run this script and have it maximize a window if it isn't already maximized. And restore the window if it isn't. The window is just whatever is currently active so no need to get specific (but bonus points if you do) 8O)
I plan on activating it from a short-cut keystroke.
It does need to run under PS v1 (I know, I know, but I don't have control over the version at work).
Thanks.
Clarification: Since I cannot update PS to v2, I can't install separate applications either. Is there a way to do this with native commands?
Set-WindowPosition – set any one of (or all of) top, left, width, height on a window … or maximize/minimize/restore
Get-WindowPosition – get the position (kind-of redundant, actually, since the Window object has it’s position as a property)
http://wasp.codeplex.com/
This works:
(Get-Host).UI.RawUI
$a = (Get-Host).UI.RawUI
$a.BackgroundColor = "white"
$a.ForegroundColor = "black"
$size = (Get-Host).UI.RawUI.WindowSize
$size.Width = 80
$size.Height = 30
(Get-Host).UI.RawUI.WindowSize = $size
But this doesn't:
$position = (Get-Host).UI.RawUI.Windowposition
$position.X = 0
$position.Y = 30
(Get-Host).UI.RawUI.Windowposition = $position
Just in case you are doing this on your own or your workplace allows open source modules:
I used the UIAutomation powershell module (http://uiautomation.codeplex.com/).
Here is my powershell script to move a window to another monitor(which required going to normal and maximize modes).
Start-Process Chrome
##orient new chrome window in full screen on left monitor
#get reference to new chrome window
$nextWin = Get-UiaWindow -Name "*New Tab*"
#transform window to "restore" mode (make sure window is not maximized)
$nextWin.SetWindowVisualState("Normal")
#move window to left monitor
$nextWin.Move(-1920,0)
#maximize window
$nextWin.SetWindowVisualState("Maximize")
Of course the main takaways here are:
$nextWin.SetWindowVisualState("Normal")
$nextWin.SetWindowVisualState("Maximize")
$nextWin.SetWindowVisualState("Minimize")
And there are quite a few options for getting a window ($nextWin) including a Get-UiaActiveWindow