How do I check if Windows desktop is locked - windows-7

Q: In AutoIt, how do I check if Windows desktop is locked
What I have
Let's take this example AutoIt script. It pings an URL in an indefinite loop and reports the response time in a tray tip.
While 1
$responsetime = Ping("www.google.com")
TrayTip("", $responsetime, 1)
sleep(5000)
Wend
Desired result
The new script should only ping if the desktop is not locked. But I haven't found a reliable way to check for this
While 1
$isLocked = secretFunctionIdontKnow
If $isLocked = false Then
Local $responsetime = Ping("www.google.com")
TrayTip("", $responsetime, 1)
EndIf
sleep(5000)
Wend
Hint: The function WinExist("A") seems not reliable enough because a desktop without any open windows will report back 0 (=false) even when unlocked

Based on my comments above, you can use the following secretFunctionIdontKnow ;-)
Func secretFunctionIdontKnow()
$classes = StringSplit(WinGetClassList("[ACTIVE]"), #LF, 2)
Return $classes[0] == "TaskSwitcherWnd"
EndFunc
Fortunately the program switcher hasn't got a return value of TaskSwitcherWnd, so this seems to work for me under Windows 7 Enterprise SP1 64 Bit...
Don't miss the brackets in your function call ;-)

Related

Running and giving codes to admin cmd with visual basic [duplicate]

This is my code trying to run cmd.exe with admin priviligies. However, I get the request operation requires elevation. if I run cmd.exe with "Run as Admin" through my windows, it works, however, through vb, it doesn't. This is my code.
Try
Dim process As New Process()
process.StartInfo.FileName = "cmd.exe "
process.StartInfo.Verb = "runas"
process.StartInfo.UseShellExecute = False
process.StartInfo.RedirectStandardInput = True
process.StartInfo.RedirectStandardOutput = True
process.StartInfo.RedirectStandardError = True
process.StartInfo.CreateNoWindow = True
process.Start()
process.StandardInput.WriteLine("route add 8.31.99.141 mask 255.255.255.255 " & cmdorder)
process.StandardInput.WriteLine("exit")
Dim input As String = process.StandardOutput.ReadToEnd
process.Close()
Dim regex As Regex = New Regex("(ok)+", RegexOptions.IgnoreCase) ' wa requested
' txtLog.AppendText(input)
Return regex.IsMatch(input)
Thanks.
You cannot achieve what you want.
You can use Process.Start() to launch an elevated process, but only if you UseShellExecute = true:
Dim process As New Process()
process.StartInfo.FileName = "cmd.exe "
process.StartInfo.Verb = "runas"
process.StartInfo.UseShellExecute = True
process.Start()
The reason is because you must use ShellExecute if you want to launch an elevated process. Only ShellExecute knows how to elevate.
If you specify UseShellExecute = False, then CreateProcess is used rather than ShellExecute. CreateProcess doesn't know how to elevate. Why? From the AppCompat guy:
Well, CreateProcess is really low in the layers. What can you do without the ability to create a process? Not a whole lot. Elevation, however, is a different story. It requires a trip to the app elevation service. This then calls into consent.exe, which has to know how to read group policy and, if necessary, switch to the secure desktop and pop open a window and ask the user for permission / credentials, etc. We don’t even need to take all of these features, let’s just take the dialog box.
Now, for creating a process that requires elevation, normally you just switch up APIs. The shell sits in a much higher layer, and consequently is able to take a dependency on elevation. So, you’d just swap out your call to CreateProcess with a call to ShellExecute.
So that explains how you can elevate cmd, but once you do: you're not allowed to redirect output, or hide the window; as only CreateProcess can do that:
Redirecting I/O and hiding the window can only work if the process is started by CreateProcess().
Which was a long way of saying that this guy asked the same question over here; but without the indignity of having someone close your question.
Note: Any code is released into the public domain. No attribution required.
Make it as an object and then set it to start up requiring admin priv in the application.object.settings thing.

Delphi XE8 Printe VCL and DocumentProperties strange issue

I'm using the vcl.printers unit (delphi XE8) and I'm facing an error when "talking" to a printer.
I traced into the vcl.printers and found this code (written by EMB people):
if OpenPrinter(ADevice, FPrinterHandle, nil) then
begin
if DeviceMode = 0 then // alloc new device mode block if one was not passed in
begin
DeviceMode := GlobalAlloc(GHND,
DocumentProperties(0, FPrinterHandle, ADevice, nil, nil, 0));
if DeviceMode <> 0 then
begin
DevMode := GlobalLock(DeviceMode);
if DocumentProperties(0, FPrinterHandle, ADevice, DevMode^,
DevMode^, DM_OUT_BUFFER) < 0 then
begin
GlobalUnlock(DeviceMode);
GlobalFree(DeviceMode);
DeviceMode := 0;
DevMode := nil;
end
end;
end;
if DeviceMode <> 0 then
SetPrinterCapabilities(DevMode^.dmFields);
end;
The
DocumentProperties(0, FPrinterHandle, ADevice, nil, nil, 0)
return the correct buffer size the first time (I haven't written it somewhere), then going thru the second execution time it returns 4294967295 bytes, indeed a -1 because declaration is wrong, but meanning an error.
As you can see the VCL code handle the errors very poorly since there is no error check !
But what error I have here and why ?
DocumentProperties lies in winspool.dll
To recover from it, I need to reboot the PC, but I cannot use this more than one time pass that is vey annoying for debug.
The printer is simply the "PDFcreator"
I tried with other PC and seems OK even if I run it many times.
I have also two laser network printers.
Thanks
In the past I did have the same problem with two customers. I did track it down to printers unit (printers.pas) Kind of hard to track it down without debugger on a distant computer in other part of my country.
Ok.. but I did track it all the way down to this line:
DeviceMode := GlobalAlloc(GHND, DocumentProperties (0, FPrinterHandle, ADevice, StubDevMode, StubDevMode, 0)); in the function SetPrinter in the unit PRINTERS.PAS
When I did broke it up into two lines, i.e. call to DocumentProperties first and store the value in integer variable and then check the value and only then call Globalalloc if the value is greater than 0 and kind of debugged it with stored values in debug file the error was truly in the DocumentProperties function from SPOOL.DLL if I remember correctly. This function returned -1 as size for the device, but only with this customer on one computer (he is using 4 or 5 with my program)
Of all my customers (close to 200 clients) I have had this issue on two computers. The other one fixed it kind of itself.. I didn't know how it did get fixed. The later one I was trying to fix just a couple of minutes ago. In the end I found a solution. I did fix this customer with simple change of shortcut. I began to use the automatic fix for compatibility in Windows 10 and then ran the button "test program" and it worked.. No error choosing printers or using it's propertis. Ok.. Then I tried again with the shortcut alone.. aarrgg.. error returned.. but then, aha.. I thought to myself "this has to connects to how Windows is running this program" and changed how Windows 10 ran the program as check "run as administrator" to uncheck.
And no problem.
On almost every compture with Windows 10 I do check "Run as Administrator" with no problems. I think there was a update or some issues with spool.dll that connects these dots.
ps. If you google this behavior with Delphi DocumentProperties problems, then you will find out this is known problem.. some say connected to x86 and x64 mode, but I found this out.

how can i make AutoIT send command reliable?

Hi guys I'm running a script with AutoIt to insert the path of a file to upload with webdriver.
But the send command is so unreliable it's 50/50 it messes up the characters and the script just stops.
Is there a way to make it reliably input the data? Or maybe how can i confirm that the input is correct, resend, and then send?
This is what i have for the code. It sends the input into the firefox upload window.
WinWaitActive("File Upload")
Send("C:\Users\elsid\Desktop\Eclipse\Workspace\NG - Mentored\Autoit\Test.png")
Send("{ENTER}")
Thanks
The most reliable way is to use ControlSetText.
Play with AutoitWindowInfo tool and tweak the script below if needed.
#RequireAdmin ;Will give your script a permission elevation (sometimes its needed)
Opt("WinTitleMatchMode", 1) ;1=start, 2=subStr, 3=exact, 4=advanced, -1 to -4=Nocase
Opt("WinSearchChildren", 1) ;0=no, 1=search children also
WinActivate("File Upload")
WinWaitActive("File Upload","",10)
ControlFocus("File Upload","","Edit1")
Sleep(2000)
ControlSetText("File Upload","","Edit1","dropdowns.jpg")
In my humble opinion, the script stops because it waits that the window will be focused. To not messes up the characters, use function flag 1 in Send().
Try this way:
While WinWait("File Upload","",1) = 0
Sleep(500)
WEnd
WinActivate("File Upload")
Send("C:\Users\elsid\Desktop\Eclipse\Workspace\NG - Mentored\Autoit\Test.png", 1) ;-- flag 1 = keys are sent raw.
Send("{ENTER}")
Good Luck ;)

Matlab - signal after command completion

Is there a way to set matlab to come to the foreground of the windows when the command in complete? I can see it happening by executing a dos() but I'm unaware how window management works? Maybe there is a better way? Someone?
Two options. Neither exactly what you are asking for.
Option 1: Open a new figure.
figure();
imagesc(processingDoneSplashImage);
If you want to get fancy, put this in a script, with a timer, and flash the image between bright green, and bright red....
Option 2: My solution to your problem. (I find popping up windows extremely annoying.) I put this function call at the end of my long running scripts, and the computer tells me when it's done processing....
function [ ] = matSpeak( textToSpeak )
%matSpeak takes some text, and outputs onto the speaker the text,
% using the .Net SpeechSynthesizer.
% This only works on Windoze.
if ~exist('textToSpeak','var')
textToSpeak = 'Your processing has completed.';
end
NET.addAssembly('System.Speech');
speak = System.Speech.Synthesis.SpeechSynthesizer;
speak.Volume = 100;
speak.Speak(textToSpeak);
end
Why not just use Growl for your notification windows?
cmd = ['/usr/local/bin/growlnotify -m ' messagestr];
system(cmd);
Of course with Windows you need to fix the path to the growlnotify binary.
Source: http://www.mathworks.com/matlabcentral/newsreader/view_thread/259142
A wrapper with lots of features: Send a notification to Growl on MATLAB Exchange
Many more examples: https://www.google.com/search?q=growl+matlab

Is there any way to tell if the Windows Directory is writeable without actually writing to it to test?

I have some old vb6 code that checks to see if the Windows directory is writeable by WRITING to it then reading a value back.
But... we have a virus scanner that's viewing that as suspicious behavior so I want to check it without touching it.
Any Windows API calls for that? (Ideally for Win 98 and above)
Something to remember here is that the file system is volatile. About the only way I can see this code being used is to first do a check if a folder is writable, and then try to write something you wanted to write. The problem here is that with a volatile file system things might change in between when you make your check and when you try to write. As a consequence, you still have to be able to handle an exception if your write fails. That means the initial check is pretty much wasted. Better to put your effort into writing a better exception handler.
Additionally, for windows 2000 and later the Windows directly should only ever be writable if the user is running as an administrator. For a very long time running as an administrator was common practice, but people are starting to get the hint that this isn't a good idea. Long term, it's not a good idea for your program to do anything that requires running that way.
In fact, starting with Windows Vista, the user doesn't run anything as administrator by default, even when logged in to the administrator account. Instead, they have to manually choose to run the program as administrator or wait a security check to fail the system can prompt them to elevate.
If you have the VB6 code, you should take the time to fix it so that it does NOT need to write to the Windows directory at all because regardless of whether or not you are an administrator - unless you work at Microsoft you should consider that directory off limits.
However, you should consider that on Windows 98, the user will always have the ability to write to the Windows directory. On Windows XP, local administrators will. On Windows Vista and Seven, even administrators will not unless your application has been elevated.
So you can check for whether or not the user is in the built-in role BUILTIN\Administrators using CheckTokenMembership. This will be false for non-admins or non-elevated processes. It does not guarantee you can write to the Windows directory but it will be right most of the time. You can then add error handling logic for when the call actually fails.
But again, you should take the opportunity to fix the code and not use the Windows directory.
For Windows 2000 and above you could use GetNamedSecurityInfo() and AccessCheck(), but I would imagine those are a pain to call from VB.
Here is a function that will do it. I adapted this from some other code kind of quickly so if you use it you need to add error handling, (for instance a directory that doesn't exist just returns False. I have no idea if your anti-virus software is going to like this or not.
Function FolderIsReadOnly(ByVal FolderSpec As String) As Boolean
Dim rst As Long
Dim udtW32FindD As WIN32_FIND_DATA
Dim lngFHandle As Long
Dim strFolder As String 'set to FolderSpec parameter so I can change it
If Len(FolderSpec) = 0 Then
FolderIsReadOnly = False
Exit Function
End If
strFolder = FolderSpec
If Right$(strFolder, 1) <> "\" Then
strFolder = strFolder & "\"
End If
strFolder = strFolder & "*" 'add the wildcard allows finding share roots
lngFHandle = FindFirstFile(strFolder, udtW32FindD)
If lngFHandle <> INVALID_HANDLE_VALUE Then
Call FindClose(lngFHandle)
FolderIsReadOnly = (udtW32FindD.dwFileAttributes And FILE_ATTRIBUTE_READONLY) = FILE_ATTRIBUTE_READONLY
End If
End Function
Function IsPathAccessible(ByVal sPath As String) As Boolean
On Error GoTo ErrHandler
FileSystem.SetAttr sPath, vbNormal
IsPathAccessible = True
Exit Function
ErrHandler:
IsPathAccessible = False
End Function

Resources