Detect when desktop is shown in a batch file - command-line

My question is, can you detect if desktop is currently visible in batch scripting(For Vista)?
The Idea is this: I'm writing a script as a prank for my friend. Some of you may heard about Weeping Angels from Doctor Who. I'm trying to make the script so that each time you return to desktop(Like minimizing something you were looking at), wallpaper changes to another
image of the angel, creating the illusion that it's moving when you aren't looking, just like in the series.
My idea for this was to detect when the desktop is not visible, and each time it became visible again, the wallpaper would cycle to the next image. Problem is, I have no idea about how to do that.
Aside from the actual question, any tips regarding the effect is appreciated.
Thank you.

Well, this isn't exactly what you asked for (not sure it is possible to detect the active window)... but it has some of the pieces you were looking for.
Basically it will change your wallpaper to one of several you have in a folder every x less than 5 minutes, where x is a random number. let me know if you have any ideas on how to change it/suggestions/questions.
#echo off
rem random number of milliseconds (0-5 minutes)
SET /A time=%RANDOM% * (300000 / 32768)
echo waiting %time% ms
PING 1.1.1.1 -n 1 -w %TIME% >NUL
echo done
rem index between 1 and 5
SET /A WALL_INDEX = %random% %% 5 + 1
rem create a folder with many wallpapers in it, and name them 1.png, 2.png, 3.png ... x.png
set WALL="C:\%WALL_INDEX%.png"
rem this is how you change the wallpaper, i stole this from some random site, but I tested it and it seemed to work... usually.
#echo off
reg add "hkcu\control panel\desktop" /v wallpaper /t REG_SZ /d "" /f
rem sets the wallpaper to the path in %WALL%
reg add "hkcu\control panel\desktop" /v wallpaper /t REG_SZ /d %WALL% /f
reg delete "hkcu\Software\Microsoft\Internet Explorer\Desktop\General" /v WallpaperStyle /f
reg add "hkcu\control panel\desktop" /v WallpaperStyle /t REG_SZ /d 0 /f
RUNDLL32.EXE user32.dll,UpdatePerUserSystemParameters

You can do it using a Java library called Sikuli which does screen pattern matching. All you do is screenshot the desktop the exact way you wish it to appear when it causes the trigger and then set the unit test to run in a 5 second loop, always checking for the desktop to appear a certain way and then trigger the wallpaper change. So, its going to take a mix of Java/JUnit/Sikuli and batch scripting. Also, you would have to get the batch script into their startup programs list somehow.

Related

Applescript - how to achieve the queue functionality

I'm writing a script to batch convert videos into h.265 format which uses repeat with to go through all videos. It works great for 3 or 4 files at the same time, but my old mac restarts when the number of videos reaches to ~50.
repeat with videofile in video_list
set filePath to POSIX path of videofile
set filePath to esc_space(filePath)
set [folderPath, filename] to split_path_name(filePath)
tell application "Terminal"
activate
do script with command "ffmpeg -hide_banner -i " & filePath & " -vcodec libx265 -tag:v hvc1 " & folderPath & filename & "_hevc.mp4; mv " & filePath & " ~/.Trash"
end tell
end repeat
Therefore, I want to use applescript to achieve the "Queue" functionality: converting limited number of videos in terminal windows (let's say 10) and monitoring if any windows finished executing, activate some remaining tasks if number of active windows is less than 10.
I did some searches and found system event can tell if apps are running, but I'm not sure how to monitoring multiple windows, especially new windows would be activated when some tasks finished.
Any suggestions is appreciated.
(shell script is also welcome if it's convenient)
After some attempts I successfully did it on my own, hope my answer would help someone who happens to have similar questions.
Since the list in AppleScript cannot be modified (correct me if I'm wrong), I have to use index to loop through my videos instead of getting the 1st item and then remove it from list:
set next_video_index to 1
The following infinite repeat loop is for monitoring the number of active terminal windows, which is counted by System Events. It is not the best solution, because System Events counts all windows including those manually opened by the user.
repeat while true
tell application "System Events"
tell application "Terminal"
set window_count to (count of windows)
end tell
end tell
if statement helps to start new converting task when the number of terminal windows doesn't reach the maximum (set to 5 in my code) and not all videos are converted.
It should be noted that ; exit at the end of terminal script, it ensures the finished task window is not messing up the window counts, but you need to change terminal preference first, see this link:
OSX - How to auto Close Terminal window after the "exit" command executed.
set task_not_finished to (next_video_index ≤ length of video_list)
if (window_count < 5) and task_not_finished then
set filePath to POSIX path of item next_video_index in video_list
set filePath to esc_space(filePath)
set [folderPath, filename] to split_path_name(filePath)
set next_video_index to next_video_index + 1
tell application "Terminal"
activate
do script with command "ffmpeg -hide_banner -i " & filePath & " -vcodec libx265 -tag:v hvc1 " & folderPath & filename & "_hevc.mp4; mv " & filePath & " ~/.Trash; exit"
end tell
end if
When the last video is converting, it's time to end the repeat loop.
if not task_not_finished then exit repeat
delay 1
end repeat

Matlab: how to select a running task/application in Windows

I want to use Matlab to automatically control the mouse and the keyboard to operate a running Task/Application. I found Matlab code which helps to show process ID (PID) of running task/application. E.g.
[status,result] = system('tasklist /FI "imagename eq excel.exe" /fo table /nh')
However, how can I select the listed task/application (like left click on the task using its PID)? Since if the wanted task/application is not selected, I may end up to controll the wrong task.
Thanks

Batch script - Record every restart in .txt file

I don't have expiriance in batch scripting bat I need help.
i need a script that will do the following:
After every windows restart, this action must be writen in one .txt file (eg. 'log_restart.txt').
My company want to know number of restarts per every computer, and they want to have recorded it in one file.
Which is the best way to do this?
Thanks
Use WMI to query the system log for the shutdown and restart event. There could be other parts of WMI thats has this info too. Use the WMI Code Creator to generate your code.
http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=8572
Class: Win32_NTLogEvent
Logfile: System
You can look over the event log with event viewer to figure out what events you want to record. Set the script to run on startup and it will write them to the file for you, recording the events. Personally, I think you should just setup a real monitoring system that will record these events to a central log. Look at syslog.
UPDATE: There is a setting that hold the last boot time...
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
Set colItems = objWMIService.ExecQuery( _
"SELECT * FROM Win32_OperatingSystem",,48)
For Each objItem in colItems
Wscript.Echo "-----------------------------------"
Wscript.Echo "Win32_OperatingSystem instance"
Wscript.Echo "-----------------------------------"
Wscript.Echo "LastBootUpTime: " & objItem.LastBootUpTime
Next

Trimming text files from command line (Windows)

I have a text file which contains several hundred lines e.g.
test.bin:8948549854958
They are all styled like the above file (xxxxxxx.xxx:xxxxxxxxxxxxxx)
Is there any way I could trim all lines e.g. take :xxxxxxxxxxxxxxx of the line, so just to leave xxxxxxx.xxx ?
Trim.bat:
#FOR /F "tokens=1 delims=:" %%G IN (%1) DO #echo %%G
Usage: trim source.txt > destination.txt
See here.
Well, since it it obvious that besides powershell, there is no 'standard' tool on windows that does this, you can roll your own:
#include <stdio.h>
#include <string.h>
main(int argc, char *argv[])
{
char s[2048], *pos=0;
while (fgets(s, 2048, stdin))
{
if (pos = strpbrk(s, ":\r\n"))
*pos='\0';
puts(s);
}
return 0;
}
Note that this has the 'side effect' of normalizing line-ends (CRLF) and not allowing lines>2048 characters in the input. However, it works equally well on all platforms and I just compiled it with winegcc (winelib), mingw (on linux) and MSVC compiler. If you want a binary, let me know
Oh, mandatory usage demo:
C:\> strip.exe < input.txt > output.txt
If you can distribute an exe with your script you could use a windows compile of 'grep' like egrep. If you want to write in script you don't have a lot of options for find replace on windows. Depending on your situation you might be able to make due with 'findstr' cmd.
Such a program already exists, although it is really buggy. This is the only program I could find that has this apparent function. I wish Notepad++ or some other text editing software would implement this feature.
For notepad++ do a find and replace. Be sure to turn on "Regular expression" in the lower left hand corner of the "Replace" tab and use this as your find criteria. (**\:.*)
I would replace it with a ")" unless you wish it removed as well. If so you might want to remove the "(" for symmetry but be sure to turn off the "Regular expression" radio button or subsequent searches will not perform as expected.
The easiest way to do this non-programmatically is to use a text editor such as TextPad or Notepad++ and do block select (have to switch modes from the menu) and select a rectangular area of text (the last twelve columns or whatever) and simply delete them. When you are in block select mode, the selection will not wrap around and grab the beginning of your lines.
For /F "tokens=1,2 delims=:" %i in (filename) do #echo %i
same as margnus1 answer but no batch file
from the command line:
FOR /F "tokens=1 delims=:" %G IN (inlist.txt) DO #echo %G >> outlist.txt
which answers the question "From Command Line"

Is there a way to run a command line command from JScript (not javascript) in Windows Scripting Host (WSH) cscript.exe?

I'm writing a JScript program which is run in cscript.exe. Is it possible to run a commnad line command from within the script. It would really make the job easy, as I can run certain commands instead of writing more code in jscript to do the same thing.
For example:
In order to wait for a keypress for 10 seconds, I could straight away use the timeout command
timeout /t 10
Implementing this in jscript means more work.
btw, I'm on Vista and WSH v5.7
any ideas? thanx!
You can execute DOS commands using the WshShell.Run method:
var oShell = WScript.CreateObject("WScript.Shell");
oShell.Run("timeout /t 10", 1 /* SW_SHOWNORMAL */, true /* bWaitOnReturn */);
If you specifically need to pause the script execution until a key is pressed or a timeout elapsed, you could accomplish this using the WshShell.Popup method (a dialog box with a timeout option):
var oShell = WScript.CreateObject("WScript.Shell");
oShell.Popup("Click OK to continue.", 10);
However, this method displays a message box when running under cscript as well.
Another possible approach is described in this article: How Can I Pause a Script and Then Resume It When a User Presses a Key on the Keyboard? In short, you can use the WScript.StdIn property to read directly from input stream and this way wait for input. However, reading from the input stream doesn't support timeout and only returns upon the ENTER key press (not any key). Anyway, here's an example, just in case:
WScript.Echo("Press the ENTER key to continue...");
while (! WScript.StdIn.AtEndOfLine) {
WScript.StdIn.Read(1);
}
thanx for the help ppl, this was my first post and stackoverflow is awesome!
Also, I figured out another way to do this thing, using the oShell.SendKeys() method.
Here's How:
var oShell = WScript.CreateObject("WScript.Shell");
oShell.SendKeys("cls{enter}timeout /t 10{enter}");
This way you can run almost every dos command without spawning a new process or window
EDIT: Although it seems to solve the problem, this code is not very reliable. See the comments below
Yes, with the WScript.Shell object.
See the docs and samples