Capturing screenshot while workstation is locked - screenshot

I would like to capture a screenshot of the monitor or a window, preferably using AutoIt (I am open to using any convenient method). The method needs to be able to function while the workstation is locked, due to the program being run overnight.
I cannot simply put code to unlock the workstation, as it poses a security risk. Current behavior: _ScreenCapture_SaveImage() saves a blank screen with only the mouse showing.

Try using captdll.dll to capture fullscreen or a program window.
$LogFilePath = "C:\Temp"
$TimeStamp = #YEAR & #MON & #MDAY & #HOUR & #MIN & #SEC
; Capture full screen
; Fist parameter - filename, last - jpeg quality.
$erg = DllCall("captdll.dll", "int:cdecl", "CaptureScreen", "str", $LogFilePath & "\Ce2eC_" & $TimeStamp & ".JPG", "int", 75)

Related

VBA to save PDF from URL to local folder

I'm trying to cycle through several url's to download the pdf to a local folder.
An example of the url is https://find-energy-certificate.service.gov.uk/energy-certificate/8309-9619-9729-7796-8423?print=true
This is the vb I've written so far.
Dim sveloc As String
Dim svenme As String
Dim url As String
sveloc = Application.ActiveWorkbook.Path & "\Saved EPCs"
i = 7
Do Until sh01.Cells(i, 27) = "" 'all cells in the list are populated with no gaps
url = sh01.Cells(i, 27)
svenme = sh01.Cells(i, 2)
sveloc = sveloc & "\" & svenme & ".pdf"
ThisWorkbook.FollowHyperlink (url)
'code to open and save the pdf goes here
i = i + 1
Loop
Any help gratefully received as I'm really stumped on this one.
TIA.
Inspired by KJ's answer, without error checking etc. Just wanted to illustrate how you'd use shell to automate the entire process.
sveloc = Application.ActiveWorkbook.Path & "\Saved EPCs"
edgePath = Environ$("PROGRAMFILES(X86)") & "\Microsoft\Edge\Application\msedge.exe"
With CreateObject("WScript.Shell")
i = 7
Do Until Len(sh01.Cells(i, 27)) = 0 'all cells in the list are populated with no gaps
On Error Resume Next
.Run """" & edgePath & """ --profile-directory=Default --headless -print-to-pdf=""" & sveloc & "\" & sh01.Cells(i, 2) & ".pdf" & """ """ & sh01.Cells(i, 27) & """", 1, True
On Error GoTo 0
i = i + 1
Loop
End With
No need for VBA but you can use that to alter the variables so using your example from Windows we can run the build pdf at html runtime via Edge:-
"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --profile-directory=Default --headless -print-to-pdf=C:\Users\WDAGUtilityAccount\Desktop\8309-9619-9729-7796-8423.pdf "https://find-energy-certificate.service.gov.uk/energy-certificate/8309-9619-9729-7796-8423?print=true"
and as if by magic the file is in less than a second on my desktop
There is no online pdf it is built by the browser. So it is essential to use the browser. You can remove the print header/footer with one extra switch, but cannot change orientation it will be A4 portrait in UK device.
-print-to-pdf-no-header see currently https://source.chromium.org/chromium/chromium/src/+/main:headless/app/headless_shell_switches.cc;l=60
one other switch may be of value if you only want smaller untagged files
-disable-pdf-tagging see https://source.chromium.org/chromium/chromium/src/+/main:headless/app/headless_shell_switches.cc;l=64
If you try to download without browser printing you will just get the raw HTML as needed for web page printing, thus calling browser remote print as above, will generate the desired "designed for the web" graphics copy.
curl -o test.htm https://find-energy-certificate.service.gov.uk/energy-certificate/8309-9619-9729-7796-8423?print=true
In comments the question was raised how to adapt this approach for change of browser and keeping call simple so I suggest use a cmd or bat file to make that part easier. Thus from vba call something like
Batchfile 8309-9619-9729-7796-8423
#echo off
set "browser=C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"
set "filedir=C:\Users\WDAGUtilityAccount\Desktop"
set "urlpath=https://find-energy-certificate.service.gov.uk/energy-certificate"
"%browser%" --profile-directory=Default --headless --print-to-pdf="%filedir%\%~1.pdf" -print-to-pdf-no-header "%urlpath%/%~1?print=true"
However, beware calling pdf generations too fast, add a small wait between calls, even on multithreaded CPU writing PDF's at same time often leads to disasters, due to graphics resource conflicts.

Run iMacros Enterprise Edition macro on the iMacros Player Edition

I developed a macro to fill fields in a web site, click a "validate" and "submit" button.
On my machine, with the Enterprise Edition, it runs as expected. I tested it a number of times.
I sent the macro to a field user, who has the Player Edition (same version number). The macro, runs through the login process and works until it starts entering data. When it runs the highlighted code below, the macro clears the web site and leaves a few links.
The code below is for updating the first field. It enters the value and then clicks the "ENTER" button. This particular website needs an "enter" or "tab" keystroke at this point to start a behind the scenes validation. (When it runs on my machine, there is a little validation message that pops up after the "ENTER" key is executed - just like it is supposed to. This isn’t happening with the Player Edition.)
Several different users, with the Player Edition have tried the macro, and the same thing happens; the website goes practically blank when the "ENTER" command is executed.
I have tried the following things:
Commented the code out – doesn’t work
Change the 0 to * - doesn’t work
Changed ENTER to TAB – doesn’t work – the macro enters } after TAB
I also looked at the emulation. When I run the macro, the bottom of the web site says “Emulating IE 10”. When the user runs the macro, the web site says “Emulating IE 11”. Could this be the cause of the different behavior? If so, is there a way to programmatically change it? Is there was way to force the macro to emulate IE 10 when the user runs the macro? I have two other iMacros that they use and this hasn’t been an issue before.
The extract code below is used to confirm that a value has been entered and validated and then the macro moves on to the next field.
IM = ""
IM = "CODE:"
IM = IM + "TAB T=2" + vbNewLine
IM = IM + "SET !TIMEOUT 1" + vbNewLine
IM = IM + "TAG POS=1 TYPE=INPUT:TEXT ATTR=NAME:editWarrantyform:repairOrderNumberId CONTENT=" & vRO(Y) + vbNewLine
iret = iim1.iimPlay(IM)
IM = ""
IM = "CODE:"
IM = IM + "TAB T=2" + vbNewLine
IM = IM + "SET !TIMEOUT 60" + vbNewLine
IM = IM + "DS CMD=KEY X=0 Y=0 CONTENT={ENTER}" + vbNewLine
iret = iim1.iimPlay(IM) **** MACRO ERRORS OUT WHEN THIS LINE IS EXECUTED
IM = ""
IM = "CODE:"
IM = IM + "TAB T=2" + vbNewLine
IM = IM + "SET !TIMEOUT 60" + vbNewLine
IM = IM + "TAG POS=1 TYPE=INPUT:TEXT ATTR=NAME:editWarrantyform:repairOrderNumberId EXTRACT=TXT" + vbNewLine
iret = iim1.iimPlay(IM)
vTmp = ""
vTmp = iim1.iimgetlastextract
vTmp = Replace(vTmp, "[EXTRACT]", "")
vTmp = Trim(vTmp)
Does the "ENTER" command work any different in the Player edition than in the Enterprise Edition? I have several other iMacro processes in this same macro and the field users say these run without any issues. I don't think the "ENTER" command is used in any of these other processes.
Turns out it was the IE emulation. On my machine (Enterprise Edition), the IE emulation was 10. On the user's machine (Player Edition), the IE emulation was 11. Once we switched the user's emulation to IE 10, the macro ran like it did on my machine....who knew....

Is it possible to change internet connection (e.g. from WiFi to Cable) with VBA?

For reporting purposes, I'm importing data from various sources on the net into an Excel Workbook.
Problem is: while some of the stuff I want is on my company's private network (requiring cable connection), some of the URL/webservices I want to connect to are not allowed by my company's proxy (via cable connection).
Thus, I have to use another connection without proxy (via WiFi) to get those to work.
This WiFi connection is always active on my computer, but it requires me to manually unplug the cable for half of my imports and to plug it back to access files on my company's network for the other half...
I wonder if there is a way with VBA to tell the computer to use cable / WiFi according to what I need.
I am working on a Windows XP Pro computer with Excel 2010/VBA. Please help!
Found Two ways to enable or disable i.e change internet adapter connection from VBA:
'adjust these according to your need i.e change adapter name, change enabled or disabled parameter, change path, change file name etc. VBS approach is long but gives more control. Bat approach is short but limited IMO
1 Using vbs Source link :
'file name: asdf.vbs
'Get and disable all physical wired adapters (AdapterTypeID=0) (Ethernet 802.3)
'Wscript.Echo "test"
Set wmi = GetObject("winmgmts:root\CIMV2")
Set adapters = wmi.ExecQuery("Select * from Win32_NetworkAdapter where _
AdapterTypeId=0 AND NetConnectionID IS NOT NULL",,48)
For Each adapter in adapters
With adapter
WScript.Echo "available: " & .Availability & " enabled: " & .NetEnabled & " netconStatus: " & .NetConnectionStatus & " status: " & .Status & " netconnID: " & .NetConnectionID & " adType: " & .AdapterType
'adapter.disable()
'adapter.enable()
End With
Next
' Get and disable all physical wireless adapters (AdapterTypeID=9) (wireless)
2 Using bat Ref link1 and Ref link2 :
'file name: switch_lan6.bat
#echo off
start /MIN cmd.exe /c "netsh interface set interface name="Local Area Connection 6" admin=disabled"
Running these inside excel vba:
Shell "wscript ""C:\Users\USER\Desktop\asdf.vbs""", vbNormalFocus
or,
Call Shell(ThisWorkbook.Path & "\switch_lan6.bat", 0)

VB.NET is seeing the wrong monitor as having the TaskBar for computing the height

When I run this VB.NET code in my WinForms program it displays the expected results if Monitor #1 is on the left, and Monitor #2 is on the right.
(And Monitor #1 contains the Windows TaskBar.)
But if the user has his monitors switched around, with Monitor #2 on the left (containing the TaskBar), and #1 on the right... the height is now wrong.
My code then (incorrectly) assumes the Monitor with the TaskBar has a LARGER value for the height.
Is there a way to fix that? (Without forcing 1000s of users to switch their Monitors around... or switch the TaskBars to the other monitor.)
Or am I totally misunderstanding "WorkingArea()"????
Dim msg As String = ""
Dim numberOfMonitors As Int16 = Screen.AllScreens.GetUpperBound(0) + 1
If (numberOfMonitors >= 1) Then msg &= "Monitor #1 = " & Screen.AllScreens(0).WorkingArea.Width & " x " & Screen.AllScreens(0).WorkingArea().Height & ". "
If (numberOfMonitors >= 2) Then msg &= "Monitor #2 = " & Screen.AllScreens(1).WorkingArea.Width & " x " & Screen.AllScreens(1).WorkingArea().Height & ". "
Call MsgBox(msg)
No you are not misunderstanding Working area. Here is the definition from MSDN
The working area is the desktop area of the display, excluding taskbars, docked windows, and docked tool bars.
WorkingArea will return the entire area of the screen if the Windows Taskbar is set to Auto-Hide, no matter whether the Taskbar is currently displayed or not.
I would look into two propertys of the Screen class one is Primary which returns a Boolean value indicating wether or not that screen is the Primary, the second is just use the PrimaryScreen Property to get the Working area of your Primary Screen.
Caveat: I do not have a dual monitor system powered up at this time to verify if this works.

How to programmatically generate a PDF from any document on OSX?

I'm working on a project for OSX where the user can pick a collection of documents (from any application) which I need to generate PDF's from. The standard Macintosh Print dialog has a PDF button which has a number of PDF-related commands including "Save as PDF...". However, I need to generate the PDF file without requiring user interactions. I ideally want this to work with any type of document.
Here's the options I've explored so far:
Automator actions. There's a PDF library for Automator but it provides actions for working with PDF files, not generating them. There's a Finder action for printing any file but only to a real printer.
AppleScript. Some applications have the ability to generate PDF files (for instance, if you send 'save doc in "test.pdf"' to Pages it will generate a PDF (but this only works for Pages - I need support for any type of document).
Custom Printer. I could create a virtual printer driver and then use the automator action but I don't like the idea of confusing the user with an extra printer in the print list.
My hope is that there's some way to interact with the active application as if the user was carrying out the following steps:
Do Cmd-P (opens the print dialog)
Click the "PDF" button
Select "Save as PDF..." (second item in menu)
Type in filename in save dialog
Click "Save"
If that's the best approach (is it?) then the real problem is: how do I send UI Events to an external application (keystrokes, mouse events, menu selections) ?
Update: Just to clarify one point: the documents I need to convert to PDF are documents that are created by other applications. For example, the user might pick a Word document or a Numbers spreadsheet or an OmniGraffle drawing or a Web Page. The common denominator is that each of these documents has an associated application and that application knows how to print it (and OSX knows how to render print output to a PDF file).
So, the samples at Cocoa Dev Central don't help because they're about generating a PDF from my application.
I think you could use applescript to open a document and then use applescript UI scripting to invoke print menu.
For example :
tell application "System Events"
tell window of process "Safari"
set foremost to true
keystroke "p" using {command down}
delay 3
click menu button "PDF" of sheet 2
click menu item "Save as PDF…" of menu 1 of menu button "PDF" of sheet 2
keystroke "my_test.file"
keystroke return
delay 10
end tell
end tell
Take a look at a program called CUPS-PDF
It is a virtual printer for OS X which does what the "Save As PDF" method does when print through your normal printer except every print job passed through it results in a pdf output.
Once you install it then you could create shell or AppleScripts using the lp command.
For example, once the virtual printer is setup you could print test.txt and have it automatically save as a pdf. To do this using an AppleScript you would use the following code:
do shell script "lp -d CUPS_PDF test.txt"
The CUPS-PDF app saves all output to /Users/Shared/CUPS-PDF. I am not sure if you can change that path but you could retrieve the file in your script and move it.
There are a few caveats though.
First, the lp command cannot print .doc files. I think there are some other third party apps which will allow you to do this though.
Second, the CUPS-PDF app shows in the Printer pane of System Preferences as having the hyphen in its name but CUPS shows the queue name as having an underscore. So, on the command line you need to refer to the CUPS queue name which is CUPS_PDF with an underscore.
Even if you don't find it very useful to build a script via the lp command
and still want to involve GUI scripting then having a virtual printer should save you some steps.
you could use cups like this
on open afile
set filename to name of (info for afile)
tell application "Finder"
set filepath to (container of (afile as alias)) as alias
end tell
set filepath to quoted form of POSIX path of filepath
set tid to AppleScript's text item delimiters
set AppleScript's text item delimiters to "."
set filename to text item 1 of filename
set AppleScript's text item delimiters to tid
set afile to quoted form of POSIX path of afile
do shell script "cupsfilter " & afile & " > " & filepath & filename & ".pdf"
end open
I have created an alias in bash for this:
convert2pdf() {
/System/Library/Printers/Libraries/convert -f "$1" -o "$2" -j "application/pdf"
}
I typed up the code below with the assistance of Automator (recording an action, and then dragging the specific action out of the "Watch Me Do" window in order to get the Applescript). If you want to print a PDF from an application other than Safari, you might have to run through the same process and tweak this Applescript around the Print dialogue, since each program might have a different Print GUI.
# Convert the current Safari window to a PDF
# by Sebastain Gallese
# props to the following for helping me get frontmost window
# http://stackoverflow.com/questions/480866/get-the-title-of-the-current-active-window- document-in-mac-os-x
global window_name
# This script works with Safari, you might have
# to tweak it to work with other applications
set myApplication to "Safari"
# You can name the PDF whatever you want
# Just make sure to delete it or move it or rename it
# Before running the script again
set myPDFName to "mynewpdfile"
tell application myApplication
activate
if the (count of windows) is not 0 then
set window_name to name of front window
end if
end tell
set timeoutSeconds to 2.0
set uiScript to "keystroke \"p\" using command down"
my doWithTimeout(uiScript, timeoutSeconds)
set uiScript to "click menu button \"PDF\" of sheet 1 of window \"" & window_name & "\" of application process \"" & myApplication & "\""
my doWithTimeout(uiScript, timeoutSeconds)
set uiScript to "click menu item 2 of menu 1 of menu button \"PDF\" of sheet 1 of window \"" & window_name & "\" of application process \"" & myApplication & "\""
my doWithTimeout(uiScript, timeoutSeconds)
set uiScript to "keystroke \"" & myPDFName & "\""
my doWithTimeout(uiScript, timeoutSeconds)
set uiScript to "keystroke return"
my doWithTimeout(uiScript, timeoutSeconds)
on doWithTimeout(uiScript, timeoutSeconds)
set endDate to (current date) + timeoutSeconds
repeat
try
run script "tell application \"System Events\"
" & uiScript & "
end tell"
exit repeat
on error errorMessage
if ((current date) > endDate) then
error "Can not " & uiScript
end if
end try
end repeat
end doWithTimeout
"/System/Library/Printers/Libraries/./convert"
has been removed in later version of MacOS.
You can use sips now. AppleScript example:
do shell script: sips -s format pdf Filename.jpg --out Filename.pdf