之前找到一个修改 exe 中 DLL地址 的方法, 不太好使,
虽然能正确启动, 但无法改变 exe 的工作目录,
这就影响了.Net 中很多获取 exe 执行目录来拼接的地址 ( 相对路径 ),
比如 wwwroot 和 代码中相对目录
还有一些复制到目录的普通文件 等等,
它们的地址都会指向原来 exe 的目录, 而不是自定义的 “lib” 目录,
根本原因就是没有修改 exe 的工作目录
这次来搞一个启动程序,
把 .net 的所有东西都放在一个文件夹,
在文件夹同级的目录制作一个 exe.
用来启动文件夹中的 .net 程序, 并把工作目录设置为 lib,
这样就完美解决了上面的bug
例子中新建了名称为 “BlazorApp” 的 Blazor 项目.
发布后复制 publish 文件夹到 “demo” 文件夹 ,
publish 改为 “lib”
先说一个简单的方法, 就是新建一个 bat 文件
@echo off
cd ./lib
BlazorApp.exe
exit
先进入到 lib 目录, 再启动 exe.
最终效果, 就两个, 非常的干净, 双击 Run.bat 就可以成功启动 .Net 程序了
bat 文件不是 exe . 可能有些人接受不了… 所以请看下面 C 语言制作 exe
测试环境:
.Net 8
gcc (c/c++的编译器) 版本: x86_64-8.1.0-release-win32-sjlj-rt_v6-rev0
一句话概括:
下载个编译器, 啥也不用做. 新建一个 c 文件, 记事本打开, 把名称改成自己的.
一条命令直接编译, 就完成了.
https://sourceforge.net/projects/mingw-w64/files/
下载 x86_64-win32-sjlj
下载后 是一个 压缩包, 放在自己喜欢的地方解压出来
一句话概括,就是用 c 通过代码执行命令, 打开 .Net exe
#include
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
LPCWSTR dirPath = L"lib";
LPCWSTR exeName = L"BlazorApp.exe";
ShellExecuteW(NULL, L"open", exeName, NULL, dirPath, SW_SHOW);
return 0;
}
WinMain 是 桌面程序的入口. (控制台入口是 main)
“BlazorApp.exe” 是 .Net 程序的文件名,
“lib” 是文件夹的名称, 也就是工作目录, 影响到 .Net 程序相关文件的加载
D:\Software\x86_64-8.1.0-release-win32-sjlj-rt_v6-rev0\mingw64\bin\gcc.exe -m32 -mwindows -o a.exe a.c
前半段是 gcc 的 exe 地址 (咱也不常用, 就不加入到 path 环境变量了)
-m32 指定为 32位程序 ( 兼容性强 )
-mwindows 指定为 windows gui 程序 ( main 函数需要改为 WinMain )
(默认是 控制台程序, 如果代码中没有停顿, 控制台会一闪而过.体验很差, gui程序可以完美解决这个问题)
-o 是输出的地址和文件名
a.c 是 C语言源代码, 文件名叫做 a (随便取的)
执行命令后就可以看到 a.exe 文件, 只有 44 kb !!!
把 exe 复制到 lib 目录旁边, 改个名字…
我这里 .Net 叫做 BlazorApp. 所以把 c 的 exe 也改成这个. 以假乱真
.Net 的 Content root path 也变成了 期望的值,
程序中各种静态文件加载也都正确了.
装一个 微软官方 Windows XP, 啥也不做. 直接把程序搞上去,
44kb 也可以直接在 XP 上运行
由于.net8 不能在 xp 上运行, 为了测试 搞了个 C 语言的 b.exe , 输出一下 工作目录
#include
#include
#include
#define MAXPATH 1024
int main()
{
char buffer[MAXPATH];
_getcwd(buffer, MAXPATH);
printf("work path: %s \n hello b.exe", buffer);
sleep(10);
return 0;
}
编译成控制台项目, 这个就不用 -mwindows 了
gcc -m32 -o b.exe b.c