ultimatepp/uppsrc/CtrlLib/Update.cpp
cxl b7def4e671 Core: GetIniKey fix
git-svn-id: svn://ultimatepp.org/upp/trunk@1724 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2009-11-26 16:43:08 +00:00

167 lines
3.8 KiB
C++

#include "CtrlLib.h"
NAMESPACE_UPP
#ifdef PLATFORM_WIN32
#ifndef PLATFORM_WINCE
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 = GetIniKey("UPDATE");
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("UPDATER.EXE");
::GetModuleFileName(NULL, dst, 512);
{
String src = GetIniKey("UPDATE");
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 = GetIniKey("UPDATE");
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]);
RLOG("SelfUpdateSelf (running updater): " << commandline);
return WinExec(commandline, SW_SHOWNORMAL) >= 32;
}
#endif
#endif
END_UPP_NAMESPACE