April 20, 2009

Twittering from Macro Scheduler with the Twitter API

Filed under: Scripting, Web/Tech — Marcus Tettmar @ 7:42 am

Way back in the deep and distant past when the Internet was new and Bill Gates thought it was just a passing fad, I remember reading about a Cola vending machine on a University campus that some frivolous young boffins hooked up to the ‘net so that you could check its inventory from anywhere in the world using an old fashioned network command called “finger”. Why? Because they could.

Fast forward to the technologies of the current day and the latest trend of Twitter, and history is repeating itself. In the last week I’ve read about a restaurant that can take orders via Twitter, a bakery tweeting the emergence of fresh loaves from the oven; and, utterly pointless, some guys who created a system which sends a tweet every time their cat enters or exits its cat flap. Why? Well, because they can I guess.

Not wanting to be left out I decided to write some Macro Scheduler code to tweet status updates and monitor replies. Why? Well there might be a good reason for being able to do this – I’m sure someone will have one. Perhaps you have a client who wants you to set up a system to monitor the movement of his cat, process restaurant orders, or your local baker wants an automated fresh-loaf tweeter! But mostly, it’s because we can.

You’ll find the Twitter API documentation here. Here’s the code to Tweet a status update:

Let>username=YOURTWITTERNAME
Let>password=YOURPASSWORD

//Tweet from Macro Scheduler
Let>url=http://%username%:%password%@twitter.com/statuses/update.xml
Let>message=Kitty just left the buildng
HTTPRequest>url,,POST,status=%message%,result

Being serious for a moment I can see how a macro that monitors an application might want to post status updates to Twitter, or a backup script could alert you by Twitter when there’s a problem. It might be a public system, but don’t forget that Twitter profiles can be made private too, and Tweets can be viewed on and sent from your BlackBerry, iPhone, or even by SMS.

The following script sets up a loop which monitors your Twitter stream for “mentions” of your username. This might form the basis of a script which retrieves orders. Perhaps it could listen to Twitter for commands and carry out actions based on what message was sent. Or perhaps you just want a macro which does something when a cat decides to head out for the night. Use your imagination.

Let>username=YOURTWITTERNAME
Let>password=YOURPASSWORD
Let>ini_file=%SCRIPT_DIR%\twit.ini
Let>_delay=30

VBSTART
VBEND

//monitor twitter username "mentions" loop
Label>monitor_loop

Let>url=http://%username%:%password%@twitter.com/statuses/mentions.xml
HTTPRequest>url,,GET,,result

//remove the  portion (I don't need it and it avoids distinguishing the text IDs from the user IDs.
RegEx>[^>](.*?),result,0,user_matches,nf,1,,result

//extract all texts
RegEx>(?<=)[^>]*?(?=),result,0,text_matches,num_texts,0
If>num_texts>0
  //extract all ids
  RegEx>(?<=)[^>]*?(?=),result,0,id_matches,num_ids,0

  //get last known
  Let>last_known_id=0
  IfFileExists>ini_file
    ReadIniFile>ini_file,SETTINGS,LAST_ID,last_known_id
  Else
    WriteLn>ini_file,wlnr,
  Endif

  //iterate through texts
  Let>k=0
  Repeat>k
    Let>k=k+1
    Let>this_id=id_matches_%k%
    If>this_id>last_known_id
      Let>msg_text=text_matches_%k%
      /*
      msg_text contains the message 
      Use your imagination here!
      For now we'll show it in a message
      */
      MessageModal>msg_text
    Endif
  Until>k=num_texts

  //store last ID
  EditIniFile>ini_file,SETTINGS,LAST_ID,id_matches_1
Endif

Wait>_delay
Goto>monitor_loop

The script retrieves the 20 most recent “mentions”. It stores the last seen ID in an INI file so that on the next check it ignores those it has seen before, only retrieving messages with a larger ID number.

This is a quick and dirty solution with no error checking, using RegEx to parse the XML that is returned by the call to Twitter. You may prefer to use the MS XML object as shown here.

Whether this proves useful or completely pointless, I hope you have fun. If you’re using Macro Scheduler with Twitter, please add a comment below to let us know how … and why!

Don’t forget you can follow me on Twitter where I may occassionally say something useful.

April 17, 2009

Working with Windows API Functions

Filed under: Scripting — Marcus Tettmar @ 9:43 am

Macro Scheduler‘s LibFunc command allows you to run functions contained inside DLLs.  A DLL, or Dynamic Link Library, is a file which contains functions that other programs can use.  Windows includes a number of DLLs containing lots of functions that make Windows tick, and other applications are able to call them.  These functions are known as the Windows API (Application Programming Interface). Using LibFunc a Macro Scheduler script can access some of these functions too.

The Windows API Reference can be found here:
http://msdn.microsoft.com/en-us/library/aa383749(VS.85).aspx

This provides a list of functions which you can browse alphabetically or by category.

Data Types

Before I go on I should mention data types.  Not every Windows API function can be used by Macro Scheduler.  This is because Macro Scheduler does not know about every possible Windows data type.  Macro Scheduler currently only knows about integers, long integers and strings. Almost any function that requires or returns integer and/or character based data can be called.  But anything that requires, for example, a record structure or a callback function can not be used.

The API documentation lists the Windows data types here:
http://msdn.microsoft.com/en-us/library/aa383751(VS.85).aspx

Many of these are based on the same fundamental data types.  E.g. all the HANDLE types are just unsigned numbers, so are supported by Macro Scheduler’s long integer.  LPTSTR and LPCTSTR are interchangeable with strings. From this list only CALLBACK and FLOAT are NOT compatible.

So, as long as the function requires or returns only bools, integers or strings, we should be able to use the function in Macro Scheduler.  Note that BOOLs are really just integers.  A BOOL is an integer with value 1 (true) or 0 (false).

An Example: CopyFile

Let’s look at a Windows API function and how we can use it in Macro Scheduler.

Take a look at the CopyFile function:
http://msdn.microsoft.com/en-us/library/aa363851(VS.85).aspx

At the top of the page we are told what this function does:

“Copies an existing file to a new file.”

We are then given the syntax.  You’ll notice that it is provided using C++ syntax.  It certainly helps if you know C++ but it is not essential and hopefully this example will help you understand what the syntax definition is telling us:

BOOL WINAPI CopyFile(
  __in  LPCTSTR lpExistingFileName,
  __in  LPCTSTR lpNewFileName,
  __in  BOOL bFailIfExists
);

The first thing this tells us is that CopyFile returns a BOOL (0 or 1).  Inside the parenthesis we see that the function requires three parameters.  The first two are of type LPCTSTR.  For our purposes this means it is a string.  The third parameter is a BOOL again.

We are then told what each parameter is for, what the function returns and various remarks.

While the names of the parameters are quite self explanatory the documentation gives us more detail.  So we can see that the first parameter lpExistingFileName represents the name of an existing file, lpNewFileName is what we set to the name of the new file we want to copy to, and bFailIfExists can be set to true (1) to make the function fail if the new file already exists or false (0) to overwrite.

We are told that the function returns zero if the function fails, or non zero if it succeeds.

DLL and Function Name

At the end of the page is some information crucial to us in the Requirements section.  This tells us which versions of the operating system support this function and what DLL it is contained in – Kernel32.dll in this case.  Note also that it tells us the alias names of the function.  In this case CopyFileA for the ANSI version and CopyFileW for the unicode version (Why “W” not “U” I hear you ask – W stands for WideString, a special form of string which can contain double byte characters).

So, putting it all together, we end up with the following LibFunc call:

LibFunc>kernel32.dll,CopyFileA,result,c:\source.txt,c:\my docs\new.txt,0

From left to right LibFunc takes the DLL name, then the function name, a variable which should return the result of the call and then the values to pass to the function. One thing to be aware of is that DLL function names are case sensitive. Make sure the function name is entered into the LibFunc command exactly as specified in the API documentation.

Try the above line with a real filename to see it in action.

Passing by Reference

Some DLL functions modify the values being passed to them.  Parameters are passed by reference rather than by value.  This means that what you’re really passing is a pointer to the memory address that stores that value, rather than just the value itself.  So when the function changes that value we can see the new value after the call. 

The way LibFunc handles this is that it puts each parameter value into an array, using the name of the return variable specified.  So if you specify the return value as “result” and the function takes 3 parameters LibFunc would return result, result_1, result_2, and result_3 where result contains the function result and result_1 to result_3 contain the values of the passed parameters which might have changed if the function modifies them.

Here’s an example of a Windows API function which returns data in a passed parameter:

http://msdn.microsoft.com/en-us/library/ms724373(VS.85).aspx

UINT WINAPI GetSystemDirectory(
  __out  LPTSTR lpBuffer,
  __in   UINT uSize
);

Note that the first parameter has the word “out” in front of it.  This signifies that its value is set by the function.  The function also returns an integer.  If we read the docs we see that the function writes the system directory in lpBuffer and returns the number of characters written to lpBuffer.

So I can use the following code to get the system directory:

LibFunc>Kernel32,GetSystemDirectoryA,dir,buffer,255
MidStr>dir_1,1,dir,sys_dir
MessageModal>System Directory: %sys_dir%

Note that I’ve set the return variable to “dir”. We can pass any old value in buffer, but I’ve used “buffer” here to make it obvious what it does.  Remember that LibFunc creates an array named after the result variable.  So we get “dir” containing the number of characters written to the buffer, dir_1 containing the buffer itself and dir_2 will just be 255 because that’s what we passed in but isn’t changed by the function as it is an “__in” parameter.

We set the maximum buffer size to 255.  So we need to extract only the characters returned, which is the reason why the function tells you how many characters it output.  So I’ve used MidStr to extract only those characters from the returned buffer.

Windows Constants

Many times we need to know the value of a Windows Constant.  The documentation for a function may refer to the name of a constant you need to use with the function.  E.g.:

ShowWindow
http://msdn.microsoft.com/en-us/library/ms633548(VS.85).aspx

BOOL ShowWindow(      
    HWND hWnd,
    int nCmdShow
)

The docs say that nCmdShow specifies how the window is to be shown and says it can be one of the following values: SW_FORCEMINIMIZE, SW_HIDE, SW_MAXIMIZE, SW_MINIMIZE, SW_RESTORE and so on.  These are Windows Constants.

In Windows development languages such as C++ and Delphi these constants are defined in the header files. In Macro Scheduler they are not defined, so we need to define them ourselves:

Let>SW_RESTORE=9

But, I hear you ask, how do I know that SW_RESTORE’s value is 9?  Well, if you have a development environment like Visual Studio or Delphi installed you can find out by searching the header files. 

However, if you don’t have this facility there’s a very handy free tool from Microsoft snappily titled “P/Invoke Interop Assistant” which contains a database of Windows functions and constants you can search.  You can download it from:

http://www.codeplex.com/clrinterop

Under the “SigImp Search” tab enter the constant you are looking for and it will tell you its value.

The Windows header files give the constant values in hexadecimal, so if obtaining them from the header files you will need to convert to decimal. The Windows Calculator is handy for doing this. “P/Invoke Interop Assistant” also shows the values in hexadecimal, but if you click the “Generate” button it will create C# or VB code with the value declared as an integer.

STDCALL Calling Convention

Finally, a note about calling conventions.  When a DLL is created the programmer can decide in what order parameters should be passed to the functions and who should clean up afterwards.  Windows API functions use the “stdcall” calling convention in which arguments are passed from right to left and the callee, i.e. the DLL, is responsible for cleaning the stack.  This therefore is the calling convention supported by LibFunc.  You don’t need to worry about this when calling Windows API functions.  But if you come to working with third party or custom DLLs, or ones you have created yourself, you will need to make sure the DLL uses the stdcall convention.

April 13, 2009

We can Automate Your Task

Filed under: Announcements, Automation, Scripting — Marcus Tettmar @ 8:01 pm

We don’t just sell great automation software.  We can also build your task for you.

If you don’t have the time, know-how or technical resource to automate your task yourself you might want to check out our new We Can Build It service.

We’ve been doing custom script development for years but have never actively promoted it as a separate service.  Now, with our We Can Build It service we can take a look at your process and automate it for you.

Many people reading this blog are already using and benefiting from Macro Scheduler and happily automating their tasks themselves.  If you’re one of those people you probably don’t need this service, but you may know someone else who does.  If so please pass this post on to them.  

For more information or to find out if your task is a candidate for automation click here.

April 1, 2009

WebRecorder 2.1 Update

Filed under: Announcements — Marcus Tettmar @ 1:47 pm

WebRecorder has been updated to version 2.1 with the following changes:

IEAuto.DLL (Runtime) Changes:

– CreateIE now ensures new IE window has focus

WebRecorder Changes:

– Support for Vista themes
– If a ClickTag element has no NAME recorder will use its ID if it has one, else will use numeric INDEX.  This helps to ensure more objects can be recorded and played back with less editing. 

Registered Downloads/Upgrades | Evaluation Downloads | New License Sales

Macro Scheduler 11.1.08 Update

Filed under: Announcements — Marcus Tettmar @ 11:01 am

Macro Scheduler 11.1.08 is now available with the following changes:

  • Added: GetTextReset – reset/initialise text capture functions
  • Fixed: Syntax highlighting: CR in CreateDir showing as CR system variable
  • Fixed: WLN_NOCRLF not included in syntax highlighting / sys var list
  • Fixed: Incorrect tab in macro properties being displayed on some data entry validation errors on save
  • Change: Hotkeys now ineffective while cursor is in type hotkey field of macro properties

Registered Downloads/Upgrades | Evaluation Downloads | New License Sales

March 29, 2009

MJT Net Gearhead Spotted in the New Forest

Filed under: General, Uncategorized — Marcus Tettmar @ 8:40 pm

If you were down in the woods yesterday you may have been in for a surprise. For in the New Forest, Southern England, you might have seen 400 participants of the first Questars Adventure Race of 2009, running, biking and canoeing.

MJT Net Adventure Race Team

Three of those people were sponsored by MJT Net and wearing our lovely new MJT Net Gearhead T-Shirts. We were not let down – the team came in 8th place in the Novice Mixed category. An excellent result for their first ever adventure race.

MJT Net Adventure Race Team

Congratulations to Angela Fulcher, Dan Spry and Tom Lloyd-Edwards, and thanks for wearing the T-shirts!

March 27, 2009

Macro Scheduler 11.1.07 Update Released

Filed under: Announcements — Marcus Tettmar @ 11:03 am

Macro Scheduler 11.1.07 is now available with the following changes:

  • Fixed: Separate failing to work if delimiter a variable in % symbols
  • Fixed: WebRecorder/VBScript web automation issues with IE8+Vista+UAC
  • Fixed: Added ‘ (apostrophe), Rem and Remark as valid comment tokens to syntax highlighter in editor
  • Fixed: Syntax parser highlighting recognised command names inside other commands
  • Fixed: Empty (“”) variable names can no longer be created. Any empty names ignored.
  • Fixed: SOWriteLn not adding line break
  • Added: Code folding support for For..Next, While..Wend, Do..Loop in VBScript

As you can see this release addresses the IE8+Vista+UAC issue discussed in my last post.

Registered Downloads/Upgrades | Evaluation Downloads | New License Sales

March 25, 2009

IE8, Vista, UAC and WebRecorder/VBScript Web Macros

Filed under: General, Vista — Marcus Tettmar @ 11:50 am

I just upgraded to IE8 on a new Vista desktop with UAC enabled out of the box. Now, WebRecorder macros and VBScript macros which automate Internet Explorer fail to work unless Macro Scheduler is run as Admin. IE’s Protected Mode is turned off, and “Allow scripting of Internet Explorer webbrowser control” is enabled. But if you try to run a WebRecorder macro without elevating Macro Scheduler to run as admin you will see a delay followed by:

Error Calling DLL – Possible wrong number or type of parameters.

If you try and run a VBScript macro which creates an Internet Explorer instance using CreateObject you will get the following error after a delay:

Microsoft VBScript runtime error :429

ActiveX component can’t create object: ‘InternetExplorer.Application’

This problem did not occur with IE6 or IE7.

If you run Macro Scheduler as administrator, or disable UAC everything works fine. To run Macro Scheduler as admin right click on the Macro Scheduler icon and select “Run as administrator”.

I have emailed the IE team at Microsoft to find out if there is any better solution. I will let you know what they say.


Update: No news from Microsoft but after lots of experimentation we discovered some very surprising things which don’t really make any sense, but have enabled us to make some changes in order to solve the problem. The next Macro Scheduler update will therefore have the above issues fixed.

March 23, 2009

Macro Scheduler Portable Installer Updated

Filed under: Uncategorized — Marcus Tettmar @ 1:01 pm

I’ve improved the Macro Scheduler Portable installer so that it now prompts for the drive letter you want to install on rather than default to Program Files which doesn’t make much sense for a portable install. It also grabs your license code from your full install so that you don’t need to enter it manually the first time you run the portable copy.

I’ve added the Macro Scheduler Portable Installer download to the plugins page.

It’s time to bring down IE6!

Filed under: General, Web/Tech — Marcus Tettmar @ 12:12 pm

Bring Down IE6

Some of you may remember that we had some issues with Internet Explorer 6 support when we released our new web site. I made some negative comments about IE6. And I was being polite. Unfortunately IE6 is still in use in millions of companies and, as I mentioned in that last post, some 35% of our web traffic is delivered by people using IE6. If it were up to me I’d banish it to web browser hell.

So I’m all for a new campaign from .Net magazine: Bring Down IE6.

If you have the power to do so, upgrade now, or try out Firefox or Google Chrome . If you’re working for a company that locks down their PCs and forces you to use IE6, get vocal – educate your colleagues and IT department. Petition them to lift you out of the dark ages! 🙂

Check out the site to see how you can get involved.