The following will explain how to encrypt your own program through LiteDB. Let's introduce LiteDB to implement it.
LiteDB
LiteDB is a lightweight embedded database written in C#for use on the. NET platform. It is designed to provide an easy-to-use database solution that can be used in a variety of applications.
LiteDB uses a single file as a database store, which can be on disk or in memory. It supports a document storage model, similar to a NoSQL database, where each document is a JSON formatted object. This means that you can store and retrieve any type of data without requiring a predefined schema.
LiteDB provides a simple set of APIs to perform various database operations, including inserts, updates, deletes, and queries. It also supports transactions to ensure data consistency and integrity.
LiteDB also provides advanced features such as indexing, full-text search and file storage. Indexing can speed up queries, full-text search can perform keyword searches in text data, and file storage can store files directly in the database.
Advantages of LiteDB include ease of use, lightweight, fast and embeddable. Its code base is very small and can be easily integrated into your application. In addition, it has cross-platform capabilities and can run on operating systems such as Windows, Linux and Mac.
In summary, LiteDB is an easy-to-use embedded database suitable for a variety of applications. It provides a simple set of APIs to perform database operations and supports some advanced features. If you need a lightweight database solution, consider using LiteDB.
cryptographic encapsulation
创建LiteDB.Service的 WebApi 项目。
Right click to publish:

创建控制台LiteDB.Launch项目。
EntryPointDiscoverer.cs 用于寻找执行方法。
internal class EntryPointDiscoverer
{
public static MethodInfo FindStaticEntryMethod(Assembly assembly, string? entryPointFullTypeName = null)
{
var candidates = new List<MethodInfo>();
if (!string.IsNullOrWhiteSpace(entryPointFullTypeName))
{
var typeInfo = assembly.GetType(entryPointFullTypeName, false, false)?.GetTypeInfo();
if (typeInfo == null)
{
throw new InvalidProgramException($"Could not find '{entryPointFullTypeName}' specified for Main method. See <StartupObject> project property.");
}
FindMainMethodCandidates(typeInfo, candidates);
}
else
{
foreach (var type in assembly
.DefinedTypes
.Where(t => t.IsClass)
.Where(t => t.GetCustomAttribute<CompilerGeneratedAttribute>() is null))
{
FindMainMethodCandidates(type, candidates);
}
}
string MainMethodFullName()
{
return string.IsNullOrWhiteSpace(entryPointFullTypeName) ? "Main" : $"{entryPointFullTypeName}.Main";
}
if (candidates.Count > 1)
{
throw new AmbiguousMatchException(
$"Ambiguous entry point. Found multiple static functions named '{MainMethodFullName()}'. Could not identify which method is the main entry point for this function.");
}
if (candidates.Count == 0)
{
throw new InvalidProgramException(
$"Could not find a static entry point '{MainMethodFullName()}'.");
}
return candidates[0];
}
private static void FindMainMethodCandidates(TypeInfo type, List<MethodInfo> candidates)
{
foreach (var method in type
.GetMethods(BindingFlags.Static |
BindingFlags.Public |
BindingFlags.NonPublic)
.Where(m =>
string.Equals("Main", m.Name, StringComparison.OrdinalIgnoreCase)))
{
if (method.ReturnType == typeof(void)
|| method.ReturnType == typeof(int)
|| method.ReturnType == typeof(Task)
|| method.ReturnType == typeof(Task<int>))
{
candidates.Add(method);
}
}
}
}
然后打开Program.cs文件,请注意修改 SaveDb 的参数为自己项目打包的地址
// 用于打包指定程序。
SaveDb(@"E:\Project\LiteDB-Application\LiteDB.Service\bin\Release\net7.0\publish");
// 打开db
var db = new LiteDatabase("Launch.db");
// 打开表。
var files = db.GetCollection<FileAssembly>("files");
// 接管未找到的程序集处理
AppDomain.CurrentDomain.AssemblyResolve += (sender, eventArgs) =>
{
try
{
var name = eventArgs.Name.Split(",")[0];
if (!name.EndsWith(".dll"))
{
name += ".dll";
}
var file = files.FindOne(x => x.Name == name);
return file != null ? Assembly.Load(file.Bytes) : default;
}
catch (Exception)
{
return default;
}
};
// 启动程序。
StartServer("LiteDB.Service", new string[] { });
Console.ReadKey();
void StartServer(string assemblyName, string[] args)
{
var value = files!.FindOne(x => x.Name == assemblyName + ".dll");
var assembly = Assembly.Load(value!.Bytes);
var entryPoint = EntryPointDiscoverer.FindStaticEntryMethod(assembly);
try
{
var parameters = entryPoint.GetParameters();
if (parameters.Length != 0)
{
var parameterValues = parameters.Select(p =>
p.ParameterType.IsValueType ? Activator.CreateInstance(p.ParameterType) : null)
.ToArray();
entryPoint.Invoke(null, parameterValues);
}
else
{
entryPoint.Invoke(null, null);
}
}
catch (Exception e)
{
}
}
// 扫描指定目录下所有文件和子目录,保存到LiteDB数据库中。
void SaveDb(string path)
{
var files = ScanDirectory(path);
using var db = new LiteDatabase("Launch.db");
var col = db.GetCollection<FileAssembly>("files");
col.InsertBulk(files);
}
// 实现一个方法,扫描指定目录下所有文件和子目录,返回一个集合。
List<FileAssembly> ScanDirectory(string path)
{
var files = new List<FileAssembly>();
var dir = new DirectoryInfo(path);
var fileInfos = dir.GetFiles("*", SearchOption.AllDirectories);
foreach (var fileInfo in fileInfos)
{
var file = new FileAssembly
{
Name = fileInfo.Name,
Bytes = File.ReadAllBytes(fileInfo.FullName)
};
files.Add(file);
}
return files;
}
class FileAssembly
{
/// <summary>
/// 文件名
/// </summary>
public string Name { get; set; }
/// <summary>
/// 文件的内容
/// </summary>
public byte[] Bytes { get; set; }
}
点击LiteDB.Launch项目文件,添加 LiteDB 依赖,并且修改 SDK 为Microsoft.NET.Sdk.Web
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="LiteDB" Version="5.0.17" />
</ItemGroup>
</Project>
在启动项目的时候先将LiteDB.Service发布一下。然后修改SaveDb参数为发布的目录(会自动扫描所有文件打包到 LiteDB 的文件中。)
Then start the project;

当我们启动了LiteDB.Launch以后在StartServer方法里面就会打开创建的 LiteDB 文件中搜索到指定的启动程序集。
然后在AppDomain.CurrentDomain.AssemblyResolve中会将启动程序集缺少的程序集加载到域中。
AppDomain.CurrentDomain.AssemblyResolve会在未找到依赖的时候触发的一个事件。
在存储到 LiteDB 的时候可以对于存储的内容进行加密,然后在AppDomain.CurrentDomain.AssemblyResolve触发的时候将读取 LiteDB 的文件的内容的时候进行解密。
end
Sharing from token
Qq technical exchange group: 737776595