Added support for .NET embedded resources

This commit is contained in:
Yoshi Askharoun
2022-07-05 15:15:26 -05:00
parent c09f29e92c
commit e5ae6cd7cb
2 changed files with 120 additions and 0 deletions
+58
View File
@@ -0,0 +1,58 @@
using Microsoft.Iris.Data;
using System;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
namespace Microsoft.Iris.OS
{
internal class ClrDllResource : Resource
{
private Assembly _assembly;
private string _identifier;
private GCHandle _handle;
private IntPtr _buffer;
private uint _length;
internal ClrDllResource(string uri, Assembly assembly, string identifier)
: base(uri, true)
{
_assembly = assembly;
_identifier = identifier;
}
public override string Identifier => _identifier;
protected override void StartAcquisition(bool forceSynchronous)
{
string errorDetails = null;
if (_buffer == IntPtr.Zero)
{
try
{
var resName = _assembly.GetManifestResourceNames()
.First(s => s.EndsWith("." + _identifier, StringComparison.OrdinalIgnoreCase));
using System.IO.Stream fs = _assembly.GetManifestResourceStream(resName);
var data = new byte[fs.Length];
fs.Read(data, 0, (int)fs.Length);
_handle = GCHandle.Alloc(data, GCHandleType.Pinned);
_buffer = _handle.AddrOfPinnedObject();
_length = (uint)data.LongLength;
}
catch
{
errorDetails = $"Resource not found: {ClrDllResources.Scheme}://{_assembly.Location}!{_identifier}";
}
}
NotifyAcquisitionComplete(_buffer, _length, false, errorDetails);
}
protected override void CancelAcquisition()
{
}
public override string ToString() => _assembly.GetName().Name + "|" + _identifier.ToLowerInvariant();
}
}
+62
View File
@@ -0,0 +1,62 @@
using Microsoft.Iris.Data;
using Microsoft.Iris.Library;
using Microsoft.Iris.Markup;
using Microsoft.Iris.Session;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
namespace Microsoft.Iris.OS
{
internal class ClrDllResources : IResourceProvider
{
public const string Scheme = "clr-res";
private static ClrDllResources s_instance = new ClrDllResources();
private Dictionary<string, Assembly> _shortNameToAssembly;
private ClrDllResources() => _shortNameToAssembly = new Dictionary<string, Assembly>(InvariantString.OrdinalIgnoreCaseComparer);
public static ClrDllResources Instance => s_instance;
public Resource GetResource(string hierarchicalPart, string uri, bool forceSynchronous)
{
Resource resource = null;
DllResources.ParseResource(hierarchicalPart, out string host, out string identifier);
if (host != null)
{
Assembly assembly = GetAssembly(host);
if (assembly != null)
resource = new ClrDllResource(uri, assembly, identifier);
}
if (resource == null)
ErrorManager.ReportError($"Invalid resource uri: '{uri}'");
return resource;
}
public Assembly GetAssembly(string moduleName)
{
if (!_shortNameToAssembly.TryGetValue(moduleName, out Assembly a))
{
AssemblyName name = null;
try
{
name = new AssemblyName(moduleName);
}
catch (COMException)
{
}
catch (IOException)
{
}
if (name != null)
a = AssemblyLoadResult.FindAssembly(name, out _);
_shortNameToAssembly[moduleName] = a;
}
return a;
}
}
}