Manifests for IE Hosted Controls

Earlier this week,I talked about the Orcas feature where controls can declaratively request permissions in a similar way to ClickOnce applications.  In fact, the manifests used for this request are the same manifests used for ClickOnce applications, with a few special requirements added onto them.  When you're developing controls, its possible to have manifests which don't meet one of these requirements.  In that case, the error in the manifest will be logged to the IEHost debug log in order to help you figure out what needs to be changed.  Lets dig in deeper to the manifests, since they are really at the heart of this feature.

Like a ClickOnce application, IE hosted controls will have both a deployment and an application manifest.  By convention, the deployment manifest will have a .control extension, while the application manifest will have a .dll.manifest extension.  Both manifests are required to have a valid Authenticode and StrongName signature (a self signed certificate will work, however it must be installed in the trusted root store on the client machines so that it "chains" to a valid root).  Both manifests must also be located on the same site as the control -- a control on foo.com cannot have manifest on bar.com.  Similarly, a deployment manifest on bar.com cannot refer to an application manifest on baz.com.

Outside of those common requirements, each manifest has its own specific requirements.  Let's look at the deployment manifest first.  The requirements for the deployment manifest are:

  • It must not request to be installed on the local machine.  IE hosted controls do not get installed into the ClickOnce application store.
  • It must have a deploymentProvider which exactly matches the URL it was downloaded from.
  • Point at the application manifest, and have the correct hash of the manifest included.

I've attached TemplateControl.control as a template that control deployment manifests can be based upon.  The first two requirements can be seen in the deployment section of the manifest:

  <deployment install="false">

    <deploymentProvider codebase="https://www.contoso.com/TemplateControl/TemplateControl.control" />

  </deployment>

And the last one is in the dependency section:

  <dependency>

    <dependentAssembly codebase="TemplateControl.dll.manifest" size="1929" dependencyType="install">

      <assemblyIdentity name="TemplateControl.dll" version="1.0.0.0" publicKeyToken="7bbbb9ce54f53dd4" processorArchitecture="msil" language="neutral" type="win32" />

      <hash>

        <dsig:Transforms>

          <dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />

        </dsig:Transforms>

        <dsig:DigestMethod Algorithm="https://www.w3.org/2000/09/xmldsig#sha1" />

        <dsig:DigestValue>QPq0hc3mZPhWUeRAthX7QefabZk=</dsig:DigestValue>

      </hash>

    </dependentAssembly>

  </dependency>

Onto the application manifest.  There are a few more rules around this manifest:

  • The hash of the application manifest must match the hash specified in the deployment manifest
  • The entry point must match the control being downloaded
  • There must be a <hostInBrowser /> tag
  • A permission set must be supplied
  • The only file allowed to be listed is the control itself, we do not support having additional files in the manifest.  You can of course load them when your control is running, but only the control assembly may appear in the manifest
  • The control must have its SHA-1 hash listed, and that hash must match the control

Again, I've attached TemplateControl.dll.manifest to this post to use as a template for control application manifests.  You can see in the entry point section that the entry point is indeed the control (assuming the control is hosted in TemplateControl.dll), and that it should be hosted in the browser:

  <entryPoint>

    <assemblyIdentity name="TemplateControl" version="1.0.0.0" publicKeyToken="7bbbb9ce54f53dd4" processorArchitecture="msil" language="neutral" />

    <commandLine file="TemplateControl.dll" />

    <hostInBrowser xmlns="urn:schemas-microsoft-com:asm.v3" />

  </entryPoint>

The permission set exists in the trustInfo section, as is the case for regular ClickOnce manifests:

  <trustInfo>

    <security>

      <applicationRequestMinimum>

        <PermissionSet class="System.Security.NamedPermissionSet" version="1" Unrestricted="true" Description="Allows full access to all resources" SameSite="site" ID="FullTrust" />

        <defaultAssemblyRequest permissionSetReference="FullTrust" />

      </applicationRequestMinimum>

    </security>

  </trustInfo>

And the dependency is the control assembly:

  <dependency>

    <dependentAssembly codebase="TemplateControl.dll" size="4608" dependencyType="install" allowDelayedBinding="true">

      <assemblyIdentity name="TemplateControl" version="1.0.0.0" publicKeyToken="7bbbb9ce54f53dd4" processorArchitecture="msil" language="neutral" />

      <hash>

        <dsig:Transforms>

          <dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />

        </dsig:Transforms>

        <dsig:DigestMethod Algorithm="https://www.w3.org/2000/09/xmldsig#sha1" />

        <dsig:DigestValue>yxh1Z4B1Maw8UoXSU+rDwsj+8bA=</dsig:DigestValue>

      </hash>

    </dependentAssembly>

  </dependency>

Unfortunately, the tools story for creating control manifests isn't all together great at this point.  The easiest way that you'll be able to generate these manifests is to start with the template manifests, and then use the Mage tool that ships in the Framework SDK to update and sign them.  Since Mage does not yet know about control manifests, there are a few manual steps involved:

  1. Create a directory containing your manifest and control.  You may want to edit the manifest at this point, to point it at YourControl.dll rather than TemplateControl.dll.  You could also update the other names in the manifest.
  2. Update the hash value of your control: Mage -Update YourControl.dll.manifest
  3. Mage will give a warning about a .dll not being a valid entry point, and insert dependencies on the operating system and CLR.  You'll have to edit the manifest so that the extra dependencies are removed.
  4. Sign the manifest: Mage -Sign YourControl.dll.manifest -CertFile <path to your certificate> -Password <certificate password>

At this point you'll have a valid application manifest for your control.  Similar steps are required to setup the deployment manifest:

  1. Rename TemplateControl.control to give it a more appropriate name.  You'll also need to change the deploymentProvider to point at the URL where your manifest will be accessed by client machines, and update the reference to TemplateControl.dll.manifest to point at your control's application manifest.
  2. Update the hash value of the application manifest: Mage -Update YourControl.control
  3. Sign the manifest: Mage -Sign YourControl.control -CertFile <path to your certificate> -Password <certificate password>

Now you have a pair of valid manifests to use with your control.  Yes, I know that this isn't exactly ... well ... the easiest procedure in the world.  Hopefully by the time we finish the release we will have a better story here, but for now these steps will allow you to play with generating controls for the CTP releases.

So now we know the overall picture of manifested IE controls in Orcas and have seen what the manifests look like and how to create them, that leaves us with one last step.  Next time, we'll take a look at how we hook the whole thing up in an HTML page to get the full story working end-to-end.

[Update 3/29] Provided a link to the TemplateControl.control file

TemplateControl.dll.manifest