ComIntegrationManifestGenerator.cs 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //-----------------------------------------------------------------------------
  4. namespace System.ServiceModel.ComIntegration
  5. {
  6. using System;
  7. using System.IO;
  8. using System.Reflection;
  9. using System.Runtime;
  10. using System.Runtime.InteropServices;
  11. using System.ServiceModel;
  12. // this is a heavily modified version of the Win32ManifestGenerator found in the CLR
  13. class ComIntegrationManifestGenerator : MarshalByRefObject
  14. {
  15. internal static void GenerateManifestCollectionFile(Guid[] manifests, String strAssemblyManifestFileName, String assemblyName)
  16. {
  17. String title = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
  18. String asmTitle = "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">";
  19. String asmEnd = "</assembly>";
  20. String path = Path.GetDirectoryName(strAssemblyManifestFileName);
  21. if (!String.IsNullOrEmpty(path) && !Directory.Exists(path))
  22. {
  23. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(System.ServiceModel.ComIntegration.Error.DirectoryNotFound(path));
  24. }
  25. Stream s = null;
  26. try
  27. {
  28. // manifest title
  29. s = File.Create(strAssemblyManifestFileName);
  30. WriteUTFChars(s, title + Environment.NewLine);
  31. WriteUTFChars(s, asmTitle + Environment.NewLine);
  32. WriteUTFChars(s, "<assemblyIdentity" + Environment.NewLine, 4);
  33. WriteUTFChars(s, "name=\"" + assemblyName + "\"" + Environment.NewLine, 8);
  34. WriteUTFChars(s, "version=\"1.0.0.0\"/>" + Environment.NewLine, 8);
  35. for (int i = 0; i < manifests.Length; i++)
  36. {
  37. WriteUTFChars(s, "<dependency>" + Environment.NewLine, 4);
  38. WriteUTFChars(s, "<dependentAssembly>" + Environment.NewLine, 8);
  39. WriteUTFChars(s, "<assemblyIdentity" + Environment.NewLine, 12);
  40. WriteUTFChars(s, "name=\"" + manifests[i].ToString() + "\"" + Environment.NewLine, 16);
  41. WriteUTFChars(s, "version=\"1.0.0.0\"/>" + Environment.NewLine, 16);
  42. WriteUTFChars(s, "</dependentAssembly>" + Environment.NewLine, 8);
  43. WriteUTFChars(s, "</dependency>" + Environment.NewLine, 4);
  44. }
  45. WriteUTFChars(s, asmEnd);
  46. }
  47. catch (Exception e)
  48. {
  49. if (e is NullReferenceException || e is SEHException)
  50. {
  51. throw;
  52. }
  53. s.Close();
  54. File.Delete(strAssemblyManifestFileName);
  55. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(System.ServiceModel.ComIntegration.Error.ManifestCreationFailed(strAssemblyManifestFileName, e.Message));
  56. }
  57. s.Close();
  58. }
  59. internal static void GenerateWin32ManifestFile(Type[] aTypes, String strAssemblyManifestFileName, String assemblyName)
  60. {
  61. String title = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
  62. String asmTitle = "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">";
  63. String path = Path.GetDirectoryName(strAssemblyManifestFileName);
  64. if (!String.IsNullOrEmpty(path) && !Directory.Exists(path))
  65. {
  66. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(System.ServiceModel.ComIntegration.Error.DirectoryNotFound(path));
  67. }
  68. Stream s = null;
  69. try
  70. {
  71. // manifest title
  72. s = File.Create(strAssemblyManifestFileName);
  73. WriteUTFChars(s, title + Environment.NewLine);
  74. WriteUTFChars(s, asmTitle + Environment.NewLine);
  75. WriteUTFChars(s, "<assemblyIdentity" + Environment.NewLine, 4);
  76. WriteUTFChars(s, "name=\"" + assemblyName + "\"" + Environment.NewLine, 8);
  77. WriteUTFChars(s, "version=\"1.0.0.0\"/>" + Environment.NewLine, 8);
  78. AsmCreateWin32ManifestFile(s, aTypes);
  79. }
  80. catch (Exception e)
  81. {
  82. if (e is NullReferenceException || e is SEHException)
  83. {
  84. throw;
  85. }
  86. s.Close();
  87. File.Delete(strAssemblyManifestFileName);
  88. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(System.ServiceModel.ComIntegration.Error.ManifestCreationFailed(strAssemblyManifestFileName, e.Message));
  89. }
  90. s.Close();
  91. }
  92. static void AsmCreateWin32ManifestFile(Stream s, Type[] aTypes)
  93. {
  94. String asmEnd = "</assembly>";
  95. WriteTypes(s, aTypes, 4);
  96. WriteUTFChars(s, asmEnd);
  97. }
  98. static void WriteTypes(Stream s, Type[] aTypes, int offset)
  99. {
  100. RegistrationServices regServices = new RegistrationServices();
  101. String name = null;
  102. Assembly asm = Assembly.GetExecutingAssembly();
  103. string asmver = asm.ImageRuntimeVersion;
  104. foreach (Type t in aTypes)
  105. {
  106. // only registrable managed types will show up in the manifest file
  107. if (!regServices.TypeRequiresRegistration(t))
  108. {
  109. throw Fx.AssertAndThrow("User defined types must be registrable");
  110. }
  111. String strClsId = "{" + Marshal.GenerateGuidForType(t).ToString().ToUpperInvariant() + "}";
  112. name = t.FullName;
  113. // this type is a com imported type or Record
  114. if (regServices.TypeRepresentsComType(t) || t.IsValueType)
  115. {
  116. WriteUTFChars(s, "<clrSurrogate" + Environment.NewLine, offset);
  117. // attribute clsid
  118. WriteUTFChars(s, " clsid=\"" + strClsId + "\"" + Environment.NewLine, offset);
  119. // attribute class
  120. WriteUTFChars(s, " name=\"" + name + "\"" + Environment.NewLine, offset);
  121. // clr version
  122. WriteUTFChars(s, " runtimeVersion=\"" + asmver + "\">" + Environment.NewLine, offset);
  123. WriteUTFChars(s, "</clrSurrogate>" + Environment.NewLine, offset);
  124. }
  125. }
  126. }
  127. static void WriteUTFChars(Stream s, String value, int offset)
  128. {
  129. for (int i = 0; i < offset; i++)
  130. {
  131. WriteUTFChars(s, " ");
  132. }
  133. WriteUTFChars(s, value);
  134. }
  135. static void WriteUTFChars(Stream s, String value)
  136. {
  137. byte[] bytes = System.Text.Encoding.UTF8.GetBytes(value);
  138. s.Write(bytes, 0, bytes.Length);
  139. }
  140. }
  141. }