Backup

English main discussion
Post Reply
  • Author
  • Message
Offline
Posts: 4
Joined: Wed Oct 21, 2026 8:47 am

Backup

Post 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

DV
Offline
Posts: 1267
Joined: Thu Nov 16, 2006 11:53 am
Location: Kyiv, Ukraine

Re: Backup

Post by DV »

The SaveFile plugin is intended to produce backups.
What exactly does not work for you?

Offline
Posts: 4
Joined: Wed Oct 21, 2026 8:47 am

Re: Backup

Post 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").

DV
Offline
Posts: 1267
Joined: Thu Nov 16, 2006 11:53 am
Location: Kyiv, Ukraine

Re: Backup

Post 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.

Offline
Posts: 4
Joined: Wed Oct 21, 2026 8:47 am

Re: Backup

Post by K652 »

Thanks for advise = just post it there :). And thanks for script - I'll try it.

DV
Offline
Posts: 1267
Joined: Thu Nov 16, 2006 11:53 am
Location: Kyiv, Ukraine

Re: Backup

Post 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.
Post Reply