-
Notifications
You must be signed in to change notification settings - Fork 4.8k
/
Copy pathComHost.cs
72 lines (64 loc) · 3.14 KB
/
ComHost.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace Microsoft.NET.HostModel.ComHost
{
public class ComHost
{
// These need to match RESOURCEID_CLSIDMAP and RESOURCETYPE_CLSIDMAP defined in comhost.h.
private const int ClsidmapResourceId = 64;
private const int ClsidmapResourceType = 1024;
/// <summary>
/// Create a ComHost with an embedded CLSIDMap file to map CLSIDs to .NET Classes.
/// </summary>
/// <param name="comHostSourceFilePath">The path of the comhost library</param>
/// <param name="comHostDestinationFilePath">The destination path for desired location to place, including the file name</param>
/// <param name="clsidmapFilePath">The path to the *.clsidmap file.</param>
/// <param name="typeLibraries">Resource IDs for tlbs and paths to the tlb files to be embedded.</param>
public static void Create(
string comHostSourceFilePath,
string comHostDestinationFilePath,
string clsidmapFilePath,
IReadOnlyDictionary<int, string> typeLibraries = null)
{
var destinationDirectory = new FileInfo(comHostDestinationFilePath).Directory.FullName;
if (!Directory.Exists(destinationDirectory))
{
Directory.CreateDirectory(destinationDirectory);
}
// Copy comhost to destination path so it inherits the same attributes/permissions.
File.Copy(comHostSourceFilePath, comHostDestinationFilePath, overwrite: true);
string clsidMap = File.ReadAllText(clsidmapFilePath);
byte[] clsidMapBytes = Encoding.UTF8.GetBytes(clsidMap);
using (ResourceUpdater updater = new ResourceUpdater(comHostDestinationFilePath))
{
updater.AddResource(clsidMapBytes, (IntPtr)ClsidmapResourceType, (IntPtr)ClsidmapResourceId);
if (typeLibraries is not null)
{
foreach (var typeLibrary in typeLibraries)
{
if (!ResourceUpdater.IsIntResource((IntPtr)typeLibrary.Key))
{
throw new InvalidTypeLibraryIdException(typeLibrary.Value, typeLibrary.Key);
}
try
{
byte[] tlbFileBytes = File.ReadAllBytes(typeLibrary.Value);
if (tlbFileBytes.Length == 0)
throw new InvalidTypeLibraryException(typeLibrary.Value);
updater.AddResource(tlbFileBytes, "TYPELIB", (IntPtr)typeLibrary.Key);
}
catch (FileNotFoundException ex)
{
throw new TypeLibraryDoesNotExistException(typeLibrary.Value, ex);
}
}
}
updater.Update();
}
}
}
}