Page 1 of 1

Backup

Posted: Wed Oct 21, 2026 8:55 am
by K652
I just started to use this very good program, but I am unable to setup one feature, which is in almost any program - trivial backup ( filename.bak in the same dir as original file) when Save. Tried to set it up in SaveFile, but failed. Is there any sim ple way how to handle this? TIA, Milan

Re: Backup

Posted: Fri Oct 23, 2026 10:28 pm
by DV
The SaveFile plugin is intended to produce backups.
What exactly does not work for you?

Re: Backup

Posted: Sat Oct 24, 2026 12:06 pm
by K652
I know this plugin, but, as I understand, it works continuosly and saving intermediate states..., but I need to be able to return to the state _before_ I started all editing in current session after open it and started editing (as it is done for example in Notepad++ with option "Backup on save = Simple backup").

Re: Backup

Posted: Sat Oct 24, 2026 2:14 pm
by DV
This seems to do the job.
But you need to explicitly run this script. For example, by means of the CmdLineEnd manual setting. (Refer to AkelHelp-Eng.htm and to Scripts-Eng.txt for details).

Code: Select all

var hWndMain = AkelPad.GetMainWnd();
var oSys = AkelPad.SystemFunction();

var AKD_JS_SCRIPT_STOP   = 0x7CDF; // unique message (must not be equal to any existing AKD_* message)
var UNIQUE_SCRIPT_ID     = 0x1A2BC83F; // unique wParam id to identify _this_ script file

AkelPad.ScriptNoMutex();

var mutexName = "BackupOnSave_js_" + hWndMain;
var hMutex;
if (hMutex = oSys.Call("kernel32::CreateMutex" + _TCHAR, 0, 1, mutexName))
{
  if (oSys.GetLastError() == 183 /*ERROR_ALREADY_EXISTS*/)
  {
    oSys.Call("kernel32::CloseHandle", hMutex); // closes the just opened mutex
    oSys.Call("user32::PostMessage" + _TCHAR, hWndMain, AKD_JS_SCRIPT_STOP, UNIQUE_SCRIPT_ID, 0);
    WScript.Quit();
  }
}

var hMainSubClass;
if (hMainSubClass = AkelPad.WindowSubClass(1 /*WSC_MAINPROC*/, MainCallback))
{
  AkelPad.WindowGetMessage(); //Message loop

  AkelPad.WindowUnsubClass(1 /*WSC_MAINPROC*/);
}

function MainCallback(hWnd, uMsg, wParam, lParam)
{
  if (uMsg == 0x437 /*AKDN_SAVEDOCUMENT_START*/)
  {
    // a document is about to be saved
    var ptr = AkelPad.MemRead(lParam, 2 /*DT_QWORD*/); // NSAVEDOCUMENT.pFile
    var filePath = AkelPad.MemRead(ptr, _TSTR);
    var bakfilePath = filePath + ".bak";
    if (!oSys.Call("kernel32::CopyFile" + _TCHAR, filePath, bakfilePath, 0))
    {
      WScript.Echo("CopyFile failed with an error=" + oSys.GetLastError());
    }
  }
  else if ((uMsg == 0x406 /*AKDN_MAIN_ONFINISH*/)
        || (uMsg == AKD_JS_SCRIPT_STOP && wParam == UNIQUE_SCRIPT_ID))
  {
    oSys.Call("kernel32::CloseHandle", hMutex); // closes the previously created mutex
    oSys.Call("user32::PostQuitMessage", 0); // exit the message loop
  }

  return 0;
}


Though the best way is to ask Instructor to update the SaveFile plugin with an option to produce a backup file on each manual save rather than an auto-save.

Re: Backup

Posted: Sat Oct 24, 2026 2:43 pm
by K652
Thanks for advise = just post it there :). And thanks for script - I'll try it.

Re: Backup

Posted: Wed Oct 28, 2026 5:06 pm
by DV
The latest version of the script is here:
https://github.com/d0vgan/AkelPad-Scrip ... pOnSave.js

It will not be needed when the SaveFile plugin is (hopefully) updated, but still this script will be useful as a reference or an example of a resident script that runs in background.