The Blog

TouchSmart Setup Wizard

My son, using touch

I just received my HP TouchSmart, and wanted to write down some of my first impressions. First off, this is one sexy computer (if a computer can be considered sexy). The screen is gorgeous, the design is very appealing, and the whole unit appears to be very well thought-out.

Configuration/Purchase/Shipping

I purchased the computer from HP directly (http://shopping.hp.com) because I had an employee discount through the EPP program. It saved me about three hundred dollars, and gave me nice discounts on the optional wall mounting hardware (I’m going to mount this in my kitchen). The computer was built, shipped and received in 7 total days, which was sooner than the estimates that HP gave me during the ordering process.

I made a custom configured model (IQ-800t) rather than going with the quick-ship options. The configuration wizard was slow but very clear. The only real change to the configuration was an upgraded graphics card. I cheesed out and did not get the BluRay player to save a few bucks.

Size and Weight

This computer is heavy, make no mistake about it. It is probably heavier than a similar sized 25.5” flat screen TV, and weighs about as much as my black lab, ~40 pounds.

The computer is pretty thick too. Without the stand on the back, it is around 3-3.5 inches thick, so if you are going to wall mount this thing, it may stick out as much as 4.5-5 inches from the wall with the mounting plate and adapter. Make sure you have studs to screw into if wall mounting.

IMG_4382

Computer Thickness

 

The power supply brick is huge. Certainly an issue if you are wall mounting, and you don’t have an outlet high up in the wall. You’ll have to run the wire down the wall and figure out how to hang the brick somewhere.

IMG_4378

Power Supply Size

The keyboard is very lightweight, compact, and thin. It’s thinner than my BlackJack phone with the extended battery in it. The mouse is a standard size for a wireless mouse.

IMG_4383

Keyboard Thickness

Setup

The computer and accessories are configured very well to “just work” out of the box. I set it up on the dining table, plugged it in, turned it on, and it started a configuration wizard. I wanted to avoid the keyboard and mouse and just use touch, but the very first Vista configuration screens did not support a tablet/touch interface for the text boxes for typing the username, password, and computer name.

IMG_4368

Touch does not work on these textboxes in the setup screen

I grabbed the keyboard, which already had batteries in it. All I had to do was pull out a sheet of plastic on the keyboard (it covered up the contacts on the batteries) and the keyboard was activated and recognized right away. No headaches with Bluetooth or anything.

Once through the wizards and at the login screen, the tablet input keyboard appeared and I could begin working almost exclusively with touch.

TV Tuner and Radio

I tried to configure the TV Tuner through Windows Media Center for over-air digital or analog signals but got no reception (digital) or just static (analog). I was hoping the unit had a built-in amplified antenna, but it looks like it will need rabbit ears or a separate wire attached to the coax input. I’m going to try to hook it up to the non-functioning cable TV connection in my house and see if that can be used as a suitable antenna.

One bummer, there is apparently no FM tuner. I read that the IQ7xxx series had an FM tuner, but the IQ8xxx series doesn’t seem to have one. Not sure why they left that out, so it looks like I’ll need to get a separate USB FM/AM tuner, as I do listen to the radio quite a bit.

DVD Player

I grabbed Toy Story 2 and threw it in the slot-load DVD player to see how easy it would be to just fire up a DVD for my son. I had the TouchSmart software up, and nothing happened when I loaded the DVD. I scrolled the list of applications and started the TouchSmart DVD application. This was an adequate app for playing the DVD, but didn’t have other features such as skipping to the menu, so I had to skip tracks to get past the trailers and into the main DVD menu. It was nice to touch the “Play Movie” link on the menu screen and have it start right up. Video quality was excellent. I think in general there will be some confusion on whether to use the TouchSmart applications for multi-media, or just use Media Center instead.

Games and Applications

There aren’t very many games installed, but one game, Purble Place, is just right for my three year old. There is a memory card game which my son picked up right away, and a fun game to create made-to-order cakes by touching the right color filling, icing, and packaging.

The TouchSmart shell has some nice applications. The Photos, Notes, and Weather apps are solid. I couldn’t get the calendar to sync with my Google Calendar though.

Usability of Touch

Overall I’m finding the touch aspect very usable. Resizing windows, clicking on buttons/hyperlinks, drag/drop all work really well.

Right-clicking within Vista is a little frustrating, as is copy/paste of text. There are some text boxes not well suited to touch input, for example:

  • The text boxes in the setup wizards (you’ll need the keyboard)
  • Some text boxes in Media Center (setting up your TV prompts you for your zip code, but no tablet input appears, so you have to use the keyboard or the remote control).
  • The Live Search box in the installed HP browser toolbar in IE doesn’t show the tablet input.

My son plays an online 3D game called Jump Start on our other desktop, and uses the arrow keys and mouse to move the character around. Using touch with this is very frustrating, because when you touch the screen the character moves around wildly, as opposed to the smooth movements with the mouse/keyboard.

 

So far I’m pretty impressed. My next step is to wall mount this thing…

This is an old one, but some co-workers ran into this again recently on a project.

When you have a SharePoint workflow that assigns tasks (either Designer or Visual Studio workflow), when you change the Assigned To column on the task list to allow Multiple Selections, your workflow will hang and become unresponsive when a user edits the task. You’ll receive a message about the task being locked (“This task is currently locked by a running workflow and cannot be edited”). OnTaskChanged events will no longer fire and your workflow will be stuck and unrecoverable.

There is no hotfix or workaround for this, so you simply cannot have the assigned to column support multiple users or groups. Just use a single group instead.

Following are some other resources discussing this:

I’ve just released a beta of xPollinate, my Windows Live Writer Cross Post Plugin.

You can download the installer at the CodePlex site, and I’ll shortly post it on the Live Writer plugin gallery.

As an example, I’ve used it to cross-post this entry to my old Blogger account, as well as via Ping.FM to my Twitter feed (status method) and as a full blog post to my Tumblog.

UPDATE 3/31/09: Plugin is now available on the Live Writer Gallery here.

I’ve seen several examples of creating document converters in SharePoint that convert documents to PDF format, using tools like Aspose and other print-based solutions.

I recently did a proof of concept for a customer that used a different product, Outside In PDF Export from Oracle. This is an interpretive converter that can take a slew of file formats (including MS Office) and automatically convert them into a PDF file. If you aren’t familiar with PDF conversion, there are two basic kinds:

  • Print based conversion – This is the Acrobat Distiller approach. Uses a printer driver that accepts the PostScript output from an application (such as Microsoft Word), and converts it to PDF. This approach results in the most accurate conversions, but is hardest to automate because it involves opening the native application and automating its “Print” functionality.
  • Interpretive conversion – This is an approach that reads the contents of a native file format and translates the contents into PDF format. This results in potentially less accurate conversions, but is much easier to automate.

Outside In, and in particular the PDF Export SDK, is an EXE and set of DLLs that contains logic to covert over 400 different file types to PDF. In combination with Transformation Server (a web services wrapper to PDF Export), you can create SharePoint Document Converters that will convert your documents to PDF format.

How I Did It

For the proof of concept, I followed these steps to get it working

  • Download PDF Export, Transformation Server, and SrvAny.exe.
  • Install and Configure the Transformation Server and Web Service
  • Develop and Install the Document Converter

Download of PDF Export 8.3.0 and Transformation Server 8.2.0

You can download both products here:

http://www.oracle.com/technology/products/content-management/oit/oit_dl_otn.html

You’ll have to register with an Oracle account to get it, but it is a freely available trial version, and does not appear to have any trial expiration limitations.

You will also need SrvAny.exe to run Transformation Server as a Windows Service. I found this site that had a download:

http://www.tacktech.com/display.cfm?ttid=197

Install and Configure the Transformation Server and Web Service

Extract the contents of the Transformation Server zip you downloaded to a folder on your server that will do the document conversions (e.g. “C:PDFConverter”). There will be a bunch of dlls, some wsdl files (we’ll use those later), some EXE’s (which are run as a service), and some XML config files.

Transformation Server doesn’t really know anything about PDF generation, it is just a web service wrapper, so we’ll need to place the PDF Export library into our folder so it can use it. Extract the contents of PDF Export 8.3.0 to a separate folder on your machine. Grab every DLL in the root folder, as well as exporter.exe, px.cfg, and cmmap000.bin and copy those files into “C:PDFConverter”.

Open the file called server_startup.xml in “C:PDFConverter”. This configures the service to listen on a specific port and hostname/ip address. I went ahead and changed the port, but you can leave it as is if you wish, just make note of the port for later:

<!--Connections are the TCP/IP socket connections that the server accepts from clients.-->
<connectionsInfo xsi:type="tss:ConnectionsInfo">
    <!--The serverName is the host name, or dotted IP address that the server will use when establishing its presence on the network.-->
    <serverName xsi:type="xsd:string">localhost</serverName>
    <!--The port is the TCP/IP port that the server will establish a listener on for accepting connections.-->
    <port xsi:type="xsd:unsignedInt">9000</port>
    <!--The server will disconnect idle connections that have remained idle for too long. The activityTimeout sets the period of time a connection must be idle before it will be disconnected by the server.-->
    <activityTimeoutSecs xsi:type="xsd:unsignedInt">1800</activityTimeoutSecs>
</connectionsInfo>

Go ahead and double-click tsmanager.exe to make sure it is working. It should open a console window and show you what host/port it is listening on.

tsmanager console

Press Ctrl + C to quit.

Now we need to run this program as a service, so that it is always available, even when nobody is logged on to the server. Place instsrv.exe and srvany.exe in your C:PDFConverter folder. Run the following command prompt:

C:PDFConverter>instsrv.exe "Transformation Server" c:PDFConvertersrvany.exe

The service was successfuly added! Make sure that you go into the Control Panel
and use the Services applet to change the Account Name and Password that this
newly installed service will use for its Security Context.

Open regedit, and browse to HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesTransformation Server.

Create a new key called Parameters, and add a new string value inside this key called Application, with a value of C:PDFConvertertsmanager.exe.

ts registry entries

Go to the services console and start the Transformation Server service. Optionally, you can also go to the Properties for this service account, and change the Identity that this service runs under.

Develop the Document Converter

Create a new .NET C# console application project and solution from within Visual Studio 2008, called PDFConverter.

Right-click the project in Solution Explorer and choose Add Service Reference…

Since the wsdl files for Transformation Server are not compliant with WCF services, choose the Advanced… button on the Add Service Reference dialog, and then choose the Add Web Reference… button to add a .NET 2.0 style web service reference. In the Add Web Reference dialog, enter the path to the wsdl file: C:PDFConvertertransform_net_2005.wsdl. Hit Go.

Once your web reference has resolved, enter TransformationServer in the Web reference name box and click the Add Reference button.

Open your Properties/Settings.settings file. There will be one setting in the file for the web service URL. Change this to the right hostname/port in your server_settings.xml for Transformation Server. Make sure to include a trailing “/transform” on the end, e.g.:

https://grey-frog-177824.hostingersite.com/transform

A document converter is just a console EXE that is called by SharePoint with command line arguments, so we’ll setup our console app to handle the arguments. In Program.cs, before static void Main, add the following code (taken from the WSS SDK here):

#region Argument Handling Data
 
private enum ArgumentCode
{
    Help,
    InputFile,
    OutputFile,
    LogFile,
    ConfigFile
}
 
private struct ArgumentPair
{
    public ArgumentPair(ArgumentCode c, string s)
    {
        this.argType = c;
        this.argFlagString = s;
    }
 
    public ArgumentCode argType;
    public string argFlagString;
}
 
private static ArgumentPair[] PossibleArguments = new ArgumentPair[] {
    new ArgumentPair(ArgumentCode.Help, "-?"),
    new ArgumentPair(ArgumentCode.Help, "-help"),
    new ArgumentPair(ArgumentCode.InputFile, "-in"),
    new ArgumentPair(ArgumentCode.OutputFile, "-out"),
    new ArgumentPair(ArgumentCode.LogFile, "-log"),
    new ArgumentPair(ArgumentCode.ConfigFile, "-config"),
};
 
private static Dictionary<ArgumentCode, string> actualArguments = new Dictionary<ArgumentCode, string>();
 
#endregion
 
/// <summary>
/// Prints out the usage help to the console.
/// </summary>
static void PrintUsage()
{
    Console.WriteLine("Usage: {0} -in <inputfilename> -out <outputfilename> -config <configfilename> [-log <logfilename>]",
                      Assembly.GetExecutingAssembly().ManifestModule.Name);
}

Add the following code inside static void Main:

#region Argument Handling Code
// Read arguments.
for (int i = 0; i < args.Length; i++)
{
    bool argumentValid = false;
    foreach (ArgumentPair ap in PossibleArguments)
    {
        if (String.Compare(ap.argFlagString, args[i], StringComparison.OrdinalIgnoreCase) == 0)
        {
            switch (ap.argType)
            {
                case ArgumentCode.Help:
                    PrintUsage();
                    return;
 
                case ArgumentCode.InputFile:
                case ArgumentCode.OutputFile:
                case ArgumentCode.ConfigFile:
                case ArgumentCode.LogFile:
                    if (i + 1 < args.Length)
                    {
                        actualArguments[ap.argType] = args[i + 1];
                        i++;
                        argumentValid = true;
                    }
                    break;
            }
            break;
        }
    }
 
    if (!argumentValid)
    {
        Console.WriteLine("unknown argument {0}", args[i]);
        PrintUsage();
        return;
    }
}
 
// Validate arguments.
if (!actualArguments.ContainsKey(ArgumentCode.InputFile) ||
    String.IsNullOrEmpty(actualArguments[ArgumentCode.InputFile]) ||
    !actualArguments.ContainsKey(ArgumentCode.OutputFile) ||
    String.IsNullOrEmpty(actualArguments[ArgumentCode.OutputFile]) ||
    !actualArguments.ContainsKey(ArgumentCode.ConfigFile) ||
    String.IsNullOrEmpty(actualArguments[ArgumentCode.ConfigFile]))
{
    Console.WriteLine("required argument missing");
    PrintUsage();
    return;
}
 
#endregion

Now that the command line arguments can be parsed, it is time to use the web service and do the document conversion. The Transformation Server download contained some code samples for C#, and I was able to basically use as-is, only modifying the input and output file paths. After the argument handling code in static void Main, add the following code:

TransformationServer.transform t = new TransformationServer.transform();
 
TransformationServer.IOSpec source = new TransformationServer.IOSpec();
source.spec = new TransformationServer.stringData();
source.spec.base64 = false;
source.spec.charset = TransformationServer.CharacterSetEnum.windows1250;
source.spec.str = actualArguments[ArgumentCode.InputFile];
source.specType = "path";
TransformationServer.IOSpec sink = new TransformationServer.IOSpec();
sink.spec = new TransformationServer.stringData();
sink.spec.base64 = false;
sink.spec.charset = TransformationServer.CharacterSetEnum.windows1250;
sink.spec.str = actualArguments[ArgumentCode.OutputFile];
sink.specType = "path";
string outputFormat = "pdf";
string optionSet = "";
TransformationServer.Option[] options = new TransformationServer.Option[0];
TransformationServer.stringData resultMsg;
TransformationServer.IOSpec[] resultDocs;
UInt32 result = t.Transform(source, sink, outputFormat, optionSet, options, out resultMsg, out resultDocs);
Console.WriteLine("The result is {0} {1}", result, resultMsg.str);
foreach (TransformationServer.IOSpec ios in resultDocs)
{
    ASCIIEncoding encoding = new ASCIIEncoding();
    string constructedString = encoding.GetString(Convert.FromBase64String(ios.spec.str));
    Console.WriteLine(" {0}", constructedString);
}

Most of this code is cut-and-paste from the sample, and we are just swapping the input file path (source.spec.str) and output file path (sink.spec.str) with the arguments from the command line.

Installing the Converter

To install the converter, you need to create a feature file, install the feature, and place the converter EXE in the proper directory.

Create a feature.xml file and add the following:

<Feature xmlns="http://schemas.microsoft.com/sharepoint/"
    Id="{9E2A5231-0D81-4de8-8504-36A61026680E}"
    Title="PDF Converter"
    Description="PDF Converter."
    Scope="WebApplication">
  <ElementManifests>
    <ElementManifest Location="Elements.xml"/>
    <ElementFile Location="PDFConverter.exe"/>
  </ElementManifests>
</Feature>

Create an Elements.xml file, and add the following code. You can create as many document converter nodes as you need for each file type you want to convert (just make sure each has a unique guid).

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <DocumentConverter Id="{513130EB-A1BC-46d3-919C-1E00B6BCA742}"
      Name="DOCX to PDF Converter"
      App="PDFConverter.exe"
      From="docx"
      To="pdf"
    />
  <DocumentConverter Id="{E7374437-157E-4fb4-A4E9-A19026BAE17A}"
    Name="VSD to PDF Converter"
    App="PDFConverter.exe"
    From="vsd"
    To="pdf"
    />
</Elements>

Place both these files in a folder called PDFConverter in your …/12/TEMPLATE/Features folder, and use stsadm to activate the feature on a particular web application.

C:Program FilesCommon FilesMicrosoft Sharedweb server extensions12BIN>stsadm
-o installfeature -name PDFConverter

Operation completed successfully.

C:Program FilesCommon FilesMicrosoft Sharedweb server extensions12BIN>stsadm
-o activatefeature -name PDFConverter -url http://mossdev:8080

Operation completed successfully.

After activating the feature, go to Central Administration, Applications tab, and click the Document Conversions link. Ensure that your web application has document conversions turned on. You should see your document converters in the list at the bottom of the screen:

Document Conversion Settings

Since you are using a Web Service, a proxy class needs to be generated dynamically, and so you’ll need to give your SharePoint Document Conversion User Account rights to create this in C:WindowsTemp (or whatever your system temp directory is). Grant List Folder Contents and Read permissions to the Document Conversion account (usually a local machine account that starts with “HVU_”) on your Temp folder.

The Document Conversion service stores temporary documents in the following folder: C:Program FilesMicrosoft Office Servers12.0BINHtmlTrLauncher. By default, this folder only grants the Document Conversion User account access. Since the Transformation Server windows service is running under its own account, you need to give this account access to the folder. Grant the account that your Transformation Server windows service is running under Read and Write access to this folder.

The last step involves copying over your compiled console EXE and exe.config file into the following SharePoint folder (the actual path may vary depending on your setup, but you should be able to find the TransformApps folder):

C:Program FilesMicrosoft Office Servers12.0TransformApps

Results

Navigate to your SharePoint site. Upload a document into your document library (make sure it is a file extension that you’ve configured in your Elements.xml file). Open the drop down menu and choose Convert Document. Your document converter should appear in the list. Run the conversion. After around a minute if you refresh your document library and all went well, you should see your PDF file in the library.

Generated PDF in document library

Here is a picture of a generated Visio document in PDF format, not too bad:

exported visio file

I am just finishing up the touches on my first Windows Live Writer plugin, which I’m calling xPollinate. I’ve wanted to cross post to multiple blogs as well as Ping.FM from Windows Live Writer, and originally I found this plugin by Daniel Cazzulino that was not perfect, but got the job done.

I used this plugin as a basis and then added a bunch of bells and whistles that I wanted. Following are some feature enhancements that I’ve added:

  • Cross post to multiple blogs at the same time
  • Choose blogs to post to at cross post time
  • Set plugin defaults through the options dialog, and override at posting time.
  • Ability to turn comments and trackbacks (pings) on/off at the cross posted blog
  • Add header or footer html to each cross posted entry
  • Cross post to Ping.FM
    • Supports triggers and services
    • Post using blog, microblog, or status methods, simultaneously or individually

Here are some screen shots:

The Blogs Tab:

xPollinate Blogs Tab

This enables you to select multiple blogs to cross post to. You can optionally post a summary, and include header and footer text.

The Ping.FM tab:

xpollinate-options-ping-large-triggers

This enables you to post your blog entry via Ping.FM to your configured services. You can post a full or summarized version to your Ping.FM blogs, and can post a notification to your Ping.FM status and microblog services. The format of the notification is customizable.

Left to Do

I’ll be releasing this as a free plugin to the community, and will release the source as well. The final few things I have left to do are:

  • Clean up the installer
  • Get a public API key from Ping.FM
  • Submit to the Live Writer plugin gallery