Tuesday 3 March 2009

Running Visio SaveAsWeb in a web application or service

There are many reasons why you should not run Microsoft Office applications from inside a web application or service. But if you really want to do it anyway, here's what you need to know to use Visio SaveAsWeb on Windows Server 2003.


Create a new windows user. The Application Pool that your web application runs under will be using the Network Service account in its identity settings by default. Change this so that your Application Pool uses a custom identity account that you have created.


Add your new user to the local IIS_WPG group. Verify that Local Security Policy > Local Policies > User Rights Assignment > Log on as a service grants this role to IIS_WPG.


Run DCOMCNFG and navigate to Component Services > Computers > My Computer > DCOM Config > Microsoft Office Visio Drawing > Properties > Security > Launch and Activation Permissions > Customize > Edit. Add the IIS_WPG group and allow Local Launch & Local Activation rights.


Add the following code to somewhere appropriate in your application:


using System;
using Microsoft.Office.Interop.Visio;
using Microsoft.Office.Interop.Visio.SaveAsWeb;

public static class Visio
{
public static bool Convert(string pathToVsd, string pathToHtml, string pageTitle)
{
bool result;
try
{
InvisibleAppClass visio = new InvisibleAppClass();
VisSaveAsWeb saveAsWeb = (VisSaveAsWeb)visio.Application.SaveAsWebObject;
saveAsWeb.AttachToVisioDoc(visio.Documents.Open(pathToVsd));
VisWebPageSettings webPageSettings = (VisWebPageSettings)saveAsWeb.WebPageSettings;
webPageSettings.TargetPath = pathToHtml;
webPageSettings.PageTitle = pageTitle;
webPageSettings.DispScreenRes = VISWEB_DISP_RES.res768x1024;
webPageSettings.QuietMode = 1;
webPageSettings.SilentMode = 1;
webPageSettings.NavBar = 0;
webPageSettings.PanAndZoom = 0;
webPageSettings.Search = 0;
webPageSettings.OpenBrowser = 0;
webPageSettings.PropControl = 0;
saveAsWeb.CreatePages();
visio.Quit();
result = true;
}
catch (Exception ex)
{
//Put your error logging code here:
//Log.WriteEntry(string.Format("Failed to convert {0} to {1}.", pathToVsd, pathToHtml), ex);
result = false;
}
return result;
}
}

Following is a usage example:


protected void UploadButton_Click(object sender, EventArgs e)
{
if (FileUpload1.HasFile && FileUpload1.FileName.ToLower().EndsWith(".vsd"))
{
string documentName = FileUpload1.FileName.Substring(0, FileUpload1.FileName.Length - 4);
string newFilename = string.Format("{0}-{1:yyyyMMddHHmmss}", documentName, DateTime.Now);
string uploadFolder = Server.MapPath("Diagrams");
string pathToVsd = uploadFolder + "\\" + newFilename + ".vsd";
string pathToHtml = uploadFolder + "\\" + newFilename + ".htm";
FileUpload1.SaveAs(pathToVsd);
if(Visio.Convert(pathToVsd, pathToHtml, documentName))
Response.Redirect("Diagrams/" + newFilename + ".htm", true);
}
}