May 18, 2012

How to do an HTTPS Request Without Installing all of OpenSSL

Filed under: Automation,Scripting — Marcus Tettmar @ 9:52 am

I recently wrote a small macro for a customer which does an HTTPRequest via SSL. This requires that OpenSSL is installed. But the customer wanted to know if there was any way of distributing the macro to his users without having to install OpenSSL on all their PCs.

Thanks to our wonderful forums one of our users has already figured out how to do this and it turns out only 2 DLLs are required and can be placed in either the Macro Scheduler program folder, or, in the case of a compiled macro, the exe’s folder.

Adroege says:

I use this solution:

Download the “binaries” from this page as a zip file
http://gnuwin32.sourceforge.net/packages/openssl.htm

Unzip the contents

find the files libeay32.dll (version 0.9.8.8) and libssl32.dll
(version 0.9.8.8) in the Bin folder

Make a copy of libssl32.dll and call it “ssleay32.dll”

Now just deliver all 3 DLL files in the same folder as the
compiled Macro Scheduler EXE
(libeay32.dll libssl32.dll ssleay32.dll)

Using this method, I didn’t have to do any special SSL “install”,
run regsvr32.exe, or do any registry hacks. It just works.

And rullbandspelare responds:

It appears to work with just putting
ssleay32.dll and libeay32.dll in the same folder.

Even I learn stuff from our forums, or at least find answers more quickly. A great resource. Thanks guys.

April 18, 2012

Getting into the Zone

Filed under: Scripting — Marcus Tettmar @ 4:07 pm

Over on the forums JRL asks how to get into the “Programming Zone” and once there how do you stay in it and cope with distractions and interruptions? Any tips? Add your thoughts and suggestions to the topic.

March 27, 2012

Sending Keys to Invisible or Unfocused Windows

Filed under: Automation,Scripting — Marcus Tettmar @ 2:32 pm

Can you send keystrokes to invisible or unfocused windows? The answer is yes, if the control you want to send the keystrokes into is a “windowed control”. That is, one that has a handle.

If that’s too technical just try using the “Send Keys to Object Wizard” in Macro Scheduler 13 which generates code that uses the ObjectSendKeys function. Or Watch the video to see it in action.

If the wizard is able to identify the control the code that it generates will work even if the window is not visible or not focused. This is because it works by sending the keyboard codes directly to the specified control.

In contrast the regular Send command sends characters into the global input buffer. In other words it sends keystrokes into whatever happens to have the focus at the time. The great thing about this is that it means it can send keystrokes to ANY thing regardless of whether it is a windowed control or not and regardless of the technology. But the control does need to be focused.

So if your control has a handle then you can use ObjectSendKeys to send keystrokes to it and avoid it having to be focused. This also means it will work even if the window is minimized, or hidden. This could be turned to your advantage if you wanted to manipulate a window and be able to do something else at the same time. Of course this assumes that all the controls have a handle which is not always the case.

As an example, run this script. Notepad will open, then be minimized and then text will be sent into it. When the script has finished restore Notepad and you should see the text inside it.

Run>Notepad.exe
WaitWindowOpen>Untitled - Notepad
WindowAction>2,Untitled - Notepad

GetWindowHandle>Untitled - Notepad,hWndParent
FindObject>hWndParent,Edit,,1,hWnd,X1,Y1,X2,Y2,result
ObjectSendKeys>hWnd,{"Hello World"}

February 3, 2012

How long does xyz take?

Filed under: Scripting — Marcus Tettmar @ 12:14 pm

Need to measure how long a process or a set of commands in your script takes?

We used to have to do this with VBScript’s Timer function. As of v13 Macro Scheduler has it’s own Timer function.

Timer>result

Returns the number of milliseconds that have elapsed since the script was started.

So let’s say we want to measure how long a script takes to run. We could use Timer at the top of the script to get the current milliseconds value, then again at the end and take one from the other to get the elapsed duration in milliseconds:

Timer>startTime
..
.. some code here
..
Timer>endTime
Let>elapsed_seconds={(%endTime%-%startTime%)/1000}
MessageModal>Seconds Elapsed: %elapsed_seconds%

June 29, 2011

Get Internet IP Address

Filed under: Scripting — Marcus Tettmar @ 8:55 am

If you are connected to the Internet here’s an easy way of getting your public IP address by visiting checkip.dyndns.org:

HTTPRequest>http://checkip.dyndns.org/,,GET,,HTMLResponse
RegEx>[IPAddress],HTMLResponse,1,ips,num_ips,0
If>num_ips>0
  MessageModal>Your IP is %ips_1%
Else
  MessageModal>Error retrieving IP from checkip.dyndns.org
Endif

June 13, 2011

Calling Macro Scheduler Functions from PowerShell

Filed under: General,Scripting — Marcus Tettmar @ 11:34 am

Further to my post about the MacroScript SDK the other day, here’s an example of loading the MacroScript SDK COM object from PowerShell and running some Macro Scheduler code:

  $objMS = new-object -comobject "mscript.macroscript"
  $objMS.Init()
  $objMS.RunCode( "Run>notepad.exe" + [Environment]::NewLine + 
  		"WaitWindowOpen>Untitled - Notepad" + [Environment]::NewLine + 
  		"Wait>0.5" + [Environment]::NewLine + 
  		"Send>Hello World", "")
  $objMS.Cleanup()

You will need to put the mscript.dll file into the system path (e.g. System32/SysWow64) or into the PowerShell folder.

Don’t forget that with the MacroScript SDK you can retrieve information and query the data back to PowerShell using the GetVar function (see previous post). So for all you system administrators using PowerShell but needing the GUI automation capabilities of Macro Scheduler as well, the MacroScript SDK is the perfect companion.

May 20, 2011

Scraping Data From Web Pages

Filed under: Automation,Scripting,Web/Tech — Marcus Tettmar @ 1:02 pm

I’ve seen quite a lot of requests lately from people wanting to know how to extract text from web pages.

Macro Scheduler’s optional WebRecorder add-on simplifies the automation of web pages and includes functions for extracting tables, text or HTML from web page elements. WebRecorder’s Tag Extraction wizard makes it easy to create the code.

Sometimes you can choose a specific HTML element and identify it uniquely via it’s ID or NAME attribute. But other times you might want all the text from the whole page, or you may need to extract the entire page and then parse out the bits you’re interested in using RegEx or some other string manipulation functions.

To extract an entire page I specify the BODY element. If you want to extract data from web pages it does help if you know a little about HTML. And if you do you’ll know that each page has just one BODY element which contains the code making up the visible portion of the page.

Here’s code produced using WebRecorder when navigating to mjtnet.com and using the Tag Extraction wizard to extract the BODY text:

IE_Create>0,IE[0]

IE_Navigate>%IE[0]%,http://www.mjtnet.com/,r
IE_Wait>%IE[0]%,r
Wait>delay

//Modify buffer size if required (you may get a crash if buffer size too small for data) ...
Let>BODY0_SIZE=9999
IE_ExtractTag>%IE[0]%,,BODY,0,0,BODY0,r
MidStr>r_6,1,r,BODY0

MessageModal>BODY0

The macro simply displays just the text in a message box but could be set to pull out the full HTML. You could then parse it with RegEx to get the information you are interested in.

You will need WebRecorder installed for the above to work.

If you don’t have WebRecorder you can do the same with a bit more work using VBScript. Some library functions for doing this can be found here and here.

So here’s the equivalent in VBScript:

VBSTART
Dim IE

'Creates IE instance
Sub CreateIE
  Set IE = CreateObject("InternetExplorer.Application")
  IE.Visible=1
End Sub

'Navigate to an IE instance
Sub Navigate(URL)
  IE.Navigate URL
  do while IE.Busy
  loop
End Sub

'This function extracts text from a specific tag by name and index
'e.g. TABLE,0 (1st Table element) or P,1 (2nd Paragraph element)
'set all to 1 to extract all HTML, 0 for only inside text without HTML
Function ExtractTag(TagName,Num,all)
  dim t
  set t = IE.document.getElementsbyTagname(Tagname)
  if all=1 then
    ExtractTag = t.Item(Num).outerHTML
  else
    ExtractTag = t.Item(Num).innerText
  end if
End Function
VBEND

VBRun>CreateIE
VBRun>Navigate,www.mjtnet.com

VBEval>ExtractTag("BODY",0,0),BodyText
MessageModal>BodyText

But what if you already have a macro which already opens IE, or works against an already open instance of IE? The above macros need to create the IE instance before they can access them and extract data from them. You may have a macro that already starts IE some other way – maybe just by using a RunProgram or ExecuteFile call, or indirectly via some other application. Many times people tackle the extraction of data from such an IE window by sending keystrokes to do a Select-All, Edit/Copy and then use GetClipboard; or even File/Save As to save the HTML to a file. This of course adds time and can be unreliable. So how else can we do it?

Well, this tip shows us a function we can use to attach to an existing IE instance. So let’s use that and then use our ExtractTag function to pull out the BODY HTML:

VBSTART
Dim IE

' Attaches to an already running IE instance with given URL
Sub GetIE(URL)
  Dim objInstances, objIE
  Set objInstances = CreateObject("Shell.Application").windows
  If objInstances.Count > 0 Then '/// make sure we have instances open.
    For Each objIE In objInstances
      If InStr(objIE.LocationURL,URL) > 0 then
        Set IE = objIE
      End if
    Next
  End if
End Sub

'This function extracts text from a specific tag by name and index
'e.g. TABLE,0 (1st Table element) or P,1 (2nd Paragraph element)
'set all to 1 to extract all HTML, 0 for only inside text without HTML
Function ExtractTag(TagName,Num,all)
  dim t
  set t = IE.document.getElementsbyTagname(Tagname)
  if all=1 then
    ExtractTag = t.Item(Num).outerHTML
  else
    ExtractTag = t.Item(Num).innerText
  end if
End Function
VBEND

VBRun>GetIE,www.mjtnet.com

VBEval>ExtractTag("BODY",0,1),BodyHTML
MessageModal>BodyHTML

This snippet assumes a copy of IE is already open and pointing to www.mjtnet.com. The GetIE call creates a link to that IE window and then we use the ExtractTag function to pull out the HTML of the BODY element.

These examples use the BODY element, which will contain everything displayed on the page. As I mentioned before you can be more specific and specify some other element, and with WebRecorder, or a modified version of the ExtractTag VBScript function use other attributes to identify the element (the existing VBScript ExtractTag function shown above just uses the numeric index). WebRecorder tries to make it simple by giving you a point and click wizard, making some assumptions for you, so that you need not fully understand the HTML of the page. But it still helps you understand HTML. Looking at the source of the page you should be able to identify the element you need to extract from. And whether you extract directly from that or extract the BODY and then use RegEx being prepared to delve into the HTML source is going to get you further.

UPDATE: 19th January 2012

As of version 13.0.06 Macro Scheduler now includes a function called IEGetTags. For a given tag type and IE tab this will retrieve an array of tag contents. It can extract just the text, or html of the tags. This example extracts the inner HTML of all DIV elements in the open IE document currently at www.mjtnet.com:

IEGetTags>mjtnet.com,DIV,H,divArr

You can then cycle through each one with a Repeat Until

If>divArr_count>0
  Let>k=0
  Repeat>k
    Let>k=k+1
    Let>this_div_html=divArr_%k%
    .. 
    .. do something with it
    .. e.g. use RegEx or substring searching to determine 
    .. if this is the DIV you want and extract from it
    .. 
  Until>k=divArr_count
Endif

To further identify the tag you are interested in, or find the data you want, you can use RegEx, EasyPatterns, or string functions.

Macro Scheduler 13.0.06 and above also has a function called IETagEvent which will let you simulate a Click on a given tag, focus it, or modify its value. So once you have identified a tag using IEGetTags and your Repeat/Until loop you can click on it, focus it or modify its value (e.g. for form fields).

February 23, 2011

New Video: Using The Debugger

Filed under: Announcements,Automation,Scripting — Marcus Tettmar @ 9:44 am

Macro Scheduler veteran John Brozycki has put together this fantastic video tutorial all about Macro Scheduler’s debugging capabilities. The video is 18 minutes long and demonstrates every debug feature, showing examples of their use and talks about how useful the debugger can be for problem resolution as well as script creation. Take a look:

A larger version of the video can be found here.

John Brozycki is an information security professional who uses Macro Scheduler as a tool to accomplish a wide range of tasks in his daily activities. His personal web site is www.trueinsecurity.com.

I think this is an excellent tutorial which all script developers should benefit from. Thanks John!

February 8, 2011

Undocumented Internal Dialog Event Parameters

Filed under: Scripting,Tutorials — Marcus Tettmar @ 3:35 pm

In this forum post Armsys asks how he can determine which key the user pressed in an OnKeyPress dialog event handler. The solution I posted reveals an undocumented feature: Internal event parameters.

While there is a sample macro called “Dialogs – MouseOver” which ships with Macro Scheduler and demonstrates these event parameters, they are missing from the help file.

So here’s a short 3 minute video showing how this sample script works and demonstrating how you can determine what event parameters are available for use.

(Don’t forget you can view full screen and/or change the quality with the options in the video control panel above).

If you’re completely new to custom dialogs you might also want to watch part 1 and part 2 of the custom dialog video tutorials first.

January 18, 2011

Slow Mouse Move

Filed under: Scripting — Marcus Tettmar @ 1:33 pm

A support request came in today asking how to show the mouse moving from one point to another slowly enough to be visible in a video demo.

The regular MouseMove function simply “jumps” the mouse cursor straight to the given point, without passing any points between wherever it was to start with and that end point. So the question was how to specify a start point and an end point and show the mouse moving on a line between them.

To achieve this we need to determine what that line is. We don’t want to move to *every* point between those two points on both the x and y axis. So how do we do it?

Well, it was a long time ago but deep in the recesses of my mind was a little equation we learnt in mathematics at school. I admit I had to look it up. It was the “slope-intercept” equation:

y = mx + b

The slope “m” is the change in y over the change in x:

m = (y2 – y1) / (x2 – x1)

Once we have that we can calculate b (the y-intercept) given a known point (e.g. the start point) and then for each x we can calculate y.

So here’s a script which will move the mouse slowly through the line between two given points:

Let>startX=20
Let>startY=100
Let>endX=300
Let>endY=400
Let>delay_interval=0.001

//remember school math?
//equation of a line is y = mx+b

//m = y2-y1 / x2-x1
Let>m={(%endY%-%startY%)/(%endX%-%startX%)}
//b = y-mx
Let>b={%startY%-(%m% * %startX%)}

Let>x=startX
Let>y=startY
Repeat>x
   //y = mx+b
   Let>y={Trunc((%m% * %x%) + %b%)}
   MouseMove>x,y
   Wait>delay_interval
   If>endX>startX
     Let>x=x+1
   Else
     Let>x=x-1
   Endif
Until>x=endX

This probably isn’t much use to most people, but it’s a little bit of fun. Maybe you can jazz up your scripts to animate the movement of the cursor or something 🙂

Doing anything a little bit out of the ordinary with Macro Scheduler? Let me know.

« Newer PostsOlder Posts »