PageRenderTime 51ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/src/Compilers/CSharp/Test/Emit/Emit/ResourceTests.cs

https://gitlab.com/sharadag/TestProject2
C# | 882 lines | 689 code | 151 blank | 42 comment | 24 complexity | 37607577e4791f726f6134447f372ea4 MD5 | raw file
  1. // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  2. using System;
  3. using System.ComponentModel;
  4. using System.Diagnostics;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Reflection;
  8. using System.Runtime.InteropServices;
  9. using System.Threading;
  10. using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
  11. using Microsoft.CodeAnalysis.Emit;
  12. using Microsoft.CodeAnalysis.Test.Utilities;
  13. using Roslyn.Test.Utilities;
  14. using Xunit;
  15. namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Emit
  16. {
  17. public class ResourceTests : CSharpTestBase
  18. {
  19. [DllImport("kernel32.dll", SetLastError = true)]
  20. private static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hFile, uint dwFlags);
  21. [DllImport("kernel32.dll", SetLastError = true)]
  22. private static extern bool FreeLibrary([In] IntPtr hFile);
  23. [Fact]
  24. public void DefaultVersionResource()
  25. {
  26. string source = @"
  27. public class Maine
  28. {
  29. public static void Main()
  30. {
  31. }
  32. }
  33. ";
  34. var c1 = CreateCompilationWithMscorlib(source, assemblyName: "Win32VerNoAttrs", options: TestOptions.ReleaseExe);
  35. var exe = Temp.CreateFile();
  36. using (FileStream output = exe.Open())
  37. {
  38. c1.Emit(output, win32Resources: c1.CreateDefaultWin32Resources(true, false, null, null));
  39. }
  40. c1 = null;
  41. //Open as data
  42. IntPtr lib = IntPtr.Zero;
  43. string versionData;
  44. string mftData;
  45. try
  46. {
  47. lib = LoadLibraryEx(exe.Path, IntPtr.Zero, 0x00000002);
  48. if (lib == IntPtr.Zero)
  49. throw new Win32Exception(Marshal.GetLastWin32Error());
  50. //the manifest and version primitives are tested elsewhere. This is to test that the default
  51. //values are passed to the primitives that assemble the resources.
  52. uint size;
  53. IntPtr versionRsrc = Win32Res.GetResource(lib, "#1", "#16", out size);
  54. versionData = Win32Res.VersionResourceToXml(versionRsrc);
  55. uint mftSize;
  56. IntPtr mftRsrc = Win32Res.GetResource(lib, "#1", "#24", out mftSize);
  57. mftData = Win32Res.ManifestResourceToXml(mftRsrc, mftSize);
  58. }
  59. finally
  60. {
  61. if (lib != IntPtr.Zero)
  62. {
  63. FreeLibrary(lib);
  64. }
  65. }
  66. string expected =
  67. @"<?xml version=""1.0"" encoding=""utf-16""?>
  68. <VersionResource Size=""612"">
  69. <VS_FIXEDFILEINFO FileVersionMS=""00000000"" FileVersionLS=""00000000"" ProductVersionMS=""00000000"" ProductVersionLS=""00000000"" />
  70. <KeyValuePair Key=""FileDescription"" Value="" "" />
  71. <KeyValuePair Key=""FileVersion"" Value=""0.0.0.0"" />
  72. <KeyValuePair Key=""InternalName"" Value=""Win32VerNoAttrs.exe"" />
  73. <KeyValuePair Key=""LegalCopyright"" Value="" "" />
  74. <KeyValuePair Key=""OriginalFilename"" Value=""Win32VerNoAttrs.exe"" />
  75. <KeyValuePair Key=""ProductVersion"" Value=""0.0.0.0"" />
  76. <KeyValuePair Key=""Assembly Version"" Value=""0.0.0.0"" />
  77. </VersionResource>";
  78. Assert.Equal(expected, versionData);
  79. expected = @"<?xml version=""1.0"" encoding=""utf-16""?>
  80. <ManifestResource Size=""490"">
  81. <Contents><![CDATA[<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?>
  82. <assembly xmlns=""urn:schemas-microsoft-com:asm.v1"" manifestVersion=""1.0"">
  83. <assemblyIdentity version=""1.0.0.0"" name=""MyApplication.app""/>
  84. <trustInfo xmlns=""urn:schemas-microsoft-com:asm.v2"">
  85. <security>
  86. <requestedPrivileges xmlns=""urn:schemas-microsoft-com:asm.v3"">
  87. <requestedExecutionLevel level=""asInvoker"" uiAccess=""false""/>
  88. </requestedPrivileges>
  89. </security>
  90. </trustInfo>
  91. </assembly>]]></Contents>
  92. </ManifestResource>";
  93. Assert.Equal(expected, mftData);
  94. //look at the same data through the FileVersion API.
  95. //If the codepage and resource language information is not
  96. //written correctly into the internal resource directory of
  97. //the PE, then GetVersionInfo will fail to find the FileVersionInfo.
  98. //Once upon a time in Roslyn, the codepage and lang info was not written correctly.
  99. var fileVer = FileVersionInfo.GetVersionInfo(exe.Path);
  100. Assert.Equal(" ", fileVer.LegalCopyright);
  101. }
  102. [Fact]
  103. public void ResourcesInCoff()
  104. {
  105. //this is to test that resources coming from a COFF can be added to a binary.
  106. string source = @"
  107. class C
  108. {
  109. }
  110. ";
  111. var c1 = CreateCompilationWithMscorlib(source, assemblyName: "Win32WithCoff", options: TestOptions.ReleaseDll);
  112. var exe = Temp.CreateFile();
  113. using (FileStream output = exe.Open())
  114. {
  115. var memStream = new MemoryStream(TestResources.General.nativeCOFFResources);
  116. c1.Emit(output, win32Resources: memStream);
  117. }
  118. c1 = null;
  119. //Open as data
  120. IntPtr lib = IntPtr.Zero;
  121. string versionData;
  122. try
  123. {
  124. lib = LoadLibraryEx(exe.Path, IntPtr.Zero, 0x00000002);
  125. if (lib == IntPtr.Zero)
  126. throw new Win32Exception(Marshal.GetLastWin32Error());
  127. //the manifest and version primitives are tested elsewhere. This is to test that the resources
  128. //we expect are present. Also need to check that the actual contents of at least one of the resources
  129. //is good. That tests our processing of the relocations.
  130. uint size;
  131. IntPtr versionRsrc = Win32Res.GetResource(lib, "#1", "#16", out size);
  132. versionData = Win32Res.VersionResourceToXml(versionRsrc);
  133. uint stringTableSize;
  134. IntPtr stringTable = Win32Res.GetResource(lib, "#1", "#6", out stringTableSize);
  135. Assert.NotNull(stringTable);
  136. uint elevenSize;
  137. IntPtr elevenRsrc = Win32Res.GetResource(lib, "#1", "#11", out elevenSize);
  138. Assert.NotNull(elevenRsrc);
  139. uint wevtSize;
  140. IntPtr wevtRsrc = Win32Res.GetResource(lib, "#1", "WEVT_TEMPLATE", out wevtSize);
  141. Assert.NotNull(wevtRsrc);
  142. }
  143. finally
  144. {
  145. if (lib != IntPtr.Zero)
  146. {
  147. FreeLibrary(lib);
  148. }
  149. }
  150. string expected =
  151. @"<?xml version=""1.0"" encoding=""utf-16""?>
  152. <VersionResource Size=""1104"">
  153. <VS_FIXEDFILEINFO FileVersionMS=""000b0000"" FileVersionLS=""eacc0000"" ProductVersionMS=""000b0000"" ProductVersionLS=""eacc0000"" />
  154. <KeyValuePair Key=""CompanyName"" Value=""Microsoft Corporation"" />
  155. <KeyValuePair Key=""FileDescription"" Value=""Team Foundation Server Object Model"" />
  156. <KeyValuePair Key=""FileVersion"" Value=""11.0.60108.0 built by: TOOLSET_ROSLYN(GNAMBOO-DEV-GNAMBOO)"" />
  157. <KeyValuePair Key=""InternalName"" Value=""Microsoft.TeamFoundation.Framework.Server.dll"" />
  158. <KeyValuePair Key=""LegalCopyright"" Value=""© Microsoft Corporation. All rights reserved."" />
  159. <KeyValuePair Key=""OriginalFilename"" Value=""Microsoft.TeamFoundation.Framework.Server.dll"" />
  160. <KeyValuePair Key=""ProductName"" Value=""Microsoft® Visual Studio® 2012"" />
  161. <KeyValuePair Key=""ProductVersion"" Value=""11.0.60108.0"" />
  162. </VersionResource>";
  163. Assert.Equal(expected, versionData);
  164. //look at the same data through the FileVersion API.
  165. //If the codepage and resource language information is not
  166. //written correctly into the internal resource directory of
  167. //the PE, then GetVersionInfo will fail to find the FileVersionInfo.
  168. //Once upon a time in Roslyn, the codepage and lang info was not written correctly.
  169. var fileVer = FileVersionInfo.GetVersionInfo(exe.Path);
  170. Assert.Equal("Microsoft Corporation", fileVer.CompanyName);
  171. }
  172. [Fact]
  173. public void FaultyResourceDataProvider()
  174. {
  175. var c1 = CreateCompilationWithMscorlib("");
  176. var result = c1.Emit(new MemoryStream(), manifestResources:
  177. new[]
  178. {
  179. new ResourceDescription("r2", "file", () => { throw new Exception("bad stuff"); }, false)
  180. });
  181. result.Diagnostics.Verify(
  182. // error CS1566: Error reading resource 'file' -- 'bad stuff'
  183. Diagnostic(ErrorCode.ERR_CantReadResource).WithArguments("file", "bad stuff")
  184. );
  185. result = c1.Emit(new MemoryStream(), manifestResources:
  186. new[]
  187. {
  188. new ResourceDescription("r2", "file", () => null, false)
  189. });
  190. result.Diagnostics.Verify(
  191. // error CS1566: Error reading resource 'file' -- 'Resource data provider should return non-null stream'
  192. Diagnostic(ErrorCode.ERR_CantReadResource).WithArguments("file", CodeAnalysisResources.ResourceDataProviderShouldReturnNonNullStream)
  193. );
  194. }
  195. [WorkItem(543501, "DevDiv")]
  196. [Fact]
  197. public void CS1508_DuplicateMainfestResourceIdentifier()
  198. {
  199. var c1 = CreateCompilationWithMscorlib("");
  200. Func<Stream> dataProvider = () => new MemoryStream(new byte[] { });
  201. var result = c1.Emit(new MemoryStream(), manifestResources:
  202. new[]
  203. {
  204. new ResourceDescription("A", "x.foo", dataProvider, true),
  205. new ResourceDescription("A", "y.foo", dataProvider, true)
  206. });
  207. result.Diagnostics.Verify(
  208. // error CS1508: Resource identifier 'A' has already been used in this assembly
  209. Diagnostic(ErrorCode.ERR_ResourceNotUnique).WithArguments("A")
  210. );
  211. }
  212. [WorkItem(543501, "DevDiv")]
  213. [Fact]
  214. public void CS1508_DuplicateMainfestResourceIdentifier_EmbeddedResource()
  215. {
  216. var c1 = CreateCompilationWithMscorlib("");
  217. Func<Stream> dataProvider = () => new MemoryStream(new byte[] { });
  218. var result = c1.Emit(new MemoryStream(), manifestResources:
  219. new[]
  220. {
  221. new ResourceDescription("A", dataProvider, true),
  222. new ResourceDescription("A", null, dataProvider, true, isEmbedded: true, checkArgs: true)
  223. });
  224. result.Diagnostics.Verify(
  225. // error CS1508: Resource identifier 'A' has already been used in this assembly
  226. Diagnostic(ErrorCode.ERR_ResourceNotUnique).WithArguments("A")
  227. );
  228. // file name ignored for embedded manifest resources
  229. result = c1.Emit(new MemoryStream(), manifestResources:
  230. new[]
  231. {
  232. new ResourceDescription("A", "x.foo", dataProvider, true, isEmbedded: true, checkArgs: true),
  233. new ResourceDescription("A", "x.foo", dataProvider, true, isEmbedded: false, checkArgs: true)
  234. });
  235. result.Diagnostics.Verify(
  236. // error CS1508: Resource identifier 'A' has already been used in this assembly
  237. Diagnostic(ErrorCode.ERR_ResourceNotUnique).WithArguments("A")
  238. );
  239. }
  240. [WorkItem(543501, "DevDiv")]
  241. [Fact]
  242. public void CS7041_DuplicateMainfestResourceFileName()
  243. {
  244. var c1 = CSharpCompilation.Create("foo", references: new[] { MscorlibRef }, options: TestOptions.ReleaseDll);
  245. Func<Stream> dataProvider = () => new MemoryStream(new byte[] { });
  246. var result = c1.Emit(new MemoryStream(), manifestResources:
  247. new[]
  248. {
  249. new ResourceDescription("A", "x.foo", dataProvider, true),
  250. new ResourceDescription("B", "x.foo", dataProvider, true)
  251. });
  252. result.Diagnostics.Verify(
  253. // error CS7041: Each linked resource and module must have a unique filename. Filename 'x.foo' is specified more than once in this assembly
  254. Diagnostic(ErrorCode.ERR_ResourceFileNameNotUnique).WithArguments("x.foo")
  255. );
  256. }
  257. [WorkItem(543501, "DevDiv")]
  258. [Fact]
  259. public void NoDuplicateMainfestResourceFileNameDiagnosticForEmbeddedResources()
  260. {
  261. var c1 = CreateCompilationWithMscorlib("");
  262. Func<Stream> dataProvider = () => new MemoryStream(new byte[] { });
  263. var result = c1.Emit(new MemoryStream(), manifestResources:
  264. new[]
  265. {
  266. new ResourceDescription("A", dataProvider, true),
  267. new ResourceDescription("B", null, dataProvider, true, isEmbedded: true, checkArgs: true)
  268. });
  269. result.Diagnostics.Verify();
  270. // file name ignored for embedded manifest resources
  271. result = c1.Emit(new MemoryStream(), manifestResources:
  272. new[]
  273. {
  274. new ResourceDescription("A", "x.foo", dataProvider, true, isEmbedded: true, checkArgs: true),
  275. new ResourceDescription("B", "x.foo", dataProvider, true, isEmbedded: false, checkArgs: true)
  276. });
  277. result.Diagnostics.Verify();
  278. }
  279. [WorkItem(543501, "DevDiv"), WorkItem(546297, "DevDiv")]
  280. [Fact]
  281. public void CS1508_CS7041_DuplicateMainfestResourceDiagnostics()
  282. {
  283. var c1 = CreateCompilationWithMscorlib("");
  284. Func<Stream> dataProvider = () => new MemoryStream(new byte[] { });
  285. var result = c1.Emit(new MemoryStream(), manifestResources:
  286. new[]
  287. {
  288. new ResourceDescription("A", "x.foo", dataProvider, true),
  289. new ResourceDescription("A", "x.foo", dataProvider, true)
  290. });
  291. result.Diagnostics.Verify(
  292. // error CS1508: Resource identifier 'A' has already been used in this assembly
  293. Diagnostic(ErrorCode.ERR_ResourceNotUnique).WithArguments("A"),
  294. // error CS7041: Each linked resource and module must have a unique filename. Filename 'x.foo' is specified more than once in this assembly
  295. Diagnostic(ErrorCode.ERR_ResourceFileNameNotUnique).WithArguments("x.foo")
  296. );
  297. result = c1.Emit(new MemoryStream(), manifestResources:
  298. new[]
  299. {
  300. new ResourceDescription("A", "x.foo", dataProvider, true),
  301. new ResourceDescription("B", "x.foo", dataProvider, true),
  302. new ResourceDescription("B", "y.foo", dataProvider, true)
  303. });
  304. result.Diagnostics.Verify(
  305. // error CS7041: Each linked resource and module must have a unique filename. Filename 'x.foo' is specified more than once in this assembly
  306. Diagnostic(ErrorCode.ERR_ResourceFileNameNotUnique).WithArguments("x.foo"),
  307. // error CS1508: Resource identifier 'B' has already been used in this assembly
  308. Diagnostic(ErrorCode.ERR_ResourceNotUnique).WithArguments("B")
  309. );
  310. result = c1.Emit(new MemoryStream(), manifestResources:
  311. new[]
  312. {
  313. new ResourceDescription("A", "foo.dll", dataProvider, true),
  314. });
  315. //make sure there's no problem when the name of the primary module conflicts with a file name of an added resource.
  316. result.Diagnostics.Verify();
  317. var netModule1 = TestReferences.SymbolsTests.netModule.netModule1;
  318. c1 = CreateCompilationWithMscorlib("", references: new[] { netModule1 });
  319. result = c1.Emit(new MemoryStream(), manifestResources:
  320. new[]
  321. {
  322. new ResourceDescription("A", "netmodule1.netmodule", dataProvider, true),
  323. });
  324. // Native compiler gives CS0013 (FTL_MetadataEmitFailure) at Emit stage
  325. result.Diagnostics.Verify(
  326. // error CS7041: Each linked resource and module must have a unique filename. Filename 'netmodule1.netmodule' is specified more than once in this assembly
  327. Diagnostic(ErrorCode.ERR_ResourceFileNameNotUnique).WithArguments("netModule1.netmodule")
  328. );
  329. }
  330. [Fact]
  331. public void AddManagedResource()
  332. {
  333. string source = @"public class C { static public void Main() {} }";
  334. // Do not name the compilation, a unique guid is used as a name by default. It prevents conflicts with other assemblies loaded via Assembly.ReflectionOnlyLoad.
  335. var c1 = CreateCompilationWithMscorlib(source);
  336. var resourceFileName = "RoslynResourceFile.foo";
  337. var output = new MemoryStream();
  338. const string r1Name = "some.dotted.NAME";
  339. const string r2Name = "another.DoTtEd.NAME";
  340. var arrayOfEmbeddedData = new byte[] { 1, 2, 3, 4, 5 };
  341. var resourceFileData = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
  342. var result = c1.Emit(output, manifestResources:
  343. new ResourceDescription[]
  344. {
  345. new ResourceDescription(r1Name, () => new MemoryStream(arrayOfEmbeddedData), true),
  346. new ResourceDescription(r2Name, resourceFileName, () => new MemoryStream(resourceFileData), false)
  347. });
  348. Assert.True(result.Success);
  349. var assembly = Assembly.ReflectionOnlyLoad(output.ToArray());
  350. string[] resourceNames = assembly.GetManifestResourceNames();
  351. Assert.Equal(2, resourceNames.Length);
  352. var rInfo = assembly.GetManifestResourceInfo(r1Name);
  353. Assert.Equal(ResourceLocation.Embedded | ResourceLocation.ContainedInManifestFile, rInfo.ResourceLocation);
  354. var rData = assembly.GetManifestResourceStream(r1Name);
  355. var rBytes = new byte[rData.Length];
  356. rData.Read(rBytes, 0, (int)rData.Length);
  357. Assert.Equal(arrayOfEmbeddedData, rBytes);
  358. rInfo = assembly.GetManifestResourceInfo(r2Name);
  359. Assert.Equal(resourceFileName, rInfo.FileName);
  360. c1 = null;
  361. }
  362. [Fact]
  363. private void AddResourceToModule()
  364. {
  365. for (int metadataOnlyIfNonzero = 0; metadataOnlyIfNonzero < 2; metadataOnlyIfNonzero++)
  366. {
  367. var metadataOnly = metadataOnlyIfNonzero != 0;
  368. Func<Compilation, Stream, ResourceDescription[], CodeAnalysis.Emit.EmitResult> emit;
  369. emit = (c, s, r) => c.Emit(s, manifestResources: r, options: new EmitOptions(metadataOnly: metadataOnly));
  370. var sourceTree = SyntaxFactory.ParseSyntaxTree("");
  371. // Do not name the compilation, a unique guid is used as a name by default. It prevents conflicts with other assemblies loaded via Assembly.ReflectionOnlyLoad.
  372. var c1 = CSharpCompilation.Create(
  373. Guid.NewGuid().ToString(),
  374. new[] { sourceTree },
  375. new[] { MscorlibRef },
  376. TestOptions.ReleaseModule);
  377. var resourceFileName = "RoslynResourceFile.foo";
  378. var output = new MemoryStream();
  379. const string r1Name = "some.dotted.NAME";
  380. const string r2Name = "another.DoTtEd.NAME";
  381. var arrayOfEmbeddedData = new byte[] { 1, 2, 3, 4, 5 };
  382. var resourceFileData = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
  383. var result = emit(c1, output,
  384. new ResourceDescription[]
  385. {
  386. new ResourceDescription(r1Name, () => new MemoryStream(arrayOfEmbeddedData), true),
  387. new ResourceDescription(r2Name, resourceFileName, () => new MemoryStream(resourceFileData), false)
  388. });
  389. Assert.False(result.Success);
  390. Assert.NotEmpty(result.Diagnostics.Where(x => x.Code == (int)ErrorCode.ERR_CantRefResource));
  391. result = emit(c1, output,
  392. new ResourceDescription[]
  393. {
  394. new ResourceDescription(r2Name, resourceFileName, () => new MemoryStream(resourceFileData), false),
  395. new ResourceDescription(r1Name, () => new MemoryStream(arrayOfEmbeddedData), true)
  396. });
  397. Assert.False(result.Success);
  398. Assert.NotEmpty(result.Diagnostics.Where(x => x.Code == (int)ErrorCode.ERR_CantRefResource));
  399. result = emit(c1, output,
  400. new ResourceDescription[]
  401. {
  402. new ResourceDescription(r2Name, resourceFileName, () => new MemoryStream(resourceFileData), false)
  403. });
  404. Assert.False(result.Success);
  405. Assert.NotEmpty(result.Diagnostics.Where(x => x.Code == (int)ErrorCode.ERR_CantRefResource));
  406. var c_mod1 = CSharpCompilation.Create(
  407. Guid.NewGuid().ToString(),
  408. new[] { sourceTree },
  409. new[] { MscorlibRef },
  410. TestOptions.ReleaseModule);
  411. var output_mod1 = new MemoryStream();
  412. result = emit(c_mod1, output_mod1,
  413. new ResourceDescription[]
  414. {
  415. new ResourceDescription(r1Name, () => new MemoryStream(arrayOfEmbeddedData), true)
  416. });
  417. Assert.True(result.Success);
  418. var mod1 = ModuleMetadata.CreateFromImage(output_mod1.ToImmutable());
  419. var ref_mod1 = mod1.GetReference();
  420. Assert.Equal(ManifestResourceAttributes.Public, mod1.Module.GetEmbeddedResourcesOrThrow()[0].Attributes);
  421. {
  422. var c2 = CreateCompilationWithMscorlib(sourceTree, new[] { ref_mod1 }, TestOptions.ReleaseDll);
  423. var output2 = new MemoryStream();
  424. var result2 = c2.Emit(output2);
  425. Assert.True(result2.Success);
  426. var assembly = System.Reflection.Assembly.ReflectionOnlyLoad(output2.ToArray());
  427. assembly.ModuleResolve += (object sender, ResolveEventArgs e) =>
  428. {
  429. if (e.Name.Equals(c_mod1.SourceModule.Name))
  430. {
  431. return assembly.LoadModule(e.Name, output_mod1.ToArray());
  432. }
  433. return null;
  434. };
  435. string[] resourceNames = assembly.GetManifestResourceNames();
  436. Assert.Equal(1, resourceNames.Length);
  437. var rInfo = assembly.GetManifestResourceInfo(r1Name);
  438. Assert.Equal(System.Reflection.ResourceLocation.Embedded, rInfo.ResourceLocation);
  439. Assert.Equal(c_mod1.SourceModule.Name, rInfo.FileName);
  440. var rData = assembly.GetManifestResourceStream(r1Name);
  441. var rBytes = new byte[rData.Length];
  442. rData.Read(rBytes, 0, (int)rData.Length);
  443. Assert.Equal(arrayOfEmbeddedData, rBytes);
  444. }
  445. var c_mod2 = CSharpCompilation.Create(
  446. Guid.NewGuid().ToString(),
  447. new[] { sourceTree },
  448. new[] { MscorlibRef },
  449. TestOptions.ReleaseModule);
  450. var output_mod2 = new MemoryStream();
  451. result = emit(c_mod2, output_mod2,
  452. new ResourceDescription[]
  453. {
  454. new ResourceDescription(r1Name, () => new MemoryStream(arrayOfEmbeddedData), true),
  455. new ResourceDescription(r2Name, () => new MemoryStream(resourceFileData), true)
  456. });
  457. Assert.True(result.Success);
  458. var ref_mod2 = ModuleMetadata.CreateFromImage(output_mod2.ToImmutable()).GetReference();
  459. {
  460. var c3 = CreateCompilationWithMscorlib(sourceTree, new[] { ref_mod2 }, TestOptions.ReleaseDll);
  461. var output3 = new MemoryStream();
  462. var result3 = c3.Emit(output3);
  463. Assert.True(result3.Success);
  464. var assembly = Assembly.ReflectionOnlyLoad(output3.ToArray());
  465. assembly.ModuleResolve += (object sender, ResolveEventArgs e) =>
  466. {
  467. if (e.Name.Equals(c_mod2.SourceModule.Name))
  468. {
  469. return assembly.LoadModule(e.Name, output_mod2.ToArray());
  470. }
  471. return null;
  472. };
  473. string[] resourceNames = assembly.GetManifestResourceNames();
  474. Assert.Equal(2, resourceNames.Length);
  475. var rInfo = assembly.GetManifestResourceInfo(r1Name);
  476. Assert.Equal(ResourceLocation.Embedded, rInfo.ResourceLocation);
  477. Assert.Equal(c_mod2.SourceModule.Name, rInfo.FileName);
  478. var rData = assembly.GetManifestResourceStream(r1Name);
  479. var rBytes = new byte[rData.Length];
  480. rData.Read(rBytes, 0, (int)rData.Length);
  481. Assert.Equal(arrayOfEmbeddedData, rBytes);
  482. rInfo = assembly.GetManifestResourceInfo(r2Name);
  483. Assert.Equal(ResourceLocation.Embedded, rInfo.ResourceLocation);
  484. Assert.Equal(c_mod2.SourceModule.Name, rInfo.FileName);
  485. rData = assembly.GetManifestResourceStream(r2Name);
  486. rBytes = new byte[rData.Length];
  487. rData.Read(rBytes, 0, (int)rData.Length);
  488. Assert.Equal(resourceFileData, rBytes);
  489. }
  490. var c_mod3 = CSharpCompilation.Create(
  491. Guid.NewGuid().ToString(),
  492. new[] { sourceTree },
  493. new[] { MscorlibRef },
  494. TestOptions.ReleaseModule);
  495. var output_mod3 = new MemoryStream();
  496. result = emit(c_mod3, output_mod3,
  497. new ResourceDescription[]
  498. {
  499. new ResourceDescription(r2Name, () => new MemoryStream(resourceFileData), false)
  500. });
  501. Assert.True(result.Success);
  502. var mod3 = ModuleMetadata.CreateFromImage(output_mod3.ToImmutable());
  503. var ref_mod3 = mod3.GetReference();
  504. Assert.Equal(ManifestResourceAttributes.Private, mod3.Module.GetEmbeddedResourcesOrThrow()[0].Attributes);
  505. {
  506. var c4 = CreateCompilationWithMscorlib(sourceTree, new[] { ref_mod3 }, TestOptions.ReleaseDll);
  507. var output4 = new MemoryStream();
  508. var result4 = c4.Emit(output4, manifestResources:
  509. new ResourceDescription[]
  510. {
  511. new ResourceDescription(r1Name, () => new MemoryStream(arrayOfEmbeddedData), false)
  512. });
  513. Assert.True(result4.Success);
  514. var assembly = System.Reflection.Assembly.ReflectionOnlyLoad(output4.ToArray());
  515. assembly.ModuleResolve += (object sender, ResolveEventArgs e) =>
  516. {
  517. if (e.Name.Equals(c_mod3.SourceModule.Name))
  518. {
  519. return assembly.LoadModule(e.Name, output_mod3.ToArray());
  520. }
  521. return null;
  522. };
  523. string[] resourceNames = assembly.GetManifestResourceNames();
  524. Assert.Equal(2, resourceNames.Length);
  525. var rInfo = assembly.GetManifestResourceInfo(r1Name);
  526. Assert.Equal(ResourceLocation.Embedded | ResourceLocation.ContainedInManifestFile, rInfo.ResourceLocation);
  527. var rData = assembly.GetManifestResourceStream(r1Name);
  528. var rBytes = new byte[rData.Length];
  529. rData.Read(rBytes, 0, (int)rData.Length);
  530. Assert.Equal(arrayOfEmbeddedData, rBytes);
  531. rInfo = assembly.GetManifestResourceInfo(r2Name);
  532. Assert.Equal(ResourceLocation.Embedded, rInfo.ResourceLocation);
  533. Assert.Equal(c_mod3.SourceModule.Name, rInfo.FileName);
  534. rData = assembly.GetManifestResourceStream(r2Name);
  535. rBytes = new byte[rData.Length];
  536. rData.Read(rBytes, 0, (int)rData.Length);
  537. Assert.Equal(resourceFileData, rBytes);
  538. }
  539. {
  540. var c5 = CreateCompilationWithMscorlib(sourceTree, new[] { ref_mod1, ref_mod3 }, TestOptions.ReleaseDll);
  541. var output5 = new MemoryStream();
  542. var result5 = emit(c5, output5, null);
  543. Assert.True(result5.Success);
  544. var assembly = Assembly.ReflectionOnlyLoad(output5.ToArray());
  545. assembly.ModuleResolve += (object sender, ResolveEventArgs e) =>
  546. {
  547. if (e.Name.Equals(c_mod1.SourceModule.Name))
  548. {
  549. return assembly.LoadModule(e.Name, output_mod1.ToArray());
  550. }
  551. else if (e.Name.Equals(c_mod3.SourceModule.Name))
  552. {
  553. return assembly.LoadModule(e.Name, output_mod3.ToArray());
  554. }
  555. return null;
  556. };
  557. string[] resourceNames = assembly.GetManifestResourceNames();
  558. Assert.Equal(2, resourceNames.Length);
  559. var rInfo = assembly.GetManifestResourceInfo(r1Name);
  560. Assert.Equal(ResourceLocation.Embedded, rInfo.ResourceLocation);
  561. Assert.Equal(c_mod1.SourceModule.Name, rInfo.FileName);
  562. var rData = assembly.GetManifestResourceStream(r1Name);
  563. var rBytes = new byte[rData.Length];
  564. rData.Read(rBytes, 0, (int)rData.Length);
  565. Assert.Equal(arrayOfEmbeddedData, rBytes);
  566. rInfo = assembly.GetManifestResourceInfo(r2Name);
  567. Assert.Equal(ResourceLocation.Embedded, rInfo.ResourceLocation);
  568. Assert.Equal(c_mod3.SourceModule.Name, rInfo.FileName);
  569. rData = assembly.GetManifestResourceStream(r2Name);
  570. rBytes = new byte[rData.Length];
  571. rData.Read(rBytes, 0, (int)rData.Length);
  572. Assert.Equal(resourceFileData, rBytes);
  573. }
  574. {
  575. var c6 = CreateCompilationWithMscorlib(sourceTree, new[] { ref_mod1, ref_mod2 }, TestOptions.ReleaseDll);
  576. var output6 = new MemoryStream();
  577. var result6 = emit(c6, output6, null);
  578. if (metadataOnly)
  579. {
  580. Assert.True(result6.Success);
  581. }
  582. else
  583. {
  584. Assert.False(result6.Success);
  585. result6.Diagnostics.Verify(
  586. // error CS1508: Resource identifier 'some.dotted.NAME' has already been used in this assembly
  587. Diagnostic(ErrorCode.ERR_ResourceNotUnique).WithArguments("some.dotted.NAME")
  588. );
  589. }
  590. result6 = emit(c6, output6,
  591. new ResourceDescription[]
  592. {
  593. new ResourceDescription(r2Name, () => new MemoryStream(resourceFileData), false)
  594. });
  595. if (metadataOnly)
  596. {
  597. Assert.True(result6.Success);
  598. }
  599. else
  600. {
  601. Assert.False(result6.Success);
  602. result6.Diagnostics.Verify(
  603. // error CS1508: Resource identifier 'some.dotted.NAME' has already been used in this assembly
  604. Diagnostic(ErrorCode.ERR_ResourceNotUnique).WithArguments("some.dotted.NAME"),
  605. // error CS1508: Resource identifier 'another.DoTtEd.NAME' has already been used in this assembly
  606. Diagnostic(ErrorCode.ERR_ResourceNotUnique).WithArguments("another.DoTtEd.NAME")
  607. );
  608. }
  609. c6 = CreateCompilationWithMscorlib(sourceTree, new[] { ref_mod1, ref_mod2 }, TestOptions.ReleaseModule);
  610. result6 = emit(c6, output6,
  611. new ResourceDescription[]
  612. {
  613. new ResourceDescription(r2Name, () => new MemoryStream(resourceFileData), false)
  614. });
  615. Assert.True(result6.Success);
  616. }
  617. }
  618. }
  619. [Fact]
  620. public void AddManagedLinkedResourceFail()
  621. {
  622. string source = @"
  623. public class Maine
  624. {
  625. static public void Main()
  626. {
  627. }
  628. }
  629. ";
  630. var c1 = CreateCompilationWithMscorlib(source);
  631. var output = new MemoryStream();
  632. const string r2Name = "another.DoTtEd.NAME";
  633. var result = c1.Emit(output, manifestResources:
  634. new ResourceDescription[]
  635. {
  636. new ResourceDescription(r2Name, "nonExistent", () => { throw new NotSupportedException("error in data provider"); }, false)
  637. });
  638. Assert.False(result.Success);
  639. Assert.Equal((int)ErrorCode.ERR_CantReadResource, result.Diagnostics.ToArray()[0].Code);
  640. }
  641. [Fact]
  642. public void AddManagedEmbeddedResourceFail()
  643. {
  644. string source = @"
  645. public class Maine
  646. {
  647. static public void Main()
  648. {
  649. }
  650. }
  651. ";
  652. var c1 = CreateCompilationWithMscorlib(source);
  653. var output = new MemoryStream();
  654. const string r2Name = "another.DoTtEd.NAME";
  655. var result = c1.Emit(output, manifestResources:
  656. new ResourceDescription[]
  657. {
  658. new ResourceDescription(r2Name, () => null, true),
  659. });
  660. Assert.False(result.Success);
  661. Assert.Equal((int)ErrorCode.ERR_CantReadResource, result.Diagnostics.ToArray()[0].Code);
  662. }
  663. [Fact]
  664. public void ResourceWithAttrSettings()
  665. {
  666. string source = @"
  667. [assembly: System.Reflection.AssemblyVersion(""1.2.3.4"")]
  668. [assembly: System.Reflection.AssemblyFileVersion(""5.6.7.8"")]
  669. [assembly: System.Reflection.AssemblyTitle(""One Hundred Years of Solitude"")]
  670. [assembly: System.Reflection.AssemblyDescription(""A classic of magical realist literature"")]
  671. [assembly: System.Reflection.AssemblyCompany(""MossBrain"")]
  672. [assembly: System.Reflection.AssemblyProduct(""Sound Cannon"")]
  673. [assembly: System.Reflection.AssemblyCopyright(""circle C"")]
  674. [assembly: System.Reflection.AssemblyTrademark(""circle R"")]
  675. [assembly: System.Reflection.AssemblyInformationalVersion(""1.2.3garbage"")]
  676. public class Maine
  677. {
  678. public static void Main()
  679. {
  680. }
  681. }
  682. ";
  683. var c1 = CreateCompilationWithMscorlib(source, assemblyName: "Win32VerAttrs", options: TestOptions.ReleaseExe);
  684. var exeFile = Temp.CreateFile();
  685. using (FileStream output = exeFile.Open())
  686. {
  687. c1.Emit(output, win32Resources: c1.CreateDefaultWin32Resources(true, false, null, null));
  688. }
  689. c1 = null;
  690. string versionData;
  691. //Open as data
  692. IntPtr lib = IntPtr.Zero;
  693. try
  694. {
  695. lib = LoadLibraryEx(exeFile.Path, IntPtr.Zero, 0x00000002);
  696. Assert.True(lib != IntPtr.Zero, String.Format("LoadLibrary failed with HResult: {0:X}", +Marshal.GetLastWin32Error()));
  697. //the manifest and version primitives are tested elsewhere. This is to test that the default
  698. //values are passed to the primitives that assemble the resources.
  699. uint size;
  700. IntPtr versionRsrc = Win32Res.GetResource(lib, "#1", "#16", out size);
  701. versionData = Win32Res.VersionResourceToXml(versionRsrc);
  702. }
  703. finally
  704. {
  705. if (lib != IntPtr.Zero)
  706. {
  707. FreeLibrary(lib);
  708. }
  709. }
  710. string expected =
  711. @"<?xml version=""1.0"" encoding=""utf-16""?>
  712. <VersionResource Size=""964"">
  713. <VS_FIXEDFILEINFO FileVersionMS=""00050006"" FileVersionLS=""00070008"" ProductVersionMS=""00000000"" ProductVersionLS=""00000000"" />
  714. <KeyValuePair Key=""Comments"" Value=""A classic of magical realist literature"" />
  715. <KeyValuePair Key=""CompanyName"" Value=""MossBrain"" />
  716. <KeyValuePair Key=""FileDescription"" Value=""One Hundred Years of Solitude"" />
  717. <KeyValuePair Key=""FileVersion"" Value=""5.6.7.8"" />
  718. <KeyValuePair Key=""InternalName"" Value=""Win32VerAttrs.exe"" />
  719. <KeyValuePair Key=""LegalCopyright"" Value=""circle C"" />
  720. <KeyValuePair Key=""LegalTrademarks"" Value=""circle R"" />
  721. <KeyValuePair Key=""OriginalFilename"" Value=""Win32VerAttrs.exe"" />
  722. <KeyValuePair Key=""ProductName"" Value=""Sound Cannon"" />
  723. <KeyValuePair Key=""ProductVersion"" Value=""1.2.3garbage"" />
  724. <KeyValuePair Key=""Assembly Version"" Value=""1.2.3.4"" />
  725. </VersionResource>";
  726. Assert.Equal(expected, versionData);
  727. }
  728. }
  729. }