how to get window os system idle time using ruby? - ruby

I have a ruby script. I want to know how long the system has been idle (i.e. no user interaction - the time screen saver activation is based upon).
I believe I can do this in ruby via win32api using user32.dll and GetLastInputInfo, but I can't figure out how... can anyone can help me?
.

Here is a sample that calls GetLastInputInfo. I did not study that API, though, to see if it is really giving you the information you are wanting.
require "Win32API"
api = Win32API.new( 'user32', 'GetLastInputInfo', ['P'], 'I')
# match the structure LASTINPUTINFO. First 4 byte int is size of struct
s = [8, 0].pack('l*')
api.call( s )
a = s.unpack('l*')
puts a

It would appear what you want to do has been done for Linux:
http://coderrr.wordpress.com/2008/04/20/getting-idle-time-in-unix/
But as for windows the nearest thing I could find is for C#... I don't have a windows machine to hack with but it could well give you an indication as to how GetLastInputInfo can be interacted with:
http://dataerror.blogspot.com/2005/02/detect-windows-idle-time.html

On the basis of the answer from Mark Wilkins, I created some script to log the idle time of a user.
https://gist.github.com/Largo/11216868

Related

How to route Matlab input to specific DOS cmd input?

I have a Matlab script that uses the dos command to open an exe. This exe pauses awaiting user input. For this project I need everything to be scripted and dynamic, so matlab has to be able to continue running its script, dynamically determine what to input to the running exe, and then input it.
So far, I have been able to get the exe to run in the background and let the matlab script continue by using dos('test.exe &'), but I cant get then get matlab to send inputs to the running exe. I have tried batch files and I still run into the same issue, which is how do I automate the sending of inputs to the cmd line when the cmd line exe running is paused awaiting user input?
My best guess would be that I need to reroute the standard output of matlab to the standard input of a specific, already open instance of cmd, but I have no idea how to do that and have been unable to find anything so far on the internet. Any insight would be greatly appreciated, thanks.
There is a way. It's just not elegant.
When you call a program with &, its window appears in the foreground and has focus (at least on my system). So you can send it keyboard events from Matlab using the java.awt.Robot class.
If you need to automatize the conversion from characters to key presses, you probably need a big switch statement along these lines. The following example defines the events manually, which is only practical for small inputs.
robot = java.awt.Robot;
dos('copy con &'); % open MS-DOS Window that will just echo the input text
pause(1) % allow some time for the external program to start up
robot.keyPress(java.awt.event.KeyEvent.VK_SHIFT);
robot.keyPress(java.awt.event.KeyEvent.VK_H);
robot.keyRelease(java.awt.event.KeyEvent.VK_H);
robot.keyRelease(java.awt.event.KeyEvent.VK_SHIFT);
robot.keyPress(java.awt.event.KeyEvent.VK_E);
robot.keyRelease(java.awt.event.KeyEvent.VK_E);
robot.keyPress(java.awt.event.KeyEvent.VK_L);
robot.keyRelease(java.awt.event.KeyEvent.VK_L);
robot.keyPress(java.awt.event.KeyEvent.VK_L);
robot.keyRelease(java.awt.event.KeyEvent.VK_L);
robot.keyPress(java.awt.event.KeyEvent.VK_O);
robot.keyRelease(java.awt.event.KeyEvent.VK_O);
robot.keyPress(java.awt.event.KeyEvent.VK_SHIFT);
robot.keyPress(java.awt.event.KeyEvent.VK_1);
robot.keyRelease(java.awt.event.KeyEvent.VK_1);
robot.keyRelease(java.awt.event.KeyEvent.VK_SHIFT);
robot.keyPress(java.awt.event.KeyEvent.VK_ENTER);
robot.keyRelease(java.awt.event.KeyEvent.VK_ENTER);
Here's an example run:
Unfortunately there is no way to do what you are describing.
The fact that the external program pauses and awaits for an input is a serious challenge: for Matlab, there is just a program running in the background, and it has no way to "know" that this program is awaiting for an input at a given moment.
Then, another issue is that there is no "Matlabish" way to send a command to a running thread send in the background. edit The solution proposed by Luis is ugly but works for this.
If you can modify the external program, then you can certainly avoid the problem by defining a different protocol for input tranfer, like TCP/IP. But it's not a general answer and I guess you don't have such a possibility.
You could try to use Sikuli for this, if you are really desperate.
Thanks to the wonderful explanation by Luis Mendo, I have quickly put together a function that takes a string input and outputs the proper robot commands. It works for me!
function typeStringOut(robot,text)
keyMatch = {};
keyMatch(1,:) = {'`','-','=',',','.','/',';','[',']','\'};
keyMatch(2,:) = {'~','_','+','<','>','?',':','{','}','|'};
keyMatch(3,:) = {'BACK_QUOTE','MINUS','EQUALS','COMMA','PERIOD','SLASH','SEMICOLON','OPEN_BRACKET','CLOSE_BRACKET','BACK_SLASH'};
numKeyMatch = {};
numKeyMatch(1,:) = {'1','2','3','4','5','6','7','8','9','0'};
numKeyMatch(2,:) = {'!','#','#','$','%','^','&','*','(',')'};
for i=1:length(text)
if isstrprop(text(i),'alpha')
if isstrprop(text(i),'upper')
robot.keyPress(java.awt.event.KeyEvent.VK_SHIFT);
end
eval(['robot.keyPress(java.awt.event.KeyEvent.VK_',upper(text(i)),');']);
if isstrprop(text(i),'upper')
robot.keyRelease(java.awt.event.KeyEvent.VK_SHIFT);
end
elseif isstrprop(text(i),'digit')
eval(['robot.keyPress(java.awt.event.KeyEvent.VK_',text(i),');']);
elseif isstrprop(text(i),'wspace')&&strcmp(text(i),' ')
eval('robot.keyPress(java.awt.event.KeyEvent.VK_SPACE);');
elseif isstrprop(text(i),'punct')||isstrprop(text(i),'graphic')
switch text(i)
case {'`','-','=',',','.','/',';','[',']','\'}
matchIdx = strcmp(keyMatch(1,:),text(i));
eval(['robot.keyPress(java.awt.event.KeyEvent.VK_',keyMatch{3,matchIdx},');']);
case {'~','_','+','<','>','?',':','{','}','|'}
robot.keyPress(java.awt.event.KeyEvent.VK_SHIFT);
matchIdx = strcmp(keyMatch(2,:),text(i));
eval(['robot.keyPress(java.awt.event.KeyEvent.VK_',keyMatch{3,matchIdx},');']);
robot.keyRelease(java.awt.event.KeyEvent.VK_SHIFT);
case {'!','#','#','$','%','^','&','*','(',')'}
robot.keyPress(java.awt.event.KeyEvent.VK_SHIFT);
matchIdx = strcmp(numKeyMatch(2,:),text(i));
eval(['robot.keyPress(java.awt.event.KeyEvent.VK_',numKeyMatch{3,matchIdx},');']);
robot.keyRelease(java.awt.event.KeyEvent.VK_SHIFT);
otherwise
error([text(i),' is unknown character']);
end
elseif strcmp(text(i),'<')||strcmp(text(i),'>')
robot.keyPress(java.awt.event.KeyEvent.VK_SHIFT);
matchIdx = strcmp(keyMatch(2,:),text(i));
eval(['robot.keyPress(java.awt.event.KeyEvent.VK_',keyMatch{1,matchIdx},');']);
robot.keyRelease(java.awt.event.KeyEvent.VK_SHIFT);
else
error([text(i),' is unknown character']);
end
end
robot.keyPress(java.awt.event.KeyEvent.VK_ENTER);
robot.keyRelease(java.awt.event.KeyEvent.VK_ENTER);
end

Go/Golang Trying to get window information via syscall. (As in EnumWindows, etc.)

Thanks for reading and any comments you may have.
Context:
I've been a UI/R&D dev (prototyping, etc.) for over 20 years and just started server/backend development.
I'm very new to Go - less than 2 months - and have 1) run through much of GoByExample and 2) set up a primitive, working web server on an Amazon EC2 instance.
I created a UI in another language which serves a HUD (Heads Up Display) for another 3rd party application - a game which spawns multiple windows. (Think multiple poker tables running in multiple windows.)
I connected the HUD to a Go client I created.
I use Go to grab OS information because of limitations in the first language.
I want to continue to use Go because I really enjoy it.
I'm on a Windows 7 machine.
Goal(s):
Big picture: When a User moves a window, I want the HUD to move with it.
To do this I need information about the main windows whos WindowText starts with "Game".
The ideal would be something like this:
windows: [ { windowHwnd:hwnd, windowText:windowText, windowX:x, windowY:y, windowWidth:width, windowHeight:height },
.
.
.
{ windowHwnd:hwnd, windowText:windowText, windowX:x, windowY:y, windowWidth:width, windowHeight:height } ]
Steps I've taken:
I've grabbed and modified github.com/AllenDang/w32 which I think formats syscall for Go.
When I need an unlisted function from user32.go, I add it.
Tried using GetForegroundWindow and GetWindowText with result, then GetWindow( hwnd, previous ) to just walkthrough everything
Read through:
syscall docs (http://golang.org/pkg/syscall/)
syscall/dll_windows.go
syscall/env_windows.go
syscall/exec_windows.go
syscall/syscall.go
syscall/syscall_windows.go
syscall/syscall_windows_386.go
syscall/syscall_windows_amd86.go
syscall/syscall_windows_test.go
syscall/zsyscall_windows_386.go
syscall/zsyscall_windows_amd86.go
syscall/ztypes_windows.go
syscall/ztypes_windows_386.go
syscall/ztypes_windows_amd86.go
Every potential Window Function at Windows Dev Center
Searched StackExchange, Google, DuckDuckGo
I can see there's something (TestEnumWindows)
line 125 in runtime/syscall_windows_test.go (http://golang.org/src/pkg/runtime/syscall_windows_test.go)
Though this function doesn't exist in syscall_windows_test.go
Questions:
Better solution? In my ignorance I could easily be overlooking some method like: GiveGeoffreyExactlyWhatHeWants()
Am I in the right ballpark?
Is this doable in Go?
What's the right direction to head?
Is this something anybody else needs?
It is not clear what you want , but perhaps http://play.golang.org/p/YfGDtIuuBw will help. It uses EnumWindows to find window with a particular title.
Alex

How to check Matplotlib's speed in Xcode and increase performance?

I'm running into some considerable speed bottlenecks with a Python-Matplotlib-Xcode combination. I know some immediate responses will probably ask "Why are you doing python stuff in Xcode, just man up and use vim" --> I like the organizing ability and the built in version control, it makes elements of my work easier to deal with.
Getting python to run in xcode in the first place was a bit more tricky than I had hoped, but its possible. Now I have the following scenario:
A master file, 'main.py' does all the import stuff for me and sets up some universal formatting to make all the figures (for eventual inclusion in my PhD thesis) nice and uniform. Afterwards it runs a series of execfile commands to generate whichever graphics I need. Two things I can think of right off the bat:
1) at the very beginning of main.py after I import all the normal python stuff you tend to need, I call a system script which checks whether a certain filesystem is mounted. I keep all my climate model data on there since my local hard drive is too small to deal with all of it at once. Python pauses itself and waits for the system to do its thing, but once the filesystem has been found, it keeps going. Usually this only needs to happen once in the morning when I get to work, or if the VPN server kicked me off for whatever reason. (Side question, it'd be cool to know if theres a trick to automate an VPN login to reconnect as soon as it notices its not connected)
2) I'm not sure how much xcode is using on its own. running the same program from terminal is (somewhat) faster. I've tried to be memory conscience and turn off stuff I don't need while running the python/xcode combination.
Also, python launches a little window whenever I call plt.show(), this in itself takes time, I've considered just saving them as quick png files and opening them with some other viewer, although I guess that would also have to somehow take time to open up. Given how often these graphics change as I add model runs or think of nicer ways of displaying the data, it'd be nice to not waste something on the order of 15 to 30 minutes (possibly more) out of the entire day twiddling my thumbs and waiting for a window to pop up.
Benchmark it!
import datetime
start = datetime.datetime.now()
# your plotting code
td = datetime.datetime.now() - start
print td.total_seconds() # requires python version >= 2.7
Run it in xcode and from the command line, see what the difference is.

Playing Sound in Perl script

I'm trying to add sound to a Perl script to alert the user that the transaction was OK (user may not be looking at the screen all the time while working). I'd like to stay as portable as possible, as the script runs on Windows and Linux stations.
I can
use Win32::Sound;
Win32::Sound::Play('SystemDefault',SND_ASYNC);
for Windows. But I'm not sure how to call a generic sound on Linux (Gnome). So far, I've come up with
system('paplay /usr/share/sounds/gnome/default/alert/sonar.ogg');
But I'm not sure if I can count on that path being available.
So, three questions:
Is there a better way to call a default sound in Gnome
Is that path pretty universal (at least among Debain/Ubuntu flavors)
paplay takes a while to exit after playing a sound, is there a better way to call it?
I'd rather stay away from beeping the system speaker, it sounds awful (this is going to get played a lot) and Ubuntu blacklists the PC Speaker anyway.
Thanks!
A more portable way to get the path to paplay (assuming it's there) might be to use File::Which. Then you could get the path like:
use File::Which;
my $paplay_path = which 'paplay';
And to play the sound asynchronously, you can fork a subprocess:
my $pid = fork;
if ( !$pid ) {
# in the child process
system $paplay_path, '/usr/share/sounds/gnome/default/alert/sonar.ogg';
}
# parent proc continues here
Notice also that I've used the multi-argument form of system; doing so avoids the shell and runs the requested program directly. This avoids dangerous bugs (and is more efficient.)

Usage frequency of windows application

I have a homepage need to count the usage frequency of Notepad or Calc application. Is there any Windows API that I can know the usage frequency of windows application?
No. But you can write a service that will check applications in memory and do appropriate calculations. Few links:
Windows Services Programming
Simple Windows Service Sample
Also, shell variant from bua is quite ready solution. You just need some parsing and updating the counter (not necessary in the database).
I don't know about one, but You could quite easily achieve that by:
ex:
using
cmd.exe -> tasklist
apply each 10 sec. (that would not load the CPU) - one good solution is to use python scheduler.
import sched, time
from subprocess import *
s = sched.scheduler(time.time, time.sleep)
def get_task():
f=open("log",'wt')
p=Popen("tasklist",stdout=f)
p.terminate()
p.close()
def analise_logs():
# do some analise here
def print_some_times():
while(1):
print time.time()
s.enter(5, 1, get_tasks, ())
analise_logs()
s.run()
do some awk (if you have cygwin), or powershell awk like processing on that file.
Count processes which interest you. Write result to another file with updated infos.
Take a look at my answer to How Do I Stop An Application From Opening and use the same technique. In essence when the application is launched your program is run and you can log any information that you require and then open the app.

Resources