当前位置: 首页 > news >正文

C# .Net 发布后,把dll全部放在一个文件夹中,让软件目录更整洁

PublishFolderCleaner – Github

测试环境:

.Net 8

Program.cs 代码

// https://github.com/dotnet-campus/dotnetcampus.DotNETBuildSDK/tree/master/PublishFolderCleanerusing System.Diagnostics;
using System.Text;// 名称, 不用写 .exe
var exeName = "AbpDemo";
// 目录
var publishFolder = "D:\\Work\\CSharpProject\\AbpDemo\\AbpDemo\\bin\\Debug\\net8.0";const string libFolderName = "lib";
var libFolder = Path.GetFullPath(Path.Combine(publishFolder, libFolderName));
var tempFolder = Path.GetFullPath(Path.Combine(publishFolder, @"..", Path.GetRandomFileName()));
Directory.Move(publishFolder, tempFolder);
Directory.CreateDirectory(publishFolder);
Directory.Move(tempFolder, libFolder);var appHostFilePath = Path.Combine(libFolder, exeName + ".exe");
var newAppHostFilePath = Path.Combine(publishFolder, exeName + ".exe");File.Move(appHostFilePath, newAppHostFilePath);Patch(newAppHostFilePath, Path.Combine("lib", exeName + ".dll"));/// <summary>
/// 这里有 1024 个 byte 空间用来决定加载路径
/// 详细请看 dotnet runtime\src\installer\corehost\corehost.cpp 的注释
/// </summary>
const int MaxPathBytes = 1024;int Patch(string appHostExe, string newPath)
{try{var origPath = Path.GetFileName(ChangeExecutableExtension(appHostExe));if (!File.Exists(appHostExe)){Console.WriteLine($"AppHost '{appHostExe}' does not exist");return 1;}if (origPath == string.Empty){Console.WriteLine("Original path is empty");return 1;}var origPathBytes = Encoding.UTF8.GetBytes(origPath + "\0");Debug.Assert(origPathBytes.Length > 0);var newPathBytes = Encoding.UTF8.GetBytes(newPath + "\0");if (origPathBytes.Length > MaxPathBytes){Console.WriteLine($"Original path is too long");return 1;}if (newPathBytes.Length > MaxPathBytes){Console.WriteLine($"New path is too long");return 1;}var appHostExeBytes = File.ReadAllBytes(appHostExe);int offset = GetOffset(appHostExeBytes, origPathBytes);if (offset < 0){Console.WriteLine($"Could not find original path '{origPath}'");return 1;}if (offset + newPathBytes.Length > appHostExeBytes.Length){Console.WriteLine($"New path is too long: {newPath}");return 1;}for (int i = 0; i < newPathBytes.Length; i++)appHostExeBytes[offset + i] = newPathBytes[i];File.WriteAllBytes(appHostExe, appHostExeBytes);return 0;}catch (Exception ex){Console.WriteLine(ex.ToString());return 1;}
}string ChangeExecutableExtension(string apphostExe) =>// Windows apphosts have an .exe extension. Don't call Path.ChangeExtension() unless it's guaranteed// to have an .exe extension, eg. 'some.file' => 'some.file.dll', not 'some.dll'apphostExe.EndsWith(".exe", StringComparison.OrdinalIgnoreCase) ? Path.ChangeExtension(apphostExe, ".dll") : apphostExe + ".dll";int GetOffset(byte[] bytes, byte[] pattern)
{int si = 0;var b = pattern[0];while (si < bytes.Length){si = Array.IndexOf(bytes, b, si);if (si < 0)break;if (Match(bytes, si, pattern))return si;si++;}return -1;
}bool Match(byte[] bytes, int index, byte[] pattern)
{if (index + pattern.Length > bytes.Length)return false;for (int i = 0; i < pattern.Length; i++){if (bytes[index + i] != pattern[i])return false;}return true;
}

效果真不错

在这里插入图片描述

相关文章:

C# .Net 发布后,把dll全部放在一个文件夹中,让软件目录更整洁

PublishFolderCleaner – Github 测试环境: .Net 8 Program.cs 代码 // https://github.com/dotnet-campus/dotnetcampus.DotNETBuildSDK/tree/master/PublishFolderCleanerusing System.Diagnostics; using System.Text;// 名称, 不用写 .exe var exeName "AbpDemo&…...

[更新]ARCGIS之土地耕地占补平衡、进出平衡系统报备坐标txt格式批量导出工具(定制开发版)

序言 之前开发的耕地占补平衡报备格式&#xff0c;现在之前的基础上集成了耕地进出平衡报备格式导出。 之前版本软件详见&#xff1a;软件介绍 一、软件简介 本软件是基于arcgis二次开发的工具&#xff08;插件&#xff09;&#xff0c;需要授权后才能使用&#xff1b; 本软件…...

todolist

一开始想自己写个todolist的网页&#xff0c;一直没时间&#xff0c;直接拿这个博客记录了&#xff0c;因为仅我可见比较麻烦&#xff0c;就放在全部可见记录了 目录 2024年3月todoes了解一下深入学习k8s&#xff0c;比如pod运行多个容器 &#xff0c;编写自己的镜像 2024年2月…...

【Java程序设计】【C00307】基于Springboot的基Hadoop的物品租赁管理系统(有论文)

基于Springboot的基Hadoop的物品租赁管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的基于 Hadoop的物品租赁系统的设计与实现&#xff0c;本系统有管理员、用户二种角色权限&#xff1b; 前台首页&#…...

GIT中对子仓库的使用方法介绍

git 子仓库 主仓库中添加子仓库 git submodule add <url> <path>更新子代码代码 git submodule update --init克隆含有子仓库的仓库 git clone --recurse-submodules <url>主仓库中删除子仓库 1、进入包含子仓库的父仓库的根目录 2、使用以下命令将子仓…...

ClickHouse 指南(三)最佳实践 -- 跳数索引

Data Skipping Indexes Data Skipping Indexes 2 1、简介 影响ClickHouse查询性能的因素很多。在大多数情况下&#xff0c;关键因素是ClickHouse在计算查询WHERE子句条件时是否可以使用主键。因此&#xff0c;选择适用于最常见查询模式的主键对于有效的表设计至关重要。 然…...

Mybatis总结--传参二

#叫做占位符 Mybatis是封装的JDBC 增强版 内部还是用的jdbc 每遇到一个#号 这里就会变为&#xff1f;占位符 一个#{}就是对应一个问号 一个占位符 用这个对象执行sql语句没有sql注入的风险 八、多个参数-使用Param 当 Dao 接口方法有多个参数&#xff0c;需要通过名称使…...

2024年数字化转型风口趋势大赏

人工智能和自动化确实为提高效率和数据驱动的见解提供了巨大的潜力&#xff0c;但这些技术无法完全取代人类技能和情境决策。在混合模型中将人工智能功能与人类专业知识相结合的企业将实现最大的效益。 随着人工智能和自动化的不断发展&#xff0c;企业必须调整其战略、流程和人…...

某款服务器插上4张TDP功耗75瓦PCIE卡无法开机的调试过程

1.服务器厂家说这款服务器测过别家的4卡&#xff0c;所以一开始并没有怀疑服务器硬件有问题 2.拔掉另外三张&#xff0c;只保留cpu0对应的riser0 slot0上的一张卡&#xff0c;仍然无法开机。 3.怀疑是这张pcie卡bar空间太大导致。换另一款bar空间小的卡&#xff0c;仍然无法开…...

数据结构与算法——排序算法

目录 文章目录 前言 一.排序的基本概念 1.什么是就地排序 2.什么是内部排序和外部排序 3.什么是稳定排序 4.判定一个排序算法的是稳定的 二.插入排序算法 1.直接插入排序 1.1基本思想 1.2复杂度 1.3稳定性 1.4代码演示 2.折半插入排序 2.1基本思想 2.2性能 3.…...

阿里巴巴alibaba API商品详情接口系列(商品属性,价格,主图)阿里巴巴alibaba根据ID取商品详情 API 返回值说明

阿里巴巴Alibaba的API商品详情接口系列通常用于获取指定商品的详细信息&#xff0c;包括商品属性、价格、主图等。与来赞达Lazada的API类似&#xff0c;具体的返回值可能会根据API的版本和阿里巴巴平台的更新而有所不同。 以下是一个假设的阿里巴巴API商品详情接口的返回值示例…...

lcd画圆

//****************************************************************** //函数名&#xff1a; _draw_circle_8 //功能&#xff1a; 8对称性画圆算法(内部调用) //输入参数&#xff1a;(xc,yc) :圆中心坐标 // (x,y):光标相对于圆心的坐标 // c:填…...

React组件详解

React组件分为两大类 1.函数组件 2.类组件&#xff08;最常用&#xff09; 组件化 import ReactDom from "react-dom";// // 1.通过函数创建一个组件 // 2.函数名字必须大写开头 // 3.函数必须有返回值 function Func1() {return <h2>这是一个基础组件</h…...

C++面试:内存溢出、内存泄漏的原因与解决

目录 内存溢出&#xff08;Memory Overflow&#xff09; 内存溢出介绍 解决内存溢出问题的方法 内存泄漏&#xff08;Memory Leak&#xff09; 内存泄露基础 解决内存泄漏问题的方法 内存溢出&#xff08;Memory Overflow&#xff09; 内存溢出介绍 内存溢出是指程序在执…...

【Java程序员面试专栏 算法思维】二 高频面试算法题:二分查找

一轮的算法训练完成后,对相关的题目有了一个初步理解了,接下来进行专题训练,以下这些题目就是汇总的高频题目,本篇主要聊聊二分查找,包括基础二分,寻找目标值的左右边界,搜索旋转数组以及波峰,以及x的平方根问题,所以放到一篇Blog中集中练习 题目关键字解题思路时间空…...

kaldi 详细安装教程、PyTorch-Kaldi、TIMIT下载、Librispeech下载

kaldi 详细安装教程 本kaldi 安装教程 转载于该链接kaldi 详细安装教程 安装系统依赖&#xff08;如果经常使用linux 服务器&#xff0c;一般都会有&#xff09; apt-get updateapt-get install -y --no-install-recommends g make automake autoconf bzip2 unzip wget sox …...

EtherCAT 转 ModbusTCP 网关

功能概述 本产品是 EtherCAT 和 Modbus TCP 网关&#xff0c;使用数据映射方式工作。 本产品在 EtherCAT 侧作为 EtherCAT 从站&#xff0c;接 TwinCAT 、CodeSYS 、PLC 等&#xff1b;在 ModbusTCP 侧做为 ModbusTCP 主站&#xff08;Client&#xff09;或从站&#xff08;Se…...

iMazing2024Windows和Mac的iOS设备管理软件(可以替代iTunes进行数据备份和管理)

iMazing2024是一款兼容 Windows 和 Mac 的 iOS 设备管理软件&#xff0c;可以替代 iTunes 进行数据备份和管理。以下是一些 iMazing 的主要功能和优点&#xff1a; 数据备份和恢复&#xff1a;iMazing 提供了强大的数据备份和恢复功能&#xff0c;可以备份 iOS 设备上的各种数据…...

carpower

车载android 电源管理 车载音响电源管理器_definitely的技术博客_51CTO博客...

数据结构2月25日

第一道&#xff1a; 第二道&#xff1a; 1、插入到prev和next中间 1.new(struct list_head*)malloc(sizeof(struct list_head*)); if(newNULL) { printf("失败\n"); return; } new->nextprev->next; prev->nextnew; return; 2、删除prve和next…...

改进 RAG:自查询检索

原文地址&#xff1a;Improving RAG: Self Querying Retrieval 2024 年 2 月 11 日 让我们来解决构建 RAG 系统时的一个大问题。 我们不能依赖语义搜索来完成每个检索任务。只有当我们追求单词的含义和意图时&#xff0c;语义搜索才有意义。 But in case&#xff0c;我们正…...

【Git企业实战开发】Git常用开发流操作总结

【Git企业实战开发】Git常用开发流操作总结 大家好 我是寸铁&#x1f44a; 总结了一篇Git常用开发流操作总结的文章✨ 喜欢的小伙伴可以点点关注 &#x1f49d; 现在刚做项目的伙伴&#xff0c;可能你之前学过git&#xff0c;但是一实战发现不熟悉 没关系&#xff0c;看寸铁这篇…...

vue2+element医院安全(不良)事件报告管理系统源代码

目录 安全不良事件类型 源码技术栈 医院安全&#xff08;不良&#xff09;事件报告管理系统采用无责的、自愿的填报不良事件方式&#xff0c;有效地减轻医护人员的思想压力&#xff0c;实现以事件为主要对象&#xff0c;可以自动、及时、实际地反应医院的安全、不良、近失事件…...

leetcode初级算法(python)- 字符串

文章目录 1.反转字符串常规算法pythonic 算法2.整数反转数学法字符串法3.字符串中的第一个唯一字符pythonic算法哈希算法4.有效的字母异位词常规算法进阶算法5.最长公共前缀1.反转字符串 输入:[‘h’,‘e’,‘l’,‘l’,‘o’] 输出:[‘o’,‘l’,‘l’,‘e’,‘h’]...

Python 鼠标模拟

鼠标模拟即&#xff1a;通过python 进行模拟鼠标操作 引入类库 示例如下&#xff1a; import win32api import win32con import time 设置鼠标位置 设置鼠标位置为窗口中的回收站。 示例如下&#xff1a; # 设置鼠标的位置 win32api.SetCursorPos([30, 40]) 双击图标 设置…...

Linux进程 ----- 信号处理

前言 从信号产生到信号保存&#xff0c;中间经历了很多&#xff0c;当操作系统准备对信号进行处理时&#xff0c;还需要判断时机是否 “合适”&#xff0c;在绝大多数情况下&#xff0c;只有在 “合适” 的时机才能处理信号&#xff0c;即调用信号的执行动作。 一、信号的处理…...

【数位】【数论】【分类讨论】2999. 统计强大整数的数目

作者推荐 动态规划的时间复杂度优化 本文涉及知识点 数位 数论 LeetCode2999. 统计强大整数的数目 给你三个整数 start &#xff0c;finish 和 limit 。同时给你一个下标从 0 开始的字符串 s &#xff0c;表示一个 正 整数。 如果一个 正 整数 x 末尾部分是 s &#xff08…...

MongoDB聚合运算符:$atan2

$atan2用来计算反正切&#xff0c;返回指定表达式的反正切值&#xff0c;与$antan的区别主要是参数不同。 语法 { $atan2: [<expression1>, <expression1>] }<expression>为可被解析为数值的表达式$atan2返回弧度&#xff0c;使用$radiansToDegrees运算符可…...

敏捷开发最佳实践:价值维度实践案例之ABTest中台化

22年敏捷白皮书调研发现&#xff0c;仅有14%的企业部分实现价值管理闭环&#xff0c;8%的企业能够做到企业战略和业务目标与价值管理紧密结合。这一现象说明了大部分中国企业还不能在敏捷实践中实现需求价值的体系化及多维度价值度量&#xff0c;因此推广优秀的敏捷实践至关重要…...

爬虫基本库的使用(requests库的详细解析)

注&#xff1a;本文一共4万多字&#xff0c;希望读者能耐心读完&#xff01;&#xff01;&#xff01; 前面,我们了解了urllib库的基本用法&#xff08;爬虫基本库的使用(urllib库的详细解析)-CSDN博客&#xff09;。其中&#xff0c;确实又不方便的地方。例如处理网页验证…...

石家庄有学校交做网站和优化的吗/日本积分榜最新排名

1.Shell是什么&#xff1f; Shell 既是一种脚本编程语言&#xff0c;也是一个连接内核和用户的软件(命令解释器)。 Shell作为命令解释器&#xff0c;它在操作系统的最外层&#xff0c;负责直接与用户对话&#xff0c;把用户的输入解释给操作系统&#xff0c;并处理各种各样的操…...

建设书局 网站/安卓aso

在JavaScript脚本中获取<audio.../>元素对应的对象为HTMLAudioElement对象&#xff0c;<video.../>元素对应的对象为HTMLVideoElement对象。 HTMLAudioElement对象和HTMLVideoElement对象支持的方法有如下几个&#xff1a; play()&#xff1a;播放视频、音频pause(…...

win2003做网站/百度云资源共享

http://dev.gameres.com/Program/Abstract/DeadReckoning.htm  nufoo 小谈网络游戏同步     同步在网络游戏中是非常重要的&#xff0c;它保证了每个玩家在屏幕上看到的东西大体是一样的。其实呢&#xff0c;解决同步问题的最简单的方法就是把每个玩家的动作都向其他…...

柯林建站程序/信息流优化师招聘

蓝鸥iOS讲师推荐&#xff1a;事实上NSNumber的父类是NSValue&#xff0c;在OC中如何理解NSNumber的数字对象&#xff0c;下面就来简单的说一下&#xff01;在日常编程中也许会遇到需要将基本数据类型转换成对象&#xff0c;如&#xff1a;基本类型放入到集合中&#xff08;coco…...

wordpress附件图片/seo点击排名工具

ORACLE使用中的常见、实用的问题摘要&#xff1a;这是原来用ORACLE的过程中记录下的一些问题&#xff0c;现在翻出来看看&#xff0c;还比较实用&#xff0c;如果以后再次遇到这样的问题的时候&#xff0c;就不用东找西找资料了。里面包括字段同步问题&#xff0c;单引号问题&a…...

网站建设asp编程/网络营销师证

代码 --这个按每个小时的. 比如有一个表timeTable,有字段id,score,inputDate. 数据如下 id score inputDate 1 2 2007-4-5 3:33:33 2 1 2007-4-5 4:33:33 3 4 2007-3-5 3:33:33 4 2 2007-4-2 2:33:33 我要按时间分组统计score&#xff0c;结果如下 0:00-1:00 0 1:00-2:00 0 2:0…...