Home > Software engineering >  Running SendKeys commands from a .lnk (shortcut) with powershell doesn't work
Running SendKeys commands from a .lnk (shortcut) with powershell doesn't work

Time:08-29

I'm playing around with SendKeys and powershell. I tried to close the active window with SendKeys (ALT F4) after running a shortcut. I got this working with adding the following command to the Target field of a Windows shortcut(.lnk):

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -File "C:\Users\user\Documents\TEST\test.ps1"

Code in test.ps1:

(New-Object -ComObject Wscript.Shell).SendKeys("%{F4}")

When I run the shortcut the active windows closes. Now I wanted to make this work without .ps1 script. I tried to run the powershell command from the Target field of the shortcut and that didn't work.

The commands I added to the shortcut Target field that didn't work:

$ C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe $wshell = New-Object -ComObject wscript.shell; $wshell.SendKeys("%{F4}")
$ C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe "$wshell = New-Object -ComObject wscript.shell; $wshell.SendKeys("%{F4}")"
$ C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe (New-Object -ComObject Wscript.Shell).SendKeys("%{F4}")
$ C:\Windows\System32\cmd.exe /c powershell.exe -noprofile -executionpolicy bypass $wshell = New-Object -ComObject wscript.shell; $wshell.SendKeys("%{F4}")
$ C:\Windows\System32\cmd.exe /c powershell.exe -noprofile -executionpolicy bypass "$wshell = New-Object -ComObject wscript.shell; $wshell.SendKeys("%{F4}")"
$ C:\Windows\System32\cmd.exe /c powershell.exe -noprofile -executionpolicy bypass (New-Object -ComObject Wscript.Shell).SendKeys("%{F4}")

What I'm doing wrong in the commands above? I need to use a different syntax when I run powershell commands from Shortcuts?

CodePudding user response:

The issue here is that the commands you are attempting to execute aren't being passed to the powershell exe correctly.

You can test your statements by just executing them in a powershell session as you can nest powershell sessions. Your examples would yield some errors and so you know it wont work in the shortcut.

The below works for me in the terminal and also in the shortcut field:

powershell.exe -command "$wshell = New-Object -ComObject wscript.shell; $wshell.SendKeys('%{F4}')"

and to give an example for the rest of your attempts (full path removed for brevity)

powershell.exe -command "(New-Object -ComObject Wscript.Shell).SendKeys('%{F4}')"
powershell.exe -noprofile -executionpolicy bypass -command "$wshell = New-Object -ComObject wscript.shell; $wshell.SendKeys('%{F4}')"

CodePudding user response:

What I'm doing wrong in the commands above?

  • You're calling powershell.exe, the Windows PowerShell CLI, from outside PowerShell, such as in the no-shell context in which shortcut-file command lines are executed.

    • For troubleshooting such command lines, use -noexit as the first powershell.exe parameter in order to keep the resulting PowerShell session open, which allows you to see any error message.
  • The implied CLI parameter of powershell.exe is -Command (-c), which treats all subsequent arguments as tokens of a piece of PowerShell code to execute.

    • However, any unquoted " characters are stripped beforehand, during PowerShell's command-line processing.

    • In order to pass " characters through as part of a PowerShell command being passed to the PowerShell CLI via (possibly implied) -Command (-c), you need to escape them as \" (sic)

Additionally, for full robustness, it is best to pass the entire PowerShell command inside a single (unescaped) "..." string.

Therefore:

powershell.exe -noprofile -executionpolicy bypass "(New-Object -ComObject Wscript.Shell).SendKeys(\"%{F4}\")"

However, given that, in the context of your PowerShell command, a single-quoted string ('...') to represent the key combination %{F4} argument will do (and is arguably preferable, given that you only need "..." quoting in PowerShell for string interpolation), you can simplify to:

powershell.exe -noprofile -executionpolicy bypass "(New-Object -ComObject Wscript.Shell).SendKeys('%{F4}')"
  • Related