mirror of
https://github.com/ZuneDev/MicrosoftIris.git
synced 2026-07-27 13:13:29 -07:00
Added support for .NET embedded resources
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user