我承认在这个问题上我是在耍花招。
问题:exe部署在共享文件夹上(从现在起我称之为ShaExe),没有更改部署规则,我想在本地缓存文件(从现在起我称之为LocExe),在启动ShaExe时,我最终运行LocExe。每次修改ShaExe(=更新)都必须更新LocExe(从ShaExe复制)。
不知何故,我研究的是建立这样的东西:
-
启动ShaExe
-
ShaExe将其大小与LocExe的大小进行比较,如果不同,则将ShaExe复制到LocExe上
-
ShaExe使用
-skiplauncher
-
ShaExe自动终止
什么时候
-滑雪者
现在这种方法可行,但瓶颈是(1),因为ShaExe的大小是110MB,所以从共享路径启动exe需要时间(即使我不使用这个标志)
{$SetPEFlags IMAGE_FILE_NET_RUN_FROM_SWAP}
).
我希望(2)(3)和(4)立即执行,这是否可能与Windows?
我非常清楚,最好的做法是手动复制本地文件并运行它,或者创建一个简单的启动程序exe,在必要时运行LocExe进行缓存,但我有一个非常大的客户要求我这样做,而不改变部署过程。
这就是我在这里征求专家意见的原因。
这是我的代码(当然是简化的,而不是Unit1想象100个单元):
//this is the dpr
program MYProgram;
uses
Vcl.Forms,
execache in 'execache.pas',
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
begin
RunCachedExe;
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
//this is the execache unit
unit execache;
interface
uses
Vcl.Forms,
Windows,
ShellAPi,
sysutils,
dialogs,
system.IOUtils;
procedure RunCachedExe;
implementation
procedure RunCachedExe;
function GetFileSize(const aFilename: String): Int64;
var
info: TWin32FileAttributeData;
begin
result := -1;
if NOT GetFileAttributesEx(PWideChar(aFileName), GetFileExInfoStandard, @info) then
EXIT;
result := Int64(info.nFileSizeLow) or Int64(info.nFileSizeHigh shl 32);
end;
var
CurrentInstanceSize, CachedFileSize, i: integer;
CachedFilePath, Outs: string;
SkipLauncher: Boolean;
begin
SkipLauncher := False;
for i := 0 to paramcount -1 do
begin
if Paramstr(i) = '-SkipLauncher' then
SkipLauncher := True;
end;
if not SkipLauncher then
begin
// in this code path is hardcoded, in real life I use a function that calls:
// SHGetSpecialFolderPath with CSIDL_LOCAL_APPDATA
CachedFilePath := 'C:\Users\myuser\AppData\Local\MyProject\bincache\MyProject.exe';
CurrentInstanceSize := GetFileSize(Application.ExeName);
// this will return -1 if file not found
CachedFileSize := GetFileSize (CachedFilePath);
if CachedFileSize <> CurrentInstanceSize then
begin
ForceDirectories('C:\Users\myuser\AppData\Local\MyProject\bincache\');
CopyFile(PChar(Application.ExeName), PCHar(CachedFilePath), False);
end;
// launch local exe and close this one
ShellExecute (0, 'open', PWideChar( CachedFilePath ), PWideChar('-SkipLauncher'), nil, SW_SHOWNORMAL);
Application.Terminate;
end;
end;
这段代码使用了其他单元的一些函数,但是如果这有助于加快exe的执行速度,我可以将所有函数都移动到execache单元中。
不知何故,我只想运行一个初始化部分,包含这里描述的逻辑,然后终止应用程序(当ShaExe就位时,基本上意味着
-skipLauncher
那么,有没有可能只运行一个大exe文件的初始化逻辑?
我希望我表达了我自己,谢谢。