Wednesday, 13 April 2011

System.Net.HttpWebRequest and PowerShell, part 1

Consider this scenario: You have a system written in .NET which produces reports in some well defined format: Excel, Access, etc.  To download these files, you fire up an IE window via the Internet.Application API, login to the application, navigate to the report and use the Click() method of the Button or Image element to fire off a post request.  This ensures that the hidden fields a .NET application may produce, such as the VIEWSTATE, as well as cookies, are preserved.

This works well, with the caveat that the user of the machine gets prompted for where to save this file.  You want to automate the download of the file to save it in an already defined location, to save the time waiting for the user to save the file and close the window.

You check the documentation for IE's automation API, only wind up disappointed.  You cannot automate the saving of the file via the InternetExplorer.Application interface, or any other interface that allows access to the mshtml API.  What then to do?

Well, luckily Microsoft's .NET API contains a class known as System.Net.HttpWebRequest, which allows you to send GET or POST requests to a server, and to manage cookies.  So if you can parse the HTML returned by this API, and extract the hidden input fields described above to repost to the server, you can read back the file that the server returns and save it.

To do this in Powershell however, requires some understanding of .NET. Lets take a look at a simple function to return a HTML response from a server.

function Get-HTML-Response {
  param($uri,$cookiejar);
  $req=[System.Net.HTTPWebRequest]::Create($uri);
  $req.CookieContainer=New-Object System.Net.CookieContainer;
  $req.Method='GET';
  if ($cookiejar -ne $null) {
    $req.CookieContainer=$cookiejar;
  }
  $req.UserAgent='Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)';
  $resp=$req.GetResponse();
  $strm=$resp.GetResponseStream();
  $sr=New-Object System.IO.Streamreader($strm);
  $output=$sr.ReadToEnd();
  return @($req,$resp,$output);
}

The .NET 2.0 API allows you to create a HTTPWebRequest object directly from a URI via the Create method.  All we need to do is setup the User-Agent, method, and cookie store; then read back the response and return all the information to our script.

Note that this function does not deal with exception handling... if you want to do this (and you should care about exception handling), the documentation for the exceptions the above functions can return are available via the MSDN website.

To ensure that we can provide continuity between requests, we provide the option to pass a CookieContainer containing Session Info to the function, to communicate through to the server.

The response returned by GetResponse contains header information, including the status code returned by posting to the server.  You'll want to check this to ensure 200/OK status.  The request object's cookies are automatically updated by the process of submitting the request and returning the response.

Calling GetResponseStream on the request object, on checking it for consistency, will return a Stream object containing any textual output from the server (the server response or page content).  You  need to read this stream in using a Streamreader object or pass the stream to some other object that will deal with the information contained in it.  In this instance, we just return the output.

In the next installment, I'll discuss POST requests, and finally, HTML parsing and interpretation of the data.

Monday, 11 April 2011

Creating Styles with Storyboard Animation in Powershell

Here is an example of an event trigger which animates the color of a textbox on the MouseEnter event firing.

$trigger1=New-Object Windows.Eventtrigger([Windows.Controls.Textbox]::MouseEnterEvent);
$trigger1.Actions.Add((New-Object windows.Media.Animation.BeginStoryBoard));
$bsbitem=$trigger1.Actions.Item(0);
$bsbitem.StoryBoard=New-Object windows.Media.Animation.StoryBoard;
$bsbitem.StoryBoard.Children.Add((New-Object windows.media.animation.coloranimation([Windows.Media.Colors]::LightBlue,[Timespan]::FromSeconds(1))));
[Windows.Media.Animation.StoryBoard]::SetTargetProperty($bsbitem.StoryBoard.Children.Item(0),[Windows.PropertyPath] "Background.Color");
$styletxtbox.Triggers.Add($trigger1);

Several things should be noted:
  1. You create the EventTrigger using the associated event from the type you are animating.
  2. $styletxtbox is a Windows.Style object.
  3. The trigger events mouse be events derived from Windows.TriggerAction.  This means they must be either wrappers for a Storyboard, or a SoundPlayerAction.  You can use Keyframes to quickly change a color, or use the smooth transitions defined in the inheritance hierarchy for Windows.Media.Animation.Animationtimeline
  4. Set the property operated on  via [Windows.Media.Animation.StoryBoard]::SetTargetProperty.
The question might be raised, why not just use XAML and save yourself all the trouble?  Well, there are several answers to that, most of which focus around.
  • The wastefulness of dynamically generating XAML code for a dynamic form, parsing it and creating the objects VS just creating or manipulating the objects involved directly.
  • The capacity to easily reference every one of the elements of the form as a variable, for instance in writing event handlers.
The key here is to understand when it is necessary to use either declarative or procedural methodologies in evolving the objects.  Dynamic flexible data calls either for procedural design, or data templating, whichever fits more with your design methodology.  WPF supports both.

Sunday, 10 April 2011

Raison d'ĂȘtre

  • LiveJournal is dead.  Long live LiveJournal!
  • Facebook is facile, and unsuited to deep conversation.  Your actions are on display.
My reasons for starting this blog are varied. The first is philanthropic, to the programming community at large. I've been a programmer, system administrator or customer support person since 1998, on and off in various positions. What I've learned about programming, interface design, and the pros and cons of different programming methodologies during this time has helped me evolve... from the small intricacies of Perl/CGI based programming in the earlier years, to fully fledged timer driven UI-design in .NET.  I want to share some of the painful experiences and revelations based on experience I've had since starting this path, as there is a lack of information on particular topics in the area for instance of WPF based design, Windows Forms, Silverlight and so on.

I come originally from a Linux background, but as a programmer I have found the most joy in the abstraction that Powershell and the various Windows Interop DLLs presents to me.  Why?  Nothing that I am aware of in the Unix environment at present allows such a level of integration between existing programs and scripts, to the extent that one can cut and paste data from a spreadsheet to an automatically created email in 5 lines or less of code.  Microsoft it seems, made a very wise business decision in providing the level of abstraction they have in their products, such as Word, Outlook and Excel, as well as Access.  The ability of programs to access well defined API's to create Word documents, interact with Outlook's calendar or mail merge faculties, and more, when combined with the .NET based scripting which Powershell provides, presents to the programmer:
  • Rapid development based on models including extreme programming and functional programming.
  • The ability to abstract the development process and allow for easy customization of a UI via text  (whether in centralized INI files or the registry).
Why is this so important?  Well, for one it makes for a rapid development lifecycle, the ability to test code straight from the command line without need for lengthy recompilations of code.  Powershell's seamless ability to create background runspaces in CTP2 means the ability to create multithreaded, responsive applications.  Secondly, it means abstraction, along the lines of that abstraction which LISP originally provided in the early days of Unix.  Powershell's Invoke-Expression, as well as its quick access to function definitions direct within the environment, when combined with easy GUI design, makes it possible to embed REPL's within code for ease of testing and debugging.   It even makes it possible for Powershell code to write, test and then save or edit code in a language, in short, to create an IDE within the language itself, in a very small number of lines, to enhance the already formidable powers of the ISE.  Scenarios such as that seen in the movie Swordfish start coming out of the realm of fiction and into the realm of quite possible FACT.

So that is one reason for the creation of this blog - the exploration of how to go from 0 to 360 in the realm of GUI based programming in this area, within months.  At times I may also discuss topics that are best described as philosophical... the connections between abstraction and evolution, pros and cons of different types of abstraction, perhaps even futurist topics (or their nemesis, survivalism).  The topic is anything that interests me, and if you don't like a post, you don't have to read it.  Thats the beauty of free-will.

I have many interests, but this one will be mainly restricted to programming, abstraction, and topics related to evolution (especially as it relates to continuum or catastrophe theory).

With that in mind, lets begin!