Marcus' Macro Blog

Mostly tips, tutorials, articles and news about Macro Scheduler & Windows Automation
October 30th, 2012 by Marcus Tettmar

By now you are probably aware of UAC (User Account Control) that came along when Vista was released. And you probably know that to do anything like copy files to Windows\System32 or Program Files or do other administrative stuff you need to be running as Admin, or you’ll get the UAC prompt come up asking you for permission to continue. And when you continue the thing you launched is then running as admin.

For sensible reasons, Windows is designed so that an ordinary level process – i.e. an application that is running under a standard user account without administrative privileges (let’s call it an un-elevated application) is not allowed to manipulate, interact with or exchange information with an elevated process (one running with administrator privileges or “As Admin”).

Macro Scheduler runs “as invoker”. In other words it runs at the level of the user who starts it. In most cases, and by default, that means it is running without administrator privileges. Unless you have disabled UAC, or chosen to run Macro Scheduler as admin, or have set the Macro Scheduler shortcut properties to launch Macro Scheduler as admin, then Macro Scheduler will run as a standard user without administrative privileges.

Since a standard process is not allowed to manipulate an admin process, Macro Scheduler is not able, by default, to send keystrokes into windows belonging to processes running as admin.

Try it. Run Notepad as admin and then try the following simple macro in Macro Scheduler:

Setfocus>Untitled – Notepad
Send>Hello World

You’ll see nothing happen. The text “Hello world” will not arrive in Notepad.

Now close Notepad and run Notepad as normal and of course the script works.

So what do you do if you NEED to send keystrokes into an admin level window? Well, unless it is possible to run that process as an ordinary user you will need to also run Macro Scheduler as admin.

To run Macro Scheduler “elevated” as admin, right click on the Macro Scheduler shortcut and select “Run as Administrator”. If you have UAC enabled (the default) you’ll see the UAC confirmation box pop up to make sure you’re happy to continue. Ok that and now Macro Scheduler is running as admin.

Now try running Notepad as admin again and you’ll find our little macro works.

Some legacy applications written before Vista came along were developed assuming the user had administrative privileges, which was common in the days of XP. This was poor practice but widely done. A common transgression was that they would write their settings and files to the Program Folder. In order to run these applications under Vista or later they would therefore have to be run as Admin, unless there was any way to force them to write data to another more sensible location. Sadly there are still applications that do this, especially older ones that are no longer maintained. Since the only way to use such legacy apps on Vista/Win7/Win8 is to disable UAC or set them to run as admin and put up with the UAC prompt, if you need to automate them you’re going to have to also run Macro Scheduler (or your compiled macro) as admin.

Short version: If you wish to automate an elevated application (one that runs as admin), Macro Scheduler or your compiled macro, also needs to be running elevated.

October 29th, 2012 by Marcus Tettmar

Macro Scheduler 13.2.2 Update is now available with the following changes:

  • Fixed: ReadFile errors not being trapped correctly
  • Fixed: If a macro is being edited and its schedule fires, a file lock error occurs, macro should not be run by scheduler if being edited
  • Fixed: IEGetTagsByAttrib not setting correct array index
  • Added: IEWait function

Registered Updates | Trial Downloads | Upgrades

October 29th, 2012 by Marcus Tettmar

It occurred to me the other day while working on a script for a customer that I use this regular expression frequently:

(?<=TOKEN1).*?(?=TOKEN2)

It is very useful when parsing information out of web pages, or when finding elements in web pages.

What it does is pull out all the text between TOKEN1 and TOKEN2. Those could be other pieces of text, or html characters, or whatever.

As an example, recently I wrote a script which loops through all rows in an HTML table, and pulls out an order number, then looks this order number up in an Excel sheet. The order number appeared in a table cell along with other information. It was the first item inside an <i> (italics) tag and was followed by a space and then a hyphen. So I used this to pull it out of the row:

RegEx>(?<=<i>).*?(?= -),this_row,0,matches,nm,0

See how it looks for everything between the ‘<i>’ and ‘ -’ (space then hyphen).

The next thing my code needed to do was find the ID of the single input field in the same row. This input was used to enter the order quantity, obtained from the Excel sheet. The ID is not something we know up front but it’s the only input field in the row. So I did this:

RegEx>(?<=id=").*?(?="),theInput,0,matches,nm,0

In other words, pull the text between id=” and “, which gives us the input’s ID value. We can then use that later to identify and fill the input field.

Regular Expressions are daunting at first. But eventually you find a small number of patterns help in many situations. This is one that I often find useful.

What’s your oft-used regular expression?

October 18th, 2012 by Marcus Tettmar

Gotta love Amazon. Received the following in an email today 18th October. I have removed identifying info. Emphasis mine:

date: 18 October 2012 11:53
subject: Your Amazon.co.uk Enquiry

I’m sorry to hear that you haven’t received your order ############# yet.

I’ve checked and can see that it was sent via DPD_24_PRIME to the following address:

redacted
redacted
redacted

The estimated delivery date given for this order last 17 Oct 2012

Your order is still in transit and I’m confident that it’ll arrive by the estimated delivery date. You can confirm the estimated delivery date by visiting the “Your Orders” section of Your Account or by clicking on the following link:

https://www.amazon.co.uk/gp/css/history/orders/view.html

Awesome!

October 3rd, 2012 by Marcus Tettmar

Since version 13.2 Macro Scheduler‘s email functions now support SSL. Google’s Gmail and many other email services now insist on SSL secured connections.

To use SSL you first need to install the OpenSSL library files.

Here’s an example of sending an email via Gmail:

Let>SMTP_AUTH=1
Let>SMTP_USERID=your_email@gmail.com
Let>SMTP_PASSWORD=your_password
Let>SMTP_PORT=465
Let>SMTP_SSL=1
SMTPSendMail>someone@somewhere.com,smtp.gmail.com,your_email@gmail.com,your name,test,hello world,

And to retrieve emails from Gmail via POP3 (make sure you have enabled this in your gmail settings):

Let>POP3_PORT=995
Let>POP3_SSL=1
RetrievePOP3>pop.gmail.com,your_email@gmail.com,your_password,c:\emails\in\
October 2nd, 2012 by Marcus Tettmar

If you’re new to automating IE/websites with WebRecorder or the native Macro Scheduler IE functions you may be wondering how to determine which elements and attributes to use.

In this video I demonstrate how to use IE’s F12 key to invoke Developer Tools and use that to quickly find the elements we’re interested in and the attributes we need to use:

(You might want to click on the video toolbar to select a larger resolution size, view full screen or view on YouTube so that you can see the code).

September 27th, 2012 by Marcus Tettmar

We recently had some problems with the service we were using to host our video tutorials (divshare.com). Since most of them were also on YouTube we have therefore updated our YouTube channel to include all the videos and have modified our site so that the videos are now served from YouTube.

My only worry is that some companies may block YouTube, although I was also aware that some organizations also blocked divshare. So I guess you can’t win. If you are accessing our site from behind a company firewall and can’t view our videos drop us a line and we’ll see what we can do.

September 18th, 2012 by Marcus Tettmar
September 17th, 2012 by Marcus Tettmar

Macro Scheduler 13.2 Update is now available with the following changes:

  • Added: IEGetTagsByAttrib function
  • Added: IETagEventByAttrib function
  • Added: SSL Support to RetrievePOP3
  • Added: SSL Support to SMTPSendMail
  • Added: HTTP_CHARSET variable to override charset decoding (e.g. for XML)
  • Added: HTTP_USERAGENT variable to set user agent to string of choice
  • Fixed: Suppress unnecessary ftp errors on ftp disconnect …
  • Fixed: GetWindowChildList code builder not working
  • Fixed: TELNETSESSION_LOG, WIN_SLEEP not syntax highlighting

Registered Updates | Trial Downloads | Upgrades

September 4th, 2012 by Marcus Tettmar

Today I was asked how the outcome of a button click on a custom dialog could be altered if the ALT or CTRL key was pressed down at the time of the click.

This is possible by trapping the dialog’s OnKeyDown and OnKeyUp handlers. Using these we can detect if ALT or CTRL is pressed/released and set a flag accordingly. Then in the button’s OnClick handler we can check the value of this flag and decide what we should do.

Here’s some example code. Run it and click the button without holding down any keys. You’ll see a message saying that ALT was not pressed. Now click the button while holding down the ALT key and you’ll see the “you clicked the button while ALT was pressed” message.

Dialog>Dialog1
object Dialog1: TForm
  Left = 467
  Top = 241
  HelpContext = 5000
  BorderIcons = [biSystemMenu]
  Caption = 'CustomDialog'
  ClientHeight = 212
  ClientWidth = 431
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  KeyPreview = True
  OldCreateOrder = True
  ShowHint = True
  OnTaskBar = False
  PixelsPerInch = 96
  TextHeight = 13
  object MSButton1: tMSButton
    Left = 147
    Top = 47
    Width = 75
    Height = 25
    Caption = 'MSButton1'
    TabOrder = 0
    DoBrowse = False
    BrowseStyle = fbOpen
  end
end
EndDialog>Dialog1

AddDialogHandler>Dialog1,MSButton1,OnClick,doClick
AddDialogHandler>Dialog1,,OnKeyDown,doKeyDown
AddDialogHandler>Dialog1,,OnKeyUp,doKeyUp

Let>CTRL_DOWN=FALSE
Let>ALT_DOWN=FALSE

Show>Dialog1,r

SRT>doClick
    //button was clicked, which key is down
    If>ALT_DOWN=TRUE
      MessageModal>You clicked the button while ALT was pressed
    Else
      MessageModal>You clicked the button without pressing ALT
    Endif
END>doClick

SRT>doKeyDown
    //is CTRL key pressed
    If>DoKeyDown_Key=17
      Let>CTRL_DOWN=TRUE
    Endif
    //is ALT key pressed
    If>DoKeyDown_Key=18
      Let>ALT_DOWN=TRUE
    Endif
END>doKeyDown

SRT>doKeyUp
    //was ctrl released
    If>doKeyUp_Key=17
      Let>CTRL_DOWN=FALSE
    Endif
    //was ALT released
    If>doKeyUp_Key=18
      Let>ALT_DOWN=FALSE
    Endif
END>doKeyUp

You might be wondering how I know that the CTRL key is number 17 and the ALT key is 18. To find out the value of a key press the simplest way is just to pop a breakpoint at the start of the doKeyDown subroutine, then run the script in the debugger, press a key and look in the watch list to see what value is produced. Alternatively there’s a table here. Note that ALT is known as VK_MENU and CTRL is VK_CONTROL.