-
-
Notifications
You must be signed in to change notification settings - Fork 7
Separate DLL Files
Roy Schroedel edited this page Jan 15, 2020
·
1 revision
The library is compiled for several CPU architectures. This allows the library to be integrated without IDE warnings. The compiler is also instructed to process certain areas differently, which in certain cases can lead to minor performance advantages. In many cases, this can be safely ignored. But it would still be possible to benefit from it on Any CPU
platform targets.
- Add the file
SilDev.CSharpLib.dll
to the references of your project- Set
Copy Local
inProperties
toFalse
- Set
- Copy the files
SilDev.CSharpLib32.dll
andSilDev.CSharpLib64.dll
to the location of the compiled binary files - Add some code to the
Startup object
of your project
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Xml;
internal static class Program
{
[STAThread]
private static void Main()
{
AppDomain.CurrentDomain.AssemblyResolve += DynamicAssemblyResolve;
/*
add your code here...
*/
}
/// <summary>
/// Loads the required assembly dynamically based on the current process architecture.
/// </summary>
private static Assembly DynamicAssemblyResolve(object sender, ResolveEventArgs args)
{
var name = args.Name;
if (!name.StartsWith("SilDev.", StringComparison.Ordinal))
return null;
var length = name.IndexOf(',');
name = name.Substring(0, length);
return (from dir in GetProbingDirs()
select Environment.Is64BitProcess ?
Path.Combine(dir, $"{name}64.dll") :
Path.Combine(dir, $"{name}32.dll")
into path
where File.Exists(path)
select Assembly.LoadFile(path)).FirstOrDefault();
}
/// <summary>
/// Enables support for the `probing privatePath` settings through the `MyApplication.exe.config` file.
/// </summary>
private static IEnumerable<string> GetProbingDirs()
{
var baseDir = AppDomain.CurrentDomain.BaseDirectory.TrimEnd(Path.DirectorySeparatorChar);
yield return baseDir;
var configPath = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
if (!File.Exists(configPath))
yield break;
FileStream fileStream = default;
string xmlEntry;
try
{
const string xpath = "/*[name()='configuration']/*[name()='runtime']/*[name()='assemblyBinding']/*[name()='probing']/@privatePath";
fileStream = new FileStream(configPath, FileMode.Open);
using (var xmlReader = XmlReader.Create(fileStream, new XmlReaderSettings()))
{
fileStream = default;
var xmlDoc = new XmlDocument
{
XmlResolver = null
};
xmlDoc.Load(xmlReader);
xmlEntry = (xmlDoc.SelectSingleNode(xpath) as XmlAttribute)?.Value;
if (string.IsNullOrWhiteSpace(xmlEntry))
throw new ArgumentException();
}
}
#pragma warning disable CA1031 // Do not catch general exception types
catch
#pragma warning restore CA1031 // Do not catch general exception types
{
yield break;
}
finally
{
fileStream?.Dispose();
}
if (xmlEntry.Contains(";"))
foreach (var item in xmlEntry.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
yield return Path.Combine(baseDir, item);
else
yield return Path.Combine(baseDir, xmlEntry);
}
}