经常遇到这么一个问题:
调试运行时,程序默认目录为程序主目录。
发布后运行时,因为发布文件在dist目录,所以默认目录在dist目录。
这就导致可能会因为配置文件或其他依赖文件不同,导致调试运行和发布后运行效果不一样。
解决办法:
1、将依赖文件在主目录和dist目录都复制一份,保持相同。
2、将发布后的dist目录中的exe复制到主目录运行。
有时候觉得较麻烦。
干脆升级改造一下publish.aardio,增加以下功能:
1、发布完成后,可以自动复制exe到主目录一份,便于测试。
2、发布完成后,可以自动运行发布的exe或复制的exe(如果选择了复制功能)。
代码仅供有相同需求的朋友参考,不建议直接修改使用。同时,aardio升级会恢复该文件。
import fsys;
import config;
import process;
import ide;
import win.ui;
/*DSG{{*/
var winform = win.form(text="aardio- 已生成EXE文件";right=545;bottom=277;max=false;parent=...)
winform.add(
btnClose={cls="button";text="关闭(ESC)";left=410;top=230;right=512;bottom=260;db=1;dr=1;z=2};
btnEvb={cls="button";text="转换为独立 EXE";left=290;top=230;right=400;bottom=260;db=1;dr=1;z=12};
btnExplorer={cls="button";text="打开发布目录(Enter)";left=30;top=230;right=160;bottom=260;db=1;dr=1;z=1};
btnRun={cls="button";text="运行EXE文件(F5)";left=350;top=190;right=510;bottom=220;db=1;dr=1;z=3};
buttonMakeUpdater={cls="button";text="制作升级包";left=170;top=230;right=280;bottom=260;db=1;dr=1;z=11};
chkBuildNumInc={cls="checkbox";text="版本号自增";left=270;top=110;right=370;bottom=128;ah=1;aw=1;z=8};
chkCopy={cls="checkbox";text="复制文件到工程目录";left=380;top=110;right=530;bottom=128;ah=1;aw=1;z=13};
chkLostFocusClose={cls="checkbox";text="失去焦点自动关闭";left=30;top=110;right=168;bottom=129;ah=1;aw=1;checked=1;z=6};
chkRun={cls="checkbox";text="编译后立即运行";left=30;top=140;right=160;bottom=158;ah=1;aw=1;z=14};
chkUpxCompress={cls="checkbox";text="UPX压缩";left=180;top=110;right=260;bottom=130;ah=1;aw=1;z=7};
editCmdLine={cls="edit";left=100;top=190;right=347;bottom=218;db=1;dl=1;dr=1;edge=1;z=9};
editPublishPath={cls="edit";left=33;top=71;right=513;bottom=100;dl=1;dr=1;edge=1;readonly=1;z=4};
lbCmd={cls="static";text="启动参数:";left=30;top=190;right=100;bottom=216;center=1;db=1;dl=1;font=LOGFONT(h=-14);transparent=1;z=10};
lbTitle={cls="syslink";left=33;top=9;right=519;bottom=65;ah=1;dl=1;dr=1;dt=1;z=5}
)
/*}}*/
winform.lbTitle.text = '<a href="https://api.aardio.com/v10/pages/pub-help">
解除误报教程:基于服务端白名单进行云查杀的安全软件(或某些软件在后台运行的安全模块)会误报未知EXE、
或阻止您的软件启动(可能无任何提示),也有可能您生成EXE时一切正常,但发布给别人使用一段时间后被误报或拦截。</a>'
winform.lbTitle.onHyperlinkClick = function(nmSysLink,url,id){
process.openUrl(url);
}
win.setOwner(winform.hwnd,ide.getMainHwnd()); //避免窗口跑到IDE后面
win.setForeground(winform.hwnd);
/*abortDialog{{*/
abortDialog = function(errCode){
var frmBuildWarning = ..win.form( text="aardio生成EXE失败 错误代码:"+errCode;bottom=169;parent=ide.getMainHwnd();right=496;border="dialog frame";max=false;exmode="toolwindow";mode="popup" )
frmBuildWarning.add(
btnHelp={ bottom=159;text="安全认证教程";left=117;top=124;z=2;right=237;cls="button" };
static={ bottom=127;right=488;left=12;top=23;transparent=1;z=1;text="生成EXE失败,
部分安全软件会阻止生成未知EXE,或对未知EXE错误报警。
请关闭文件监控类软件再试!
EXE文件生成以后,建议及时提交到主流安全厂商云查杀平台通过安全认证,
即可避免发生误报现象。";cls="static" };
btnBuild={ bottom=159;text="重新生成";left=247;top=124;z=3;right=367;cls="button" };
btnExt={ bottom=159;text="退出";left=377;top=124;z=4;right=478;cls="button" }
)
import process;
frmBuildWarning.btnHelp.oncommand = function(id,event){
process.openUrl("https://api.aardio.com/v10/pages/pub-help")
}
import ide;
frmBuildWarning.btnBuild.oncommand = function(id,event){
frmBuildWarning.endModal()
::PostMessage( ide.getMainHwnd(),0x111/*_WM_COMMAND*/, 0x8317/*_IDE_ID_BUILD_PUBLISH*/,0);
}
frmBuildWarning.btnExt.oncommand = function(id,event){
frmBuildWarning.endModal()
}
frmBuildWarning.doModal()
}
/*}}*/
if( ide.projectIsOpened() ){
fsys.delete( ide.getPublishPath() )
}
winform.enableDpiScaling();
winform.chkLostFocusClose.checked = config.publish.chkLostFocusClose;
winform.chkUpxCompress.checked = config.publish.chkUpxCompress;
winform.chkCopy.checked = config.publish.chkCopy;
winform.chkRun.checked = config.publish.chkRun;
winform.chkBuildNumInc.checked = ( config.publish.chkBuildNumInc === null )
? true : config.publish.chkBuildNumInc;
var publishObj = ide.getPublishObjPath();
var objDataFile;
try{
objDataFile = ::Kernel32.LoadLibraryExW(publishObj, ,2/*_LOAD_LIBRARY_AS_DATAFILE*/)
}
catch(e){
abortDialog("30001");
}
if( !objDataFile ){
abortDialog("30002");
return;
}
import fsys.res;
var resLibs = {};
fsys.res.enum(
function(module,resType,resName){
table.push(resLibs,..string.lower(resName) )
return true;
},"LIB",topointer(objDataFile)
)
::Kernel32.FreeLibrary(objDataFile);
/*Manifest{{*/
var projectPath = ide.getProjectPath();
var projectFileName = io.splitpath(projectPath).name;
var manifestPath = ..fsys.joinpath( ide.getProjectDir(),".build\" + projectFileName + ".Manifest.xml" );
var manifestData = ..string.load( manifestPath );
if( !manifestData ){
manifestPath = ..fsys.joinpath( ide.getProjectDir(),".build\Manifest.xml" ); //兼容旧版
manifestData = ..string.load( manifestPath );
}
if( (!manifestData) || ( ! ..string.find(manifestData,"8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a" ) )
|| ( ! ..string.find(manifestData,"@</dpiAwareness>" ) ) ){
import string.template;
manifestTemplate = string.template();
manifestTemplate.template = /***
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly
xmlns="urn:schemas-microsoft-com:asm.v1"
manifestVersion="1.0">
<assemblyIdentity
processorArchitecture="x86"
version="5.1.0.0"
type="win32"
name="${EXENAME}"/>
<description>${PROJENAME}</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
publicKeyToken="6595b64144ccf1df"
language="*"
processorArchitecture="x86"/>
</dependentAssembly>
</dependency>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!--Windows Vista -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
<!--Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!--Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!-- Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!-- Windows 10, Windows 11 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
</application>
</compatibility>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<!--
可任选以下配置之一指定一个进程权限:
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
requireAdministrator 为管理员权限,
highestAvailable 为可以获取到的最高权限,
asInvoker 为默认值,即调用进程当前权限,一般不需要显式指定,指定后会禁用虚拟化。
虚拟化指Vista以后系统禁止写 Program File目录,启用虚拟化则重定向到%localappdata%\VirtualStore目录,
而注册表 HKEY_LOCAL_MACHINE\Software 则重定向到HKEY_CURRENT_USER\Software\Classes\VirtualStore\MACHINE\Software
-->
</requestedPrivileges>
</security>
</trustInfo>
<asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">True/PM</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2, PerMonitor</dpiAwareness>
</asmv3:windowsSettings>
</asmv3:application>
</assembly>
***/
manifestData = manifestTemplate.format(
EXENAME = ide.getPublishName();
PROJENAME = ide.getProjectProperty("name")
);
var manifestPath = ..io.joinpath( ide.getProjectDir(),".build\" + projectFileName + ".Manifest.xml" );
string.save(manifestPath,manifestData ) ;
}
var fileMain = io.open(ide.getProjectMainFile(),"rb");
if( fileMain ){
var tag = fileMain.read(9);
if( tag == "//RUNAS//" ){
manifestData = ..string.replace(manifestData,"\<requestedPrivileges\>.+?\<\/requestedPrivileges\>"
,"<requestedPrivileges><requestedExecutionLevel level=""requireAdministrator"" uiAccess=""false"" /> </requestedPrivileges>")
var manifestPath = ..io.joinpath( ide.getProjectDir(),".build\" + projectFileName + ".Manifest.xml" );
string.save(manifestPath,manifestData ) ;
}
fileMain.close();
}
var resFile = fsys.res.open( publishObj )
resFile.update(24,1,manifestData,0 )
resFile.close();
/*}}*/
var publishFile = ide.getPublishPath();
io.rename(publishObj,publishFile)
if(!io.exist(publishFile)){
abortDialog("30003");
return;
}
var publisDir = ide.getPublisDir();
for(k,resName in resLibs){
var customBuild = fiber.create(
function(resName){
var libPath,libDir = io.libpath(resName);
if(libDir && libPath && ..string.endWith(libPath,"_.aardio",true) ){
var builder = fsys.joinpath(libDir,".build\main.aardio");
if( io.exist( builder ) ){
var tHnd,tId = thread.create(builder)
if(tHnd){
::User32.AttachThreadInput( ..thread.getId(),tId,true);
thread.waitOne(tHnd);
raw.closehandle(tHnd);
}
}
}
}, ide.getProjectDir() /*使用工程目录下的用户库*/
)
fiber.resume (customBuild,resName);
}
var projectPath = ide.getProjectPath();
var projectFileName = io.splitpath(projectPath).name;
var builder = fsys.joinpath(ide.getProjectDir(),".build\" + projectFileName + ".main.aardio");
if( io.exist( builder ) ){
var tHnd,tId = thread.create(builder)
if(tHnd){
::User32.AttachThreadInput( ..thread.getId(),tId,true);
thread.waitOne(tHnd);
raw.closehandle(tHnd);
}
}
else {
var code =/*
//此触发器在生成EXE以后执行
import ide;
import fsys;
//获取生成的EXE文件路径
var publishFile = ide.getPublishPath();
*/
var builder = fsys.joinpath(ide.getProjectDir(),".build\" + projectFileName + ".main.aardio");
..string.save(builder,code)
}
/*自增版本号{{*/
if( winform.chkBuildNumInc.checked ){
import fsys.version;
var fileVersion = ide.getProjectProperty("FileVersion");
if( fileVersion ){
var verInfo = fsys.version(fileVersion);
verInfo.revision++;
if( verInfo.revision >= 1000 ){
verInfo.revision = 0;
verInfo.build++;
}
if( verInfo.build >= 1000 ){
verInfo.build = 0;
verInfo.minor++;
}
if( verInfo.minor >= 100 ){
verInfo.minor = 0;
verInfo.major++;
}
ide.setProjectProperty("FileVersion",tostring(verInfo));
}
var productVersion = ide.getProjectProperty("ProductVersion");
if(productVersion){
var verInfo = fsys.version(productVersion);
verInfo.revision++;
if( verInfo.revision >= 1000 ){
verInfo.revision = 0;
verInfo.build++;
}
if( verInfo.build >= 1000 ){
verInfo.build = 0;
verInfo.minor++;
}
if( verInfo.minor >= 100 ){
verInfo.minor = 0;
verInfo.major++;
}
ide.setProjectProperty("ProductVersion",tostring(verInfo));
}
}
winform.editPublishPath.text = ide.getPublishPath();
winform.show();
/*}}*/
upxCompress = function(){
if( winform.chkUpxCompress.checked ){
winform.text = "aardio- 正在使用UPX压缩EXE文件"
winform.btnRun.disabled = true;
thread.invokeAndWait(
function(publishFile){
import ide.upx;
ide.upx.compress(publishFile);
},ide.getPublishPath()
)
winform.btnRun.disabled = false;
winform.text = "aardio- 已生成EXE文件"
}
}
upxCompress();
winform.chkUpxCompress.oncommand = function(id,event){
upxCompress();
}
winform.btnClose.oncommand = function(id,event){
winform.close()
}
var cmdStorePath = ..fsys.joinpath( ide.getProjectDir(),".build\cmdline.txt" );
winform.editCmdLine.text = string.load(cmdStorePath) : "";
winform.btnRun.oncommand = function(id,event){
winform.btnRun.text = "请稍候..."
winform.btnRun.disabled = true;
process.execute(winform.editPublishPath.text,winform.editCmdLine.text);
if(#winform.editCmdLine.text){
string.save(cmdStorePath,winform.editCmdLine.text)
}
winform.close();
}
winform.btnExplorer.oncommand = function(id,event){
winform.btnExplorer.text = "请稍候..."
winform.btnExplorer.disabled = true;
process.explore_select( winform.editPublishPath.text )
winform.close();
}
winform.wndproc = function(hwnd,message,wParam,lParam){
select( message ) {
case 0x1C/*_WM_ACTIVATEAPP*/ {
if(!wParam){
if( winform.chkLostFocusClose.checked and !hold){
winform.close();
}
}
}
case 0x100/*_WM_KEYDOWN*/{
if( wParam = 0x74/*_VK_F5*/ ){
winform.btnRun.oncommand();
}
}
}
}
winform.onClose = function(hwnd,message,wParam,lParam){
config.publish.chkLostFocusClose = winform.chkLostFocusClose.checked
config.publish.chkUpxCompress = winform.chkUpxCompress.checked;
config.publish.chkCopy = winform.chkCopy.checked;
config.publish.chkRun = winform.chkRun.checked;
config.publish.chkBuildNumInc = winform.chkBuildNumInc.checked;
}
winform.buttonMakeUpdater.oncommand = function(id,event){
winform.close()
loadcodex("~\tools\3) 编码\1) maker.aardio")
}
winform.btnEvb.oncommand = function(id,event){
winform.close();
loadcodex("~\tools\1) 开发环境\evb.aardio")
}
winform.chkCopy.oncommand = function(id,event){
if winform.chkCopy.checked {
fsys.copy(publishFile, io.splitpath(projectPath).dir+ io.splitpath(publishFile).file)
}
}
win.setActive(winform.hwnd);
if winform.chkCopy.checked {
var dstfile = io.splitpath(projectPath).dir+ io.splitpath(publishFile).file;
fsys.copy(publishFile, dstfile);
if winform.chkRun.checked {
hold = true;
process.executeWait(dstfile,winform.editCmdLine.text);
winform.close();
}
} else {
if winform.chkRun.checked {
hold = true;
process.executeWait(winform.editPublishPath.text,winform.editCmdLine.text);
winform.close();
}
}
win.loopMessage();