I am trying to write a simple shell script in powershell that opens a file in a default windows app and monitors the process to wait until the process has exited to continue. At a high level I would like to open a .mp4 file to trim it in the default windows 10 app. When manually editing the file it opens in the photos app to trim, I would like to automate the part of opening the file in the app.
Currently I'm able to monitor the photos app process and wait for the process to close using the following code:
Start-Process shell:AppsFolder\Microsoft.Windows.Photos_8wekyb3d8bbwe!App
Start-Sleep -Seconds 2
$proc = Get-Process -Name Microsoft.Photos
$proc.WaitForExit()
However I would like to start the process and pass in a filepath to open, for example:
Start-Process shell:AppsFolder\Microsoft.Windows.Photos_8wekyb3d8bbwe!App "C:\Some\Path\To\File.mp4"
If I can get the file to simply open in the photos app I can simply click the edit button manually but ideally I would be able to open the file in the edit UI like this:
Then the script would wait for the photos process to close to continue on. Does anyone have any ideas on how we can open a file in a default windows 10 app in this way from powershehll? Or if this is even possible?
Thank you!
I think you should explore the -Wait option of the Start-Process cmdlet
Start-Process "C:\Some\Path\To\File.mp4" -Wait
Related
An app I want to push to various systems (Notepad++) doesn't generate it's configuration file until after it starts, so I'd like to start the application quickly hidden in the background so that the config.xml is generated (grabbing the apps PID as it is starting), then kill the app a second later. I thought I could do this as follows:
Start-Process -WindowStyle Hidden -FilePath "C:\Program Files\Notepad++\notepad++.exe
But this does not work and the app opens normally. How can I start this app hidden in the background? Also, how can I get the PID as it is starting so that I can kill it shortly afterwards?
I don't think you can start an app like notepad++ without a window, it's a GUI application. As for the other question, you are looking for the PassThru switch. Some cmdlets do not pass the output to the pipeline if this is not specified
So you can do something like this:
$process = Start-Process -FilePath 'C:\Program Files\Notepad++\notepad++.exe' -PassThru
Stop-Process -Id $process.Id
I wrote a script that loops over a folder and converts files using WinSCP
WinSCP.exe /keygen $filePath /output=$filePathdest
The script works but leaves several WinSCP windows open stating what it completed it's task. I would like to suppress this or force PowerShell to close all of its children when finished. Is this possible?
Use winscp.com instead of winscp.exe.
winscp.com /keygen $filePath /output=$filePathdest
The winscp.com is a console application with the same functionality as winscp.exe. Being a console application it inherits the console from PowerShell and does not open its own. It also does not wait for key press when done.
I'm trying to get the handle of each windows opened by the firefox process. My use case is the following: on a computer in kiosk mode, I'm opening firefox at a specific URL with a powershell script at startup. That URL directs to an application that opens a new window that conveniently disable the use of the URL bar, preventing the user to browse the web. My problem is that the old window is still opened and I want to close it programmaticaly through that same powershell script. Although, the two windows have the exact same name so I can't use this to tell them apart.
I've tried listing the windows handles of the firefox process but it doesn't work since there is only one. I've also tried closing the main window of that process but since the pop up is coming up front, it's considered as the main window and so that is the windows that is closed.
There must be a way to select the correct window and close it because it is doable through the task manager.
edit: As a complement, I'd like to mention I tried what is mentioned in this thread but it doesn't work either.
I managed to circumvent my issue by launching firefox as a hidden window. The pop-up then comes up correctly and I'm happy with the result.
$firefox = Start-Process -FilePath "C:\Program Files (x86)\Mozilla Firefox\firefox.exe" -ArgumentList "https://myurl" -WindowStyle hidden
Start-Sleep -Seconds 2
Show-Process -Process $firefox
When you're in file explorer you can click on File > Open Windows Powershell(or its icon in the Quick Access Toolbar) to start an instance of Powershell in the directory that your file explorer is in. I would like to then automatically run a simple command in this directory and close the Powershell window after it is done.
I have tried adding my command to my Powershell Profile but it executes before the path variable has been set and it runs with $pwd being equal to C:\Users\MyUsername (my home directory) or C:\WINDOWS\system32 (seems to be a race condition of some sort, no idea why it does one or the other). To the best of my understanding this is because the file explorer "open in powershell button" opens powershell and THEN cd's to the directory I was in in file explorer. So when the profile.ps1 is ran it is using the only directories it knows if since the cd call hasn't been made yet. This is similar to running the command start powershell.exe in cmd vs start powershell.exe -command "cd 'C:\wherever'". The former correctly runs my profile command while the latter uses the current directory of cmd and not the C:\wherever.
So, obviously the $pwd variable is being assigned at different times in the case of opening it from cmd and opening it from file explorer. Is there some way to delay the execution of a command in the profile until after the shell has fully loaded? Simply sleeping the script doesn't help.
Alternatively, if anyone knows how to edit the registry so that I can change the behavior of clicking File > Open Windows Powershell (since it must have access to some variable storing the current directory and I assume it calls the Powershell executable with this variable as an argument being cd'd to), that would work too.
Then again I could be incredibly naive about how File > Open Windows Powershell and the Powershell instantiation process works.
Any help is greatly appreciated, thank you!
I figured it out in the most hacky, gross way ever, but without easy access to Windows internals this is the only working method I could find. I set up my powershell profile to make my window title my prompt like so:
function Prompt
{
$host.ui.RawUI.WindowTitle = $(get-location)
“PS> “
}
Then I set up a task in the Task Scheduler that was triggered by powershell reaching its prompt (there are 3 possible hooks, when the console is starting up, when it starts an IPC listening thread, and when the console is ready for input). I used the Event Viewer to do this (I was going to post screenshots but I don't have 10 reputation yet).
Then, I set the action on this task to run the script shown below, which reads from the window title of my first instance of powershell
Start-Sleep -s 1
$A = Get-Process -Name powershell | Where-Object -FilterScript {$_.Id -ne $PID}
$B = $A.MainWindowTitle
& C:\Program` Files\MyProgram\MyProgram.exe "$B"
stop-process -Id $A.Id
stop-process -Id $PID
This whole menagerie of events properly runs my program with the current file explorer directory as an argument (and then closes powershell) when I click the little powershell icon on the quick access toolbar in file explorer.
Found a much cleaner and faster way to do this. All I had to do was set up my profile to look like this, no tasks or second instance of powershell required
function Prompt
{
& C:\Program` Files\MyProgram\MyProgram.exe "$pwd"
stop-process -Id $PID
}
I have 2 scripts working, when I start them manually.
Moving mouse cursor out of Screen:
[system.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | out-null
[System.Windows.Forms.Cursor]::Position = New-Object System.Drawing.Point(1999,100)
If there is a chrome browser open with title HUD, put it to kiosk mode:
[void] [System.Reflection.Assembly]::LoadWithPartialName("'Microsoft.VisualBasic")
[Microsoft.VisualBasic.Interaction]::AppActivate("Hud - Google Chrome")
[void] [System.Reflection.Assembly]::LoadWithPartialName("'System.Windows.Forms")
[System.Windows.Forms.SendKeys]::SendWait("{F11}")
If I put them in a Scheduled Task on Windows 7 they don't work.
They work if I start a batch file calling the script file
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -noninteractive -command "&C:\Users\Miniuser\Documents\chromeHUD.ps1"
But not if I start the batch file in a Scheduled Task.
It seems in a Scheduled Task I can't acces my UI elements.
Any ideas?
When the script runs as a scheduled task, it runs in a different context/session and there is no GUI that it can "see", nor any way to interact with your existing session.
As alroc answers, it does run under another context/session.
I was not able to find any workaround to get pass this... Using pure powershell... However i was able to get the job done with wscript.
in your PS script, open your chrome with this
(new-object -com wscript.shell).run("http://localhost/",3)
It will open the default browser in full screen. i could use this with sendkeys in the task scheduler!
To run a script as a scheduled task that must interact with the desktop
You have to create a folder (or two on a 64bit-windows):
(32Bit, always) C:\Windows\System32\config\systemprofile\Desktop
(64Bit) C:\Windows\SysWOW64\config\systemprofile\Desktop