One thing I always wanted to add to the Cognifide PowerShell Console for Sitecore but never had the chance to investigate properly, was GUI and user interaction. For example in a regular PowerShell console when an irreversible action needs to be taken or one that user needs to be notified about ? a question is asked:

image

Unfortunately due to the stateless and non-persistent nature of HTTP connections this is not easily achievable in Sitecore Sheer environment especially since in our case a PowerShell session usually lives in a separate thread within a Sitecore Job.

I knew this had to be achievable as Sitecore allows for rich interaction with user e.g. during a package installation process but I could not find any documentation regarding this subject, and my Sitecore gurus? posts were pretty discouraging in that regard:

But heck(!) Somehow the package Installer manages to show those pesky Overwrite/Merge/Skip dialogs, right?

image

Not discouraged by the early discoveries, I?ve dusted my trusty copy of Reflector and dived inside the installer code. Following are the findings of my investigations and sample solutions for using them with your Jobs.

JobMonitor

The key role in the asynchronous communication between Job and Sheer UI plays the JobMonitor control. For your job to be able to talk with your dialog you need to place this control on your dialog which you can do the following way. Add the namespace JobMonitor lives in to your code:

using Sitecore.Jobs.AsyncUI;

Now add JobMonitor as a field to your Sheer dialog/control:

protected JobMonitor Monitor;

Now we need to instantiate and use the control. For that modify the OnLoad method in your dialog to include the following:

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);

    // your code ...

    if (Monitor == null)
    {
        if (!Context.ClientPage.IsEvent)
        {
            Monitor = new JobMonitor {ID = "Monitor"};
            Context.ClientPage.Controls.Add(Monitor);
        }
        else
        {
            Monitor = Context.ClientPage.FindControl("Monitor") as JobMonitor;
        }
    }

    Monitor.JobFinished += MonitorJobFinished;
    Monitor.JobDisappeared += MonitorJobFinished;

    // more of your code ...
}

Where JobMonitorFinished is a delegate called when the asynchronous task is finished. Now all you need to do in your code to start using the JobMonitor is to run your code in its context:

Monitor.Start("MyJobExecution", "UI", jobRunner.Run);

where jobRunner is an instance of my class that contains any parameters I need for my Job to run. as well as a pointer to your method, but it can as well be containing the code of the job itself. JobMonitor now takes and executes the ?Run? method in a new asynchronous Job context. It will also poll the job for any messages and execute them periodically.

Executing UI commands from the Job

Now from the Job context point of view you signal JobMonitor to do stuff for you by sending Messages. You can do some stuff pretty easily like execute the following to show an alert to your user:

JobContext.Alert(Title);

or as for confirmation in the following way:

string response = JobContext.Confirm(?Would you like fries with that??);

If you want to show do some more elaborate things you might want to either use the following to send a command message and retrieve response:

string response = JobContext.SendMessage(?my:command?);

But if all you want to do is execute a command you can as well use:

string response = JobContext.PostMessage(?my:command?);

to post the message asynchronously and ignore the results.

You can even show dialogs using something like the following (even including parameters to the dialog):

JobContext.ShowModalDialog(parameters, "ConfirmChoice", "800", "300");

and retrieve a response from it. Which finally brings us to the Powershell interactivity that was introduced in the latest console using this technique?

image

I strongly encourage you to look into the Cognifide PowerShell Console for Sitecore code available on CodePlex. For further investigation on techniques you could employ for some more advanced usages (like sending an item to your dialogs and such. The console available on Sitecore Marketplace now already has this functionality in it and you can use this in multiple ways in commandlets starting with the word Show, like:

  • Show-Alert
  • Show-Confirm
  • Show-Input
  • Show-ModalDialog
  • Show-YesNoCancel

To find out the latest commandlets in the further versions of console and to find out what parameters each of them can supports execute the following script:

Get-Command Show-* | ft Definition

There, now we have Asynchronous Job-UI communication documented? somewhat. Hope this helps somebody.

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading...



This entry (Permalink) was posted on Thursday, May 16th, 2013 at 12:21 am and is filed under .Net Framework, ASP.NET, Code Samples, PowerShell, Sitecore, Software Development, Solution, Web applications. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response , or trackback from your own site.