The problem was related to the type library, inserting the following lines int0 the manifest fixed the problem
<file name="myusercontrol.tlb">
<typelib tlbid="{F121823D-5EF1-4149-A37B-86303971F72C}">
version="1.0" helpdir="" flags="HASDISKIMAGE"></typelib>
</file>
Also have to reference the typelib from the clrclass section, so the full manifest is as follows
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestversion="1.0">
<assemblyidentity>
name="mydotneusercontrol"
version="6.8.0.0"
processorArchitecture="msil">
</assemblyidentity>
<clrclass>
clsid="{123456AF-B555-4c06-909C-CDE19C66AD30}"
progid="mydotneusercontrol.myusercontrol"
tlbid="{F121823D-5EF1-4149-A37B-86303971F72C}"
threadingModel="Both"
name="mydotneusercontrol.myusercontrol"
runtimeVersion="">
</clrclass>
<file name="myusercontrol.dll" hashalg="SHA1"></file>
<file name="myusercontrol.tlb">
<typelib tlbid="{F121823D-5EF1-4149-A37B-86303971F72C}">
version="1.0" helpdir="" flags="HASDISKIMAGE"></typelib>
</file>
</assembly>
I wanted to automate the generation of this manifest file, so I use mt to generate a file based on the type lib then use it a again to generate a manifest based on the dll then I wrote a console application to merge the relevant parts of the two manifests together before merging into the dll. The process is as follows:
rem delete old manifests
del %dllmanifest% -Y
del %tlbmanifest% -Y
del %mergedmanifest% -Y
rem generate a dll manifest
mt -managedassemblyname:%dllname% -nodependency -out:%dllmanifest%
rem generate a tlb manifest
mt -tlb:b:\%tlbname% -dll:%dllname% -out:%tlbmanifest%
rem merge the typelib information into the dll information
MergeTLB %tlbmanifest% %dllmanifest% %mergedmanifest%
rem embbed the resulting manifest into the dll
mt -manifest %mergedmanifest% -outputresource:%dllname%;#1
The code for the MergeTLB Application is as follows:
class Program {
static void Main(string[] args) {
if (args.Length == 3) {
string tlbManifest = args[0];
string dllManifest = args[1];
string outManifest = args[2];
XmlDocument tlbXml = new XmlDocument();
tlbXml.Load(tlbManifest);
XmlNode tlbFileNode = null;
XmlAttribute tlbidAttrib = null;
XmlNode tlbNode = FindNode(tlbXml, "typelib");
if (tlbNode != null) {
tlbFileNode = tlbNode.ParentNode;
for (int i = tlbFileNode.ChildNodes.Count - 1; i >= 0; i--) {
if (tlbFileNode.ChildNodes[i] != tlbNode)
tlbFileNode.RemoveChild(tlbFileNode.ChildNodes[i]);
}
XmlAttribute nameAttrib = tlbFileNode.Attributes["name"];
nameAttrib.Value = nameAttrib.Value.Replace(".dll", ".tlb");
tlbidAttrib = tlbNode.Attributes["tlbid"];
tlbFileNode.ParentNode.RemoveChild(tlbFileNode);
}
XmlDocument dllDocument = new XmlDocument();
dllDocument.Load(dllManifest);
XmlNode clrNode = FindNode(dllDocument, "clrClass");
if (clrNode != null && tlbidAttrib != null) {
clrNode.Attributes.Append((XmlAttribute) dllDocument.ImportNode(tlbidAttrib, false));
clrNode.ParentNode.AppendChild(dllDocument.ImportNode(tlbFileNode, true));
}
dllDocument.Save(outManifest);
} else {
Console.WriteLine("MergeTLB tlbManifest dllmanifest outmanifest");
}
}
private static XmlNode FindNode(XmlDocument tlbXml, string nodeName) {
XmlNamespaceManager xsm = new XmlNamespaceManager(tlbXml.NameTable);
xsm.AddNamespace("x", "urn:schemas-microsoft-com:asm.v1");
XmlNode tlbNode = tlbXml.SelectSingleNode("descendant::x:" + nodeName, xsm);
return tlbNode;
}
}