- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
下面将介绍如何通过 LiteDB 将自己的程序进行加密,首先介绍一下 LiteDB .
LiteDB是一个轻量级的嵌入式数据库,它是用C#编写的,适用于.NET平台。它的设计目标是提供一个简单易用的数据库解决方案,可以在各种应用程序中使用.
LiteDB使用单个文件作为数据库存储,这个文件可以在磁盘上或内存中。它支持文档存储模型,类似于NoSQL数据库,每个文档都是一个JSON格式的对象。这意味着你可以存储和检索任意类型的数据,而不需要预定义模式.
LiteDB提供了一组简单的API来执行各种数据库操作,包括插入、更新、删除和查询。它还支持事务,可以确保数据的一致性和完整性.
LiteDB还提供了一些高级功能,如索引、全文搜索和文件存储。索引可以加快查询的速度,全文搜索可以在文本数据中进行关键字搜索,文件存储可以将文件直接存储在数据库中.
LiteDB的优点包括易于使用、轻量级、快速和可嵌入性。它的代码库非常小,可以很容易地集成到你的应用程序中。此外,它还具有跨平台的能力,可以在Windows、Linux和Mac等操作系统上运行.
总之,LiteDB是一个简单易用的嵌入式数据库,适用于各种应用程序。它提供了一组简单的API来执行数据库操作,并支持一些高级功能。如果你需要一个轻量级的数据库解决方案,可以考虑使用LiteDB.
创建 LiteDB.Service 的WebApi项目.
右键发布:
创建控制台 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的文件中。) 。
然后启动项目; 。
当我们启动了 LiteDB.Launch 以后在 StartServer 方法里面就会打开创建的LiteDB文件中搜索到指定的启动程序集.
然后在 AppDomain.CurrentDomain.AssemblyResolve 中会将启动程序集缺少的程序集加载到域中.
AppDomain.CurrentDomain.AssemblyResolve 会在未找到依赖的时候触发的一个事件.
在存储到LiteDB的时候可以对于存储的内容进行加密,然后在 AppDomain.CurrentDomain.AssemblyResolve 触发的时候将读取LiteDB的文件的内容的时候进行解密.
来自token的分享 。
qq技术交流群:737776595 。
最后此篇关于c#如何将程序加密隐藏?的文章就讲到这里了,如果你想了解更多关于c#如何将程序加密隐藏?的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我是 C 语言新手,我编写了这个 C 程序,让用户输入一年中的某一天,作为返回,程序将输出月份以及该月的哪一天。该程序运行良好,但我现在想简化该程序。我知道我需要一个循环,但我不知道如何去做。这是程序
我一直在努力找出我的代码有什么问题。这个想法是创建一个小的画图程序,并有红色、绿色、蓝色和清除按钮。我有我能想到的一切让它工作,但无法弄清楚代码有什么问题。程序打开,然后立即关闭。 import ja
我想安装screen,但是接下来我应该做什么? $ brew search screen imgur-screenshot screen
我有一个在服务器端工作的 UDP 套接字应用程序。为了测试服务器端,我编写了一个简单的 python 客户端程序,它发送消息“hello world how are you”。服务器随后应接收消息,将
我有一个 shell 脚本,它运行一个 Python 程序来预处理一些数据,然后运行一个 R 程序来执行一些长时间运行的任务。我正在学习使用 Docker 并且我一直在运行 FROM r-base:l
在 Linux 中。我有一个 c 程序,它读取一个 2048 字节的文本文件作为输入。我想从 Python 脚本启动 c 程序。我希望 Python 脚本将文本字符串作为参数传递给 c 程序,而不是将
前言 最近开始整理笔记里的库存草稿,本文是 23 年 5 月创建的了(因为中途转移到 onedrive,可能还不止) 网页调起电脑程序是经常用到的场景,比如百度网盘下载,加入 QQ 群之类的 我
对于一个类,我被要求编写一个 VHDL 程序,该程序接受两个整数输入 A 和 B,并用 A+B 替换 A,用 A-B 替换 B。我编写了以下程序和测试平台。它完成了实现和行为语法检查,但它不会模拟。尽
module Algorithm where import System.Random import Data.Maybe import Data.List type Atom = String ty
我想找到两个以上数字的最小公倍数 求给定N个数的最小公倍数的C++程序 最佳答案 int lcm(int a, int b) { return (a/gcd(a,b))*b; } 对于gcd,请查看
这个程序有错误。谁能解决这个问题? Error is :TempRecord already defines a member called 'this' with the same paramete
当我运行下面的程序时,我在 str1 和 str2 中得到了垃圾值。所以 #include #include #include using namespace std; int main() {
这是我的作业: 一对刚出生的兔子(一公一母)被放在田里。兔子在一个月大时可以交配,因此在第二个月的月底,每对兔子都会生出两对新兔子,然后死去。 注:在第0个月,有0对兔子。第 1 个月,有 1 对兔子
我编写了一个程序,通过对字母使用 switch 命令将十进制字符串转换为十六进制,但是如果我使用 char,该程序无法正常工作!没有 switch 我无法处理 9 以上的数字。我希望你能理解我,因为我
我是 C++ 新手(虽然我有一些 C 语言经验)和 MySQL,我正在尝试制作一个从 MySQL 读取数据库的程序,我一直在关注这个 tutorial但当我尝试“构建”解决方案时出现错误。 (我正在使
仍然是一个初学者,只是尝试使用 swift 中的一些基本函数。 有人能告诉我这段代码有什么问题吗? import UIKit var guessInt: Int var randomNum = arc
我正在用 C++11 编写一个函数,它采用 constant1 + constant2 形式的表达式并将它们折叠起来。 constant1 和 constant2 存储在 std::string 中,
我用 C++ 编写了这段代码,使用运算符重载对 2 个矩阵进行加法和乘法运算。当我执行代码时,它会在第 57 行和第 59 行产生错误,非法结构操作(两行都出现相同的错误)。请解释我的错误。提前致谢:
我是 C++ 的初学者,我想编写一个简单的程序来交换字符串中的两个字符。 例如;我们输入这个字符串:“EXAMPLE”,我们给它交换这两个字符:“E”和“A”,输出应该类似于“AXEMPLA”。 我在
我需要以下代码的帮助: 声明 3 个 double 类型变量,每个代表三角形的三个边中的一个。 提示用户为第一面输入一个值,然后 将用户的输入设置为您创建的代表三角形第一条边的变量。 将最后 2 个步
我是一名优秀的程序员,十分优秀!