Programming Microsoft's Publishing Wizards
July 1st, 2003
Microsoft XP includes some nifty “wizards” to upload files to a web site, or to order prints of digital photos. And of course, the available choices are limited to Microsoft’s properties and partners, like MSN and xDrive.
With those options, you can select a series of files and/or folders and upload them to a website (like MSN or xDrive), or select some pictures and send them to an online photo processing service.
Well… it turns out that you can create your own wizards.
(Este artículo también está disponible en español)
Microsoft XP includes some nifty “wizards” to upload files to a web site, or to order prints of digital photos. And of course, the available choices are limited to Microsoft’s properties and partners, like MSN and xDrive.
With those options, you can select a series of files and/or folders and upload them to a website (like MSN or xDrive), or select some pictures and send them to an online photo processing service.
Well… it turns out that you can create your own wizards.
Altough Microsoft has some documentation available, it is not what you would call “complete” or “easy to understand”. It is missing some links, divided in pieces, has no examples and is definetively incomplete.
It seems like they made it available, but expect “real companies” to get some direct help from Microsoft when implementing it for real. After all, if you’re paying Microsoft to include your service in the wizard’s list, you can expect some support.
But I don’t want to pay, and that’s why I decided to write this document.
The wizards are nothing more than web pages with some specific javascript calls. And to make your “service” show up in the list, all you need is some registry entries.
Registering your service
This is the easy part. Wizards are listed on the registry, under the following keys:
HKEY_CURRENT_USER\Software\Microsoft\Windows
\CurrentVersion\Explorer\PublishingWizard
\InternetPhotoPrinting\Providers\{YourNameHere}
For “Order prints online”, and:
HKEY_CURRENT_USER\Software\Microsoft\Windows
\CurrentVersion\Explorer\PublishingWizard
\PublishingWizard\Providers\{YourNameHere}
For “Publish to the Web”.
In either case, you need the following entries (all of them Strings):
DisplayName: First line of text in the listing Description: Second line of text in the listing Icon: URL to the icon (.ico file) for the listing HREF: URL of the first page of the wizard SupportedTypes: (optional) Wildcard filter for acceptable filenames (i.e. ”*.jpg”)
The easiest way to create these entries is with a REG file like this one:
Windows Registry Editor Version 5.00 [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\PublishingWizard\PublishingWizard\Providers\MyOwnProvider] "Icon"="http://www.example.com/myprovider/myicon.ico" "DisplayName"="My very own provider" "Description"="This is my own provider, free and customized" "HREF"="http://www.example.com/myprovider/wizard.php"
Put that text into a file like “myprovider.reg”, double click it, and it’s done… you have your own wizard registered on the list.
Your Service Wizard Page
This is the hard part. It involves dynamic pages on the server side (like ASP, PHP, JSP or anything you like) along with Javascript code on the client side.
The page runs inside the wizard window, and it’s expected to have 3 javascript functions, OnBack, OnNext and OnCancel, or else the wizard will not load it.
Those functions will be called whenever the user presses one of the three buttons on the bottom of the wizard.
There are two useful functions to control the wizard window (their meaning should be obvious):
window.external.SetWizardButtons(activatePrev, activateNext, isLastPage);
and
window.external.SetHeaderText(firstLine, secondLine);
And there are two functions you can call to “finish” the Wizard process:
window.external.FinalBack();
and
window.external.FinalNext();
You call FinalNext() from inside OnNext() to signal the wizard you are done asking questions and are ready to transfer the files. The next time the user clicks on “Next”, the wizard will proceed to upload the files.
And you call FinalBack() from inside OnBack() whenever you are on the “first page” of your process. (If that’s too complicated for you, simply call it all the time on OnBack()).
Uploading the files
So far, nothing is really hard. The real problem is the upload process.
See, before calling your page, the wizard created an XML file with a list of all the files to be uploaded. And you can access it through:
window.external.Property("TransferManifest")
The XML looks something like
<transfermanifest>
<filelist>
<file id="1" source="C:\My Documents\File1.jpg" destination="File1.jpg" .../>
<file id="2" source="C:\My Documents\Other File.jpg" destination="Other File.jpg" ... />
</filelist>
</transfermanifest>
If you do nothing, then the wizard will not upload any file. You need to “edit” that XML document to add information about how to upload the files and where.
You have two methods: WebDAV and POST File Uploads.
I haven’t played with WebDAV, so I’ll leave it as an exersice to the reader.
For File Uploads, you need the
<transfermanifest>
<filelist>
<file id="1" source="C:\My Documents\File1.jpg" destination="File1.jpg" ...>
<post href=http://www.example.com/myprovider/acceptfile.php name="myfile">
<formdata name="OtherFormVar">Some Value</formdata>
<formdata name="action">Save</formdata>
</post>
</file>
<file id="2" source="C:\My Documents\Other File.jpg" destination="Other File.jpg" ... >
<post href=http://www.example.com/myprovider/acceptfile.php name="myfile">
<formdata name="OtherFormVar">Some Value</formdata>
<formdata name="action">Save</formdata>
</post>
</file>
</filelist>
<uploadinfo>
<htmlui>http://www.example.com/myprovider/seeyourfiles.php</htmlui>
</uploadinfo>
</transfermanifest>
If you haven’t done POST File Uploads in regular web pages before, then you need to figure that out first.
The
All those tags are pretty much equivalent of the following HTML page being submitted once for each file:
<form method="POST" encoding="multipart/form-data" action="http://www.example.com/myprovider/acceptfile.php"> <input type="hidden" name="OtherFormVar" value="Some Value"> <input type="file" name="myfile"> <input type="submit" name="action" value="Save"> </form>
The
All the “editing” of the XML data has to be done using Microsoft’s XML DOM, but it’s not that hard. Here is some sample Javascript code to create the desired results:
var xml = window.external.Property("TransferManifest");
var files = xml.selectNodes("transfermanifest/filelist/file");
for (i = 0; i < files.length; i++) {
var postTag = xml.createNode(1, "post", "");
postTag.setAttribute("href", "http://www.example.com/myprovider/acceptfile.php");
postTag.setAttribute("name", "myfile");
var dataTag = xml.createNode(1, "formdata", "");
dataTag.setAttribute("name", "MAX_FILE_SIZE");
dataTag.text = "2000000";
postTag.appendChild(dataTag);
var dataTag = xml.createNode(1, "formdata", "");
dataTag.setAttribute("name", "action");
dataTag.text = "Save";
postTag.appendChild(dataTag);
files.item(i).appendChild(postTag);
}
var uploadTag = xml.createNode(1, "uploadinfo", "");
var htmluiTag = xml.createNode(1, "htmlui", "");
htmluiTag.text = "http://www.example.com/myprovider/seeyourfiles.php";
uploadTag.appendChild(htmluiTag);
xml.documentElement.appendChild(uploadTag);
January 31st, 2008 09:23 AM var postTag = xml.createNode(1, "post", ""); postTag.setAttribute("href", "http://wherever"); postTag.setAttribute("name", "userfile"); This is how to manipulate the Transfermanifest 4 the upload. Greetings Marco
January 31st, 2008 09:23 AM Hi! I got a real problem! Can you look at it and tell me whats wrong with it?
January 31st, 2008 09:23 AM Hi Im trying to create a wizard like here is described but I cant make it post the files. Can somebody send an example of the javescripts that are modifying the manifest.xml document. Thanks :) SSigurdarson
January 31st, 2008 09:23 AM Excellent!! Thanks!
January 31st, 2008 09:23 AM Hi, Is it possible for anyone to tell me how to write a function in asp or prefferable asp.net which will act to upload the files?
January 31st, 2008 09:23 AM Sebas, if its not too much to ask, can you also make a PDF version of this article, for offline viewing, you know, for guys like me, the broadband-impaired bunch ;) Thanks, if not, I'll just save the page...
January 31st, 2008 09:23 AM Timo (and all), I have a similar issue as you. My coppermine xp wizard won't connect after I select the icon. I guess you get father than me. If you find the answer, would you let me know! Thanks.
January 31st, 2008 09:23 AM hi, how can i had the <successpage> ??? thanks