PowerShell progress bar for file download when using PS2EXE - winforms

TL;DR: Need better way to implement progressbar for Powershell File download.
I have a .PS1 script with a GUI that I converted to a EXE using PS2EXE. I have a piece of code that downloads a large zipfile (~4GB) from the internet.
Start-BitsTransfer -Source http://speedtest.tele2.net/100MB.zip -Destination .\100MB.zip
Problem:
When its a PS1 file, output looks okay. Performance is great, user can close window to cancel the progress. However, when converting to PS2EXE, user cannot cancel the command (there is 'close window' or cancel button. And MainForm is unresponsive till command is complete or fails). Additionally, there is no way to add ETA using Bits-transfer, especially with PS2EXE.
PS2EXE is compiled using -noconsole -nooutput -noError because I dont want the output on the main script.
For a large file (4GB), it can take anywhere from 2-20mins, depending on internet speeds. I'd like to implement a solution that can:
Implement a cancel button/close window
I get to keep the progressbar
Has to be quick (Invoke-WebRequest is too slow, bits-transfer and WebClient is fast)
Optional: gives option to add additional output (ETA information in seconds)
What I've tried so far:
Invoke-WebRequest/Invoke-RestMethod (too slow because of the way it implements the progress bar)
WebClient.Downloadfile($url, $outfile) (cannot easily implement progressbar)
start-process -PassThru -wait powershell {Start-BitsTransfer -Source http://speedtest.tele2.net/100MB.zip -Destination .\100MB.zip} to execute a new powershell process to execute the bits-transfer with progressbar (need a more elegant solution if there is one. This is currently the best implementation I have)
By more elegant I mean using a (PS2EXE) GUI instead of a powershell window.
Bonus question: How do I get the ETA (00:00:10 sec of 00:02:20 sec) information from bits-transfer?

Related

Simple batch file with message

I've got a very simple batch file that deletes all files within a specified folder. It's only a single line so it executes very quickly.
To prevent users from saying its not working or clicking a dozen times, I'd like it to pop up with a simple "done" message for a few seconds before vanishing.
I've done a bit of looking around, and it seems there are/were some easy solutions, but I'm a little confused by which are still valid (some are for previous versions of Windows - we're using W10) - I also wasn't sure if the existing solutions could be dumped into the same .bat file.
If you couldn't tell, I've never written a .bat file before and I'm entirely unfamiliar with it.
Try using powershell MessageBox:
%windir%\System32\WindowsPowerShell\v1.0\powershell.exe -Command "& {Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.MessageBox]::Show('Done.', 'Message', 'OK', [System.Windows.Forms.MessageBoxIcon]::Information);}"
%windir%\System32\timeout.exe /T 2 /NOBREAK >nul
exit
Paste this code to the end of your batch file.

how to switch browser tabs using batch

I have created two independent batch files. Both open web browsers. One opens Firefox and the other Opens Edge. Both batches are opening multiple tabs in their respective applications. How do I write a batch to pass through the Control + Tab keys in batch at the end of my file to go back to the first tab?
Can this be done with Edge and Firefox? Can they be written the same way?
I don't need the tabs to refresh upon the switch.
I've tried this for Edge,
#echo off
start microsoft-edge:"https://stackoverflow.com"
start microsoft-edge:"https://google.com"
timeout 2
$wshell=New-Object -ComObject wscript.shell;
$wshell.AppActivate('microsoft-edge'); # Activate on EDGE browser
$wshell.SendKeys('^+{TAB}'); # CONTROL+SHIFT+TAB
..to no prevail. Yes, the batch starts and opens Edge and applies the two addresses to two tabs but I can not figure out how to SendKeys to the application.
Any Tips or Pointers will be greatly appreciated. Thanks in advance.
I've tried many ways to send keys combination but the combination of ^+{TAB} seems always not work. I find a software called AutoHotkey which can achieve your goal.
You can first download the software and create a autohotkey script file named test.ahk, with following content:
send ^{TAB}
exit
Then run the test.ahk in bat file:
#echo off
start microsoft-edge:"https://stackoverflow.com"
start microsoft-edge:"https://google.com"
timeout 2
$wshell=New-Object -ComObject wscript.shell;
$wshell.AppActivate('microsoft-edge');
"C:\Program Files\AutoHotkey\AutoHotkey.exe" "C:\Users\username\Desktop\test.ahk"
Please notice to replace the path with your own path. I've tested it and this could be a workaround.

Open a HTTPS URL under unattended batch control

My problem is that I need to send a shutdown command to my NAS when the UPS tells my home server that there's a power cut. I want to do this by using the (Windows 10 Home) PC server's closedown notification, which can trigger a batch file as part of the closedown event, rather than by using extra hardware. I have determined that opening a particular URL will cause the NAS to close down gracefully.
https://192.168.1.10/get_handler?PAGE=System&OUTER_TAB=tab_shutdown&INNER_TAB=NONE&shutdown_option1=1&command=poweroff&OPERATION=set
The problems seem to be related to trying to bypass dialogues that result in the browser. First it asks for credentials. I can bypass this one by including them in the URL call, like this:
start "" "C:\Program Files\Mozilla Firefox\firefox.exe"
"https://username:password#192.168.1.10/get_handler?PAGE=System&OUTER_TAB=tab_shutdown&INNER_TAB=NONE&shutdown_option1=1&command=poweroff&OPERATION=set"
Now it pops up a dialogue asking me to confirm that I want to log on as "username", again defeating my attempt to make this run unattended (I might be anywhere when a power cut strikes). Is there a way around this? Just FYI, I gave up trying to work with Microsoft Edge as it kept cutting the URL paramaeters into pieces by inserting spaces everywhere. It also kept manually complaining about the security certificate each and every time I tried it. I think I'll have the same confirmation request problems with that browser too. So I need a way to surpress all these dialogues and just make the URL call. Any thoughts please?
The lack of any answers after this question had been posted over 24 hours told me that this was a tricky one & kept me trying. After I tried everything I could think of to solve it with Window's own tool set and finding nothing worked I realised I'd need something additional to solve the problem. Finally I gave up and installed the free Autohotkey and wrote a script to do the entire job, including handling the dialogue boxes. Once it was all working I made an executable from the script for convenience so I can easily call it from the close down batch (.bat) file. This solution works. Here is the script for anyone who needs to solve a similar problem:
> runWait, C:\Program Files\Mozilla Firefox\firefox.exe
> https://admin:password#192.168.1.10/get_handler?PAGE=System&OUTER_TAB=tab_shutdown&INNER_TAB=NONE&shutdown_option1=1&command=poweroff&OPERATION=set
>
> #Persistent SetTimer, MsgBoxCheck, 3000 return
>
> MsgBoxCheck: If WinExist("ahk_class MozillaDialogClass") {
> SetControlDelay -1 ControlClick, , Confirm, SetTimer,
> MsgBoxCheck, off exitApp } else { SetTimer, MsgBoxCheck, off
> MsgBox, 4, , Debug - No Confirm Window Found. exitApp } return
Please note, to make this work with non-Mozilla programs you will need to change the ahk_class parameter. I suggest you use Windows Spy to determine the class of window you want to close. You will also need to change 'Confirm' to whatever your window's title might be.

Batch adjust times on files

I just filmed a wedding, using two different cameras, and realized after the wedding that I corrected only one camera for daylight savings time. My editing software automatically (albeit roughly) arranges the video clips on the timeline based on the time stamps in the file's properties. It would save an incredible amount of time if I could add one hour (plus/minus a couple minutes or seconds, the time synchronization was apparently not perfect) to all of the files in a given folder.
I've found some freeware online that allows me to change all of the files simultaneously, so it resets every file to have the same creation time, rather than just add some preset time to each file. I am not very apt to use or run code, so please keep that in mind when providing ideas! Any and all are greatly appreciated!
Thanks in advance!
You can use a powershell one-liner to do what you need I think.
Open a cmd console and cd into the directory containing the clips you want to modify. Then to add an hour to every file's timestamp you'd just
powershell "gci | %{ $_.LastWriteTime = $_.LastWriteTime.addHours(1) }"
You can do the same thing with .addMinutes as well if you wish. If you want to manipulate the last modified time of an individual file, instead of using Get-ChildItem | foreach (or gci | % as I have it shortened), do
powershell "$f = gi filename.ext; $f.LastWriteTime = $f.LastWriteTime.addHours(1)"
If you mess up and need to subtract hours, do .addHours(-1).
If you have questions, please bear in mind that this is a programming website. If you are uncomfortable navigating the windows file system through a cmd window or need other basic assistance, then SuperUser would probably be a more appropriate place to ask.

batch script--List of active programs via command prompt

How to find active programs through windows command line?
By active program, I mean any program that the user is using or just kept minimised. Not all running programs/processes we get when we type "tasklist".
eg: If I close google chrome, It still shows in the tasklist. But They are background processes. I don't want to list that process.
Can you use PowerShell?
If so, you could use the line below to get all the processes that don't have a window title.
It may not catch everything you want though.
Get-Process | Where {$_.MainWindowTitle -ne ''}

Resources