mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 22:02:49 -06:00
187 lines
4.1 KiB
C++
187 lines
4.1 KiB
C++
#include "CtrlLib.h"
|
|
|
|
namespace Upp {
|
|
|
|
#ifdef GUI_WIN
|
|
#ifndef PLATFORM_WINCE
|
|
|
|
#define LLOG(x)
|
|
|
|
static String s_updatedir;
|
|
static String s_updater;
|
|
|
|
void UpdateSetDir(const char *path)
|
|
{
|
|
s_updatedir = path;
|
|
}
|
|
|
|
void UpdateSetUpdater(const char *exename)
|
|
{
|
|
s_updater = exename;
|
|
}
|
|
|
|
String UpdateGetDir()
|
|
{
|
|
return Nvl(s_updatedir, GetIniKey("UPDATE"));
|
|
}
|
|
|
|
Time FileTimeToTime(const FILETIME& time) {
|
|
SYSTEMTIME t;
|
|
FileTimeToSystemTime(&time, &t);
|
|
return Time(t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond);
|
|
}
|
|
|
|
bool NoUpdate(const char *dsf, const char *srf, int& len) {
|
|
FindFile dst(dsf);
|
|
FindFile src(srf);
|
|
if(!src) return true;
|
|
len = (int)src.GetLength();
|
|
if(!dst) return false;
|
|
return abs(FileTimeToTime(dst.GetLastWriteTime()) - FileTimeToTime(src.GetLastWriteTime()))
|
|
< 100 && len == dst.GetLength();
|
|
}
|
|
|
|
void UpdateFile(String dst, String src)
|
|
{
|
|
if(src.IsEmpty()) return;
|
|
String filename = GetFileName(dst);
|
|
int len;
|
|
if(NoUpdate(dst, src, len)) return;
|
|
String tmp = dst + ".tmp";
|
|
Progress pi;
|
|
pi.Title((t_("Updating ") + filename).ToWString());
|
|
pi.SetText(t_("Updating ") + filename);
|
|
// pi.Open();
|
|
FileIn in(src);
|
|
if(!in)
|
|
{
|
|
Exclamation(NFormat(t_("Error opening file [* \1%s\1]."), src));
|
|
return;
|
|
}
|
|
FileDelete(tmp);
|
|
FileOut out(tmp);
|
|
dword n = 0;
|
|
char buffer[2048];
|
|
if(!out)
|
|
{
|
|
Exclamation(NFormat(t_("Error creating file [* \1%s\1]."), tmp));
|
|
return;
|
|
}
|
|
for(;;)
|
|
{
|
|
dword i = in.Get(buffer, 2048);
|
|
if(i == 0) break;
|
|
out.Put(buffer, i);
|
|
n += i;
|
|
pi.Set(n, len);
|
|
if(pi.Canceled() && PromptYesNo(t_("Aborting update is likely to cause trouble when running the application for the next time.\nContinue?")))
|
|
{
|
|
out.Close();
|
|
FileDelete(tmp);
|
|
return;
|
|
}
|
|
}
|
|
out.SetTime(in.GetTime());
|
|
out.Close();
|
|
if(out.IsError())
|
|
{
|
|
Exclamation(NFormat(t_("Error writing file [* \1%s\1]."), tmp));
|
|
FileDelete(tmp);
|
|
return;
|
|
}
|
|
String old = dst + ".old";
|
|
pi.SetText(NFormat(t_("Overwriting %s"), dst));
|
|
pi.SetTotal(10000);
|
|
int start = msecs();
|
|
for(;;)
|
|
{
|
|
SetFileAttributes(dst, 0);
|
|
FileDelete(old);
|
|
FileMove(dst, old);
|
|
if(FileMove(tmp, dst))
|
|
return;
|
|
if(pi.SetPosCanceled(msecs(start) % 10000) && PromptYesNo(t_("Aborting update is likely to cause trouble when running the application for the next time.\nContinue?")))
|
|
return;
|
|
Sleep(500);
|
|
}
|
|
}
|
|
|
|
void UpdateFile(const char *filename)
|
|
{
|
|
String dst = GetExeDirFile(filename);
|
|
String src = UpdateGetDir();
|
|
if(IsNull(src))
|
|
return;
|
|
UpdateFile(dst, AppendFileName(src, filename));
|
|
}
|
|
|
|
static String FixArg(String s)
|
|
{
|
|
if(s.Find(' ') < 0 && s.Find('\"') < 0)
|
|
return s;
|
|
String ucmd;
|
|
ucmd << '\"';
|
|
for(const char *p = s; *p; p++)
|
|
if(*p == '\"')
|
|
ucmd << "\"\"";
|
|
else
|
|
ucmd << *p;
|
|
ucmd << '\"';
|
|
return ucmd;
|
|
}
|
|
|
|
void SelfUpdate() {
|
|
char dst[512];
|
|
UpdateFile(Nvl(s_updater, String("UPDATER.EXE")));
|
|
::GetModuleFileName(NULL, dst, 512);
|
|
{
|
|
String src = UpdateGetDir();
|
|
if(src.IsEmpty()) return;
|
|
src = AppendFileName(src, GetFileNamePos(dst));
|
|
int dummy;
|
|
if(NoUpdate(dst, src, dummy)) return;
|
|
String commandline;
|
|
const Vector<String>& cmd = CommandLine();
|
|
for(int i = 0; i < cmd.GetCount(); i++) {
|
|
commandline += ' ';
|
|
commandline += FixArg(cmd[i]);
|
|
}
|
|
if(WinExec(GetExeDirFile("updater.exe") + " " + GetFileName(dst) + commandline, SW_SHOWNORMAL) <= 31)
|
|
return;
|
|
}
|
|
exit(0);
|
|
}
|
|
|
|
bool SelfUpdateSelf()
|
|
{
|
|
const Vector<String>& cmdline = CommandLine();
|
|
String exe = GetExeFilePath();
|
|
|
|
if(cmdline.GetCount() >= 2 && cmdline[0] == "-update")
|
|
{ // updater
|
|
String exec = FixArg(cmdline[1]);
|
|
UpdateFile(exec, exe);
|
|
for(int i = 2; i < cmdline.GetCount(); i++)
|
|
exec << ' ' << FixArg(cmdline[i]);
|
|
WinExec(exec, SW_SHOWNORMAL);
|
|
return true;
|
|
}
|
|
|
|
String src = UpdateGetDir();
|
|
if(src.IsEmpty()) return false;
|
|
src = AppendFileName(src, GetFileNamePos(exe));
|
|
int dummy;
|
|
if(NoUpdate(exe, src, dummy)) return false;
|
|
|
|
String commandline;
|
|
commandline << src << " -update " << FixArg(exe);
|
|
for(int i = 0; i < cmdline.GetCount(); i++)
|
|
commandline << ' ' << FixArg(cmdline[i]);
|
|
LLOG("SelfUpdateSelf (running updater): " << commandline);
|
|
return WinExec(commandline, SW_SHOWNORMAL) >= 32;
|
|
}
|
|
|
|
#endif
|
|
#endif
|
|
|
|
}
|