A while back, I posted “A guide to App-V publishing and streaming using IIS” on the App-V blog and since then we have continued to work on this since it continues to be such a popular topic. The code on the site has been put to the test and as a result of this, we have been working together to improve the code, and we would like to share that as well.
Let us start at the beginning!
When it comes to the configuration of IIS, we can use the same configuration that I outlined in the earlier article. There is one important difference though. Instead of a Virtual Directory, we should create a Virtual Application. Otherwise, the code we will discuss later on will not function as expected.
You can either create a new Virtual Application, but you can also choose to convert your existing Virtual Directory to a Virtual Application.
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="publishing.aspx.cs" Inherits="HttpPublishing.Publishing" ContentType="text/xml"%>
<% this.generate_app_xml(); %>
using System.Web.UI.WebControls; using System.Xml.Linq; using System.Xml; using System.IO;
namespace HttpPublishing { public partial class Publishing : System.Web.UI.Page { /* * <DESKTOPCONFIG> * <POLICY MANAGEDDESKTOP=""TRUE"" REPORTING=""FALSE""> * <REFRESH ONLOGIN=""TRUE"" PERIOD=""60""/> * </POLICY> * <APPLIST /> * </DESKTOPCONFIG>"; */
private XElement desktop_configuration = new XElement("DESKTOPCONFIG", new XElement("POLICY", new XAttribute("MANAGEDDESKTOP", "TRUE"), new XAttribute("REPORTING", "FALSE"), new XElement("REFRESH", new XAttribute("ONLOGIN", "TRUE"), new XAttribute("PERIOD", "60"))), new XElement("APPLIST"));
/* * Page_Load will parse manifest files generated by the App-V Sequencer under the Content directory * in the virtual directory associated with the web application, i.e. C:\inetpub\wwwroot\httppublishing\content */ //protected void Page_Load(object sender, EventArgs e) protected void generate_app_xml() { Response.ContentType = "text/xml";
string path = Request.Url.ToString(); string root_virt = path.Substring(0, path.LastIndexOf("/")) + @"/Content"; string root_phys = MapPath("~/Content");
try { // Best effort. string[] manifests = Directory.GetFiles(root_phys, @"*_manifest.xml", SearchOption.AllDirectories);
XElement applist_nodes = desktop_configuration.Element("APPLIST");
foreach (string filename in manifests) { try { //Check to see if the current user has read access to the file using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read)) using (XmlReader manifest = XmlReader.Create(fs)) { XElement manifest_root = XElement.Load(manifest); XElement manifest_applist = manifest_root.Element("APPLIST");
System.Text.StringBuilder app_xml = new System.Text.StringBuilder(manifest_applist.ToString());
// handle %SFT_MIME_SOURCE% paths string curr_dir = Path.GetDirectoryName(filename).Substring(root_phys.Length); curr_dir = curr_dir.Replace('\\', '/'); string full_vpath = root_virt + curr_dir;
app_xml.Replace("%SFT_MIME_SOURCE%", full_vpath);
XElement manifest_applist_nodes = XElement.Parse(app_xml.ToString());
foreach (XNode node in manifest_applist_nodes.Nodes()) { applist_nodes.Add(node); } } } catch (UnauthorizedAccessException) { } } } catch (Exception ex) { // Output to log file Response.AppendToLog(ex.Message); }
Response.Write(desktop_configuration.ToString()); Response.End(); } } }
The client can be configured as we are used to and as we described in the previous article. The only thing that should be verified is whether the Application Source Root (ASR) has been configured. If this is not done, the code will not work as expected.
This can be configured here:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SoftGrid\4.5\Client\Configuration
Name: ApplicationSourceRoot Value: http://IISSERVERNAME:80/HttpPublishing/content
Therefore, this code should indeed make our lives much easier! We hope you experience this as well en enjoy your HTTP/IIS setup for App-V even more. Below is one more quick summary of the important catches, so make sure you won’t miss them:
Note: I want to give a special thanks to Nikolaos Dalalelis for contributing the code above. Thanks Nick!
Madelinde Walraven | Senior Support Engineer
The App-V Team blog: http://blogs.technet.com/appv/ The WSUS Support Team blog: http://blogs.technet.com/sus/ The SCMDM Support Team blog: http://blogs.technet.com/mdm/ The ConfigMgr Support Team blog: http://blogs.technet.com/configurationmgr/ The OpsMgr Support Team blog: http://blogs.technet.com/operationsmgr/ The SCVMM Team blog: http://blogs.technet.com/scvmm/ The MED-V Team blog: http://blogs.technet.com/medv/ The DPM Team blog: http://blogs.technet.com/dpm/ The OOB Support Team blog: http://blogs.technet.com/oob/ The Opalis Team blog: http://blogs.technet.com/opalis