Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Welcome to the new platform of Programmer's Heaven! We apologize for the inconvenience caused, if you visited us from a broken link of the previous version. The main reason to move to a new platform is to provide more effective and collaborative experience to you all. Please feel free to experience the new platform and use its exciting features. Contact us for any issue that you need to get clarified. We are more than happy to help you.

Auto-updating a program

jammojammo Posts: 12Member
Hi there,

I was trying to think about how this is done, but cannot really get my head round it - wondering if anyone could share a minute.

I have a LAN Chat program for use with housemates on a LAN, and they then have it installed on their machine (a simple copy of the exe suffices). Now, when I make updates to this exe, is there a way I can make other copies of my program automatically update?

I can set registry settings and check that "my copy of chat program version number = master copy of chat program's version number", but then how would i go about editing the code within the exe?

My other train of thought was about perhaps the main exe is a simple script loader, where it simply reads from pre-compiled scripts (DLLs?) and all it does is copy latest versions of these. Therefore no need of copying the main exe is required.

Can anyone confirm this for me please? How would I go about transfering a module (or PAS) into a DLL file if that is the method I am to take?

Thanks in advance
- James

Comments

  • zibadianzibadian Posts: 6,349Member
    : Hi there,
    :
    : I was trying to think about how this is done, but cannot really get my head round it - wondering if anyone could share a minute.
    :
    : I have a LAN Chat program for use with housemates on a LAN, and they then have it installed on their machine (a simple copy of the exe suffices). Now, when I make updates to this exe, is there a way I can make other copies of my program automatically update?
    :
    : I can set registry settings and check that "my copy of chat program version number = master copy of chat program's version number", but then how would i go about editing the code within the exe?
    :
    : My other train of thought was about perhaps the main exe is a simple script loader, where it simply reads from pre-compiled scripts (DLLs?) and all it does is copy latest versions of these. Therefore no need of copying the main exe is required.
    :
    : Can anyone confirm this for me please? How would I go about transfering a module (or PAS) into a DLL file if that is the method I am to take?
    :
    : Thanks in advance
    : - James
    :
    There are two simple ways of performing this kind of things:
    - a DLL module
    - an external update program

    The latter is quite simple to implement. Just write a small program, which downloads the new version and writes it over the old version. Since this is a completely independant processs, you don't have to worry about updating it. The trick lies in the call. If your chat-program detects a new version, it calls the updater (see ShellExecute() and older posts for examples) and terminates itself. This way the chat-program can be overwritten. After the update is completed, the update program restarts the chat program.

    The former means that you need to recompile your program into a DLL. Luckily this isn't as hard as it sounds. All programs have a .dpr file, which looks something like ths:
    [code]
    program DD3Valid;

    uses
    Forms,
    mainwin in 'mainwin.pas' {Form1};

    {$R *.RES}

    begin
    Application.Initialize;
    Application.CreateForm(TForm1, Form1);
    Application.Run;
    end.
    [/code]
    All you need to do is to change that into this:
    [code]
    library DD3Valid;

    uses
    Forms,
    Windows,
    mainwin in 'mainwin.pas' {Form1};

    {$R *.RES}

    procedure RunChatProgram(AppHandle: THandle); StdCall;
    begin
    Application.Handle := AppHandle;
    Form1 := TForm1.Create(Application);
    Form1.ShowModal;
    end;

    exports
    RunChatProgram;

    begin
    end.
    [/code]
    This will automatically compile it as a library. Now you need to write a program, which calls the RunProgram() procedure. Here is a sample code:
    [code]
    type
    TRunChatProgram = procedure(AppHandle: THandle); StdCall;

    var
    DLLHandle: THandle;
    ProcPointer: pointer;
    begin
    ...
    DLLHandle := LoadLibrary('ChatDLL.DLL'); // Load the DLL
    if DLLHandle > HINSTANCE_ERROR then
    begin
    ProcPointer := GetProcAddress(DLLHandle, 'RunChatProgram');
    // Obtain the correct procedure pointer
    if ProcPointer <> nil then
    TRunChatProgram(ProcPointer)(Application.Handle)
    // Run the procedure = run the program
    else
    ShowMessage('Cannot run code (possibly wrong library)');
    FreeHandle(DLLHandle); // Unload the DLL
    end else
    ShowMessage('Cannot load DLL');
    ...
    end.
    [/code]
    This process will run the chat-window as a dialog. This code is error-trapping, so if the chat doesn't load the user will see a message box.

    I hope this helps you to decide which way you wish to go.
  • MasterijnMasterijn Posts: 188Member
    : Hi there,
    :
    : I was trying to think about how this is done, but cannot really get my head round it - wondering if anyone could share a minute.
    :
    : I have a LAN Chat program for use with housemates on a LAN, and they then have it installed on their machine (a simple copy of the exe suffices). Now, when I make updates to this exe, is there a way I can make other copies of my program automatically update?
    :
    : I can set registry settings and check that "my copy of chat program version number = master copy of chat program's version number", but then how would i go about editing the code within the exe?
    :
    : My other train of thought was about perhaps the main exe is a simple script loader, where it simply reads from pre-compiled scripts (DLLs?) and all it does is copy latest versions of these. Therefore no need of copying the main exe is required.
    :
    : Can anyone confirm this for me please? How would I go about transfering a module (or PAS) into a DLL file if that is the method I am to take?
    :
    : Thanks in advance
    : - James
    :
    A process can rename its executable, after this you can download a new one. Launch the new one and then quit the old. I'd use these routines for getting the application version:
    [code]
    unit Unit2;

    interface
    type
    TVersionRec = record
    Version : Byte;
    MinorVersion : Byte;
    Release : Byte;
    Build : Byte;
    end;

    function GetVersionInfoRec: TVersionRec;
    function GetFileVersionInfoRec(const AFilename: string): TVersionRec;

    implementation
    uses
    Windows, SysUtils;
    type
    TVER = packed record
    Filler : array[1..6 + 16*2] of Byte;
    BoundAdd : Word;
    PV: VS_FIXEDFILEINFO;
    end;

    function GetVersionInfoRec: TVersionRec;
    var
    HRes: DWord;
    HGlob : DWord;
    V : ^VS_FIXEDFILEINFO;
    Ver : ^TVER;
    begin
    with Result do
    begin
    Version := 0;
    MinorVersion := 0;
    Release := 0;
    Build := 0;
    end;
    HRes := FindResource(HInstance, '#1', RT_VERSION);
    if HRes = 0 then
    Exit;
    HGlob := LoadResource(HInstance, HRes);
    if HGlob = 0 then
    Exit;
    Ver := LockResource(HGlob);
    if not Assigned(Ver) then
    Exit;
    V := Pointer(Integer(@Ver^.BoundAdd) + Ver^.BoundAdd + 2);
    with V^, Result do
    begin
    Version := dwFileVersionMS shr 16;
    MinorVersion := dwFileVersionMS and $FF;
    Release := dwFileVersionLS shr 16;
    Build := dwFileVersionLS and $FF;
    end;
    end;

    function GetFileVersionInfoRec(const AFilename: string): TVersionRec;
    var
    FileName: string;
    InfoSize, Wnd: DWORD;
    VerBuf: Pointer;
    FI: PVSFixedFileInfo;
    VerSize: DWORD;
    begin
    with Result do
    begin
    Version := 0;
    MinorVersion := 0;
    Release := 0;
    Build := 0;
    end;
    // GetFileVersionInfo modifies the filename parameter data while parsing.
    // Copy the string const into a local variable to create a writeable copy.
    FileName := AFileName;
    UniqueString(FileName);
    InfoSize := GetFileVersionInfoSize(PChar(FileName), Wnd);
    if InfoSize <> 0 then
    begin
    GetMem(VerBuf, InfoSize);
    try
    if GetFileVersionInfo(PChar(FileName), Wnd, InfoSize, VerBuf) then
    if VerQueryValue(VerBuf, '', Pointer(FI), VerSize) then
    with FI^, Result do
    begin
    Version := dwFileVersionMS shr 16;
    MinorVersion := dwFileVersionMS and $FF;
    Release := dwFileVersionLS shr 16;
    Build := dwFileVersionLS and $FF;
    end;
    finally
    FreeMem(VerBuf);
    end;
    end;
    end;
    end.
    [code]


  • zibadianzibadian Posts: 6,349Member
    : : Hi there,
    : :
    : : I was trying to think about how this is done, but cannot really get my head round it - wondering if anyone could share a minute.
    : :
    : : I have a LAN Chat program for use with housemates on a LAN, and they then have it installed on their machine (a simple copy of the exe suffices). Now, when I make updates to this exe, is there a way I can make other copies of my program automatically update?
    : :
    : : I can set registry settings and check that "my copy of chat program version number = master copy of chat program's version number", but then how would i go about editing the code within the exe?
    : :
    : : My other train of thought was about perhaps the main exe is a simple script loader, where it simply reads from pre-compiled scripts (DLLs?) and all it does is copy latest versions of these. Therefore no need of copying the main exe is required.
    : :
    : : Can anyone confirm this for me please? How would I go about transfering a module (or PAS) into a DLL file if that is the method I am to take?
    : :
    : : Thanks in advance
    : : - James
    : :
    : A process can rename its executable, after this you can download a new one. Launch the new one and then quit the old. I'd use these routines for getting the application version:
    : [code]
    : unit Unit2;
    :
    : interface
    : type
    : TVersionRec = record
    : Version : Byte;
    : MinorVersion : Byte;
    : Release : Byte;
    : Build : Byte;
    : end;
    :
    : function GetVersionInfoRec: TVersionRec;
    : function GetFileVersionInfoRec(const AFilename: string): TVersionRec;
    :
    : implementation
    : uses
    : Windows, SysUtils;
    : type
    : TVER = packed record
    : Filler : array[1..6 + 16*2] of Byte;
    : BoundAdd : Word;
    : PV: VS_FIXEDFILEINFO;
    : end;
    :
    : function GetVersionInfoRec: TVersionRec;
    : var
    : HRes: DWord;
    : HGlob : DWord;
    : V : ^VS_FIXEDFILEINFO;
    : Ver : ^TVER;
    : begin
    : with Result do
    : begin
    : Version := 0;
    : MinorVersion := 0;
    : Release := 0;
    : Build := 0;
    : end;
    : HRes := FindResource(HInstance, '#1', RT_VERSION);
    : if HRes = 0 then
    : Exit;
    : HGlob := LoadResource(HInstance, HRes);
    : if HGlob = 0 then
    : Exit;
    : Ver := LockResource(HGlob);
    : if not Assigned(Ver) then
    : Exit;
    : V := Pointer(Integer(@Ver^.BoundAdd) + Ver^.BoundAdd + 2);
    : with V^, Result do
    : begin
    : Version := dwFileVersionMS shr 16;
    : MinorVersion := dwFileVersionMS and $FF;
    : Release := dwFileVersionLS shr 16;
    : Build := dwFileVersionLS and $FF;
    : end;
    : end;
    :
    : function GetFileVersionInfoRec(const AFilename: string): TVersionRec;
    : var
    : FileName: string;
    : InfoSize, Wnd: DWORD;
    : VerBuf: Pointer;
    : FI: PVSFixedFileInfo;
    : VerSize: DWORD;
    : begin
    : with Result do
    : begin
    : Version := 0;
    : MinorVersion := 0;
    : Release := 0;
    : Build := 0;
    : end;
    : // GetFileVersionInfo modifies the filename parameter data while parsing.
    : // Copy the string const into a local variable to create a writeable copy.
    : FileName := AFileName;
    : UniqueString(FileName);
    : InfoSize := GetFileVersionInfoSize(PChar(FileName), Wnd);
    : if InfoSize <> 0 then
    : begin
    : GetMem(VerBuf, InfoSize);
    : try
    : if GetFileVersionInfo(PChar(FileName), Wnd, InfoSize, VerBuf) then
    : if VerQueryValue(VerBuf, '', Pointer(FI), VerSize) then
    : with FI^, Result do
    : begin
    : Version := dwFileVersionMS shr 16;
    : MinorVersion := dwFileVersionMS and $FF;
    : Release := dwFileVersionLS shr 16;
    : Build := dwFileVersionLS and $FF;
    : end;
    : finally
    : FreeMem(VerBuf);
    : end;
    : end;
    : end;
    : end.
    : [/code]
    :
    :
    :
    I think, it is not possible to rename an active executable, because that file is locked for writing. This locking mechanism is the whole problem of updating an running executable from within itself.
  • MasterijnMasterijn Posts: 188Member
    : : : Hi there,
    : : :
    : : : I was trying to think about how this is done, but cannot really get my head round it - wondering if anyone could share a minute.
    : : :
    : : : I have a LAN Chat program for use with housemates on a LAN, and they then have it installed on their machine (a simple copy of the exe suffices). Now, when I make updates to this exe, is there a way I can make other copies of my program automatically update?
    : : :
    : : : I can set registry settings and check that "my copy of chat program version number = master copy of chat program's version number", but then how would i go about editing the code within the exe?
    : : :
    : : : My other train of thought was about perhaps the main exe is a simple script loader, where it simply reads from pre-compiled scripts (DLLs?) and all it does is copy latest versions of these. Therefore no need of copying the main exe is required.
    : : :
    : : : Can anyone confirm this for me please? How would I go about transfering a module (or PAS) into a DLL file if that is the method I am to take?
    : : :
    : : : Thanks in advance
    : : : - James
    : : :
    : : A process can rename its executable, after this you can download a new one. Launch the new one and then quit the old. I'd use these routines for getting the application version:
    : : [code]
    : : unit Unit2;
    : :
    : : interface
    : : type
    : : TVersionRec = record
    : : Version : Byte;
    : : MinorVersion : Byte;
    : : Release : Byte;
    : : Build : Byte;
    : : end;
    : :
    : : function GetVersionInfoRec: TVersionRec;
    : : function GetFileVersionInfoRec(const AFilename: string): TVersionRec;
    : :
    : : implementation
    : : uses
    : : Windows, SysUtils;
    : : type
    : : TVER = packed record
    : : Filler : array[1..6 + 16*2] of Byte;
    : : BoundAdd : Word;
    : : PV: VS_FIXEDFILEINFO;
    : : end;
    : :
    : : function GetVersionInfoRec: TVersionRec;
    : : var
    : : HRes: DWord;
    : : HGlob : DWord;
    : : V : ^VS_FIXEDFILEINFO;
    : : Ver : ^TVER;
    : : begin
    : : with Result do
    : : begin
    : : Version := 0;
    : : MinorVersion := 0;
    : : Release := 0;
    : : Build := 0;
    : : end;
    : : HRes := FindResource(HInstance, '#1', RT_VERSION);
    : : if HRes = 0 then
    : : Exit;
    : : HGlob := LoadResource(HInstance, HRes);
    : : if HGlob = 0 then
    : : Exit;
    : : Ver := LockResource(HGlob);
    : : if not Assigned(Ver) then
    : : Exit;
    : : V := Pointer(Integer(@Ver^.BoundAdd) + Ver^.BoundAdd + 2);
    : : with V^, Result do
    : : begin
    : : Version := dwFileVersionMS shr 16;
    : : MinorVersion := dwFileVersionMS and $FF;
    : : Release := dwFileVersionLS shr 16;
    : : Build := dwFileVersionLS and $FF;
    : : end;
    : : end;
    : :
    : : function GetFileVersionInfoRec(const AFilename: string): TVersionRec;
    : : var
    : : FileName: string;
    : : InfoSize, Wnd: DWORD;
    : : VerBuf: Pointer;
    : : FI: PVSFixedFileInfo;
    : : VerSize: DWORD;
    : : begin
    : : with Result do
    : : begin
    : : Version := 0;
    : : MinorVersion := 0;
    : : Release := 0;
    : : Build := 0;
    : : end;
    : : // GetFileVersionInfo modifies the filename parameter data while parsing.
    : : // Copy the string const into a local variable to create a writeable copy.
    : : FileName := AFileName;
    : : UniqueString(FileName);
    : : InfoSize := GetFileVersionInfoSize(PChar(FileName), Wnd);
    : : if InfoSize <> 0 then
    : : begin
    : : GetMem(VerBuf, InfoSize);
    : : try
    : : if GetFileVersionInfo(PChar(FileName), Wnd, InfoSize, VerBuf) then
    : : if VerQueryValue(VerBuf, '', Pointer(FI), VerSize) then
    : : with FI^, Result do
    : : begin
    : : Version := dwFileVersionMS shr 16;
    : : MinorVersion := dwFileVersionMS and $FF;
    : : Release := dwFileVersionLS shr 16;
    : : Build := dwFileVersionLS and $FF;
    : : end;
    : : finally
    : : FreeMem(VerBuf);
    : : end;
    : : end;
    : : end;
    : : end.
    : : [/code]
    : :
    : :
    : :
    : I think, it is not possible to rename an active executable, because that file is locked for writing. This locking mechanism is the whole problem of updating an running executable from within itself.
    :
    Renaming does not interfere with locking (as I expected also). This is probably because it doesn't change the content of a file.


  • zibadianzibadian Posts: 6,349Member
    : : : : Hi there,
    : : : :
    : : : : I was trying to think about how this is done, but cannot really get my head round it - wondering if anyone could share a minute.
    : : : :
    : : : : I have a LAN Chat program for use with housemates on a LAN, and they then have it installed on their machine (a simple copy of the exe suffices). Now, when I make updates to this exe, is there a way I can make other copies of my program automatically update?
    : : : :
    : : : : I can set registry settings and check that "my copy of chat program version number = master copy of chat program's version number", but then how would i go about editing the code within the exe?
    : : : :
    : : : : My other train of thought was about perhaps the main exe is a simple script loader, where it simply reads from pre-compiled scripts (DLLs?) and all it does is copy latest versions of these. Therefore no need of copying the main exe is required.
    : : : :
    : : : : Can anyone confirm this for me please? How would I go about transfering a module (or PAS) into a DLL file if that is the method I am to take?
    : : : :
    : : : : Thanks in advance
    : : : : - James
    : : : :
    : : : A process can rename its executable, after this you can download a new one. Launch the new one and then quit the old. I'd use these routines for getting the application version:
    : : : [code]
    : : : unit Unit2;
    : : :
    : : : interface
    : : : type
    : : : TVersionRec = record
    : : : Version : Byte;
    : : : MinorVersion : Byte;
    : : : Release : Byte;
    : : : Build : Byte;
    : : : end;
    : : :
    : : : function GetVersionInfoRec: TVersionRec;
    : : : function GetFileVersionInfoRec(const AFilename: string): TVersionRec;
    : : :
    : : : implementation
    : : : uses
    : : : Windows, SysUtils;
    : : : type
    : : : TVER = packed record
    : : : Filler : array[1..6 + 16*2] of Byte;
    : : : BoundAdd : Word;
    : : : PV: VS_FIXEDFILEINFO;
    : : : end;
    : : :
    : : : function GetVersionInfoRec: TVersionRec;
    : : : var
    : : : HRes: DWord;
    : : : HGlob : DWord;
    : : : V : ^VS_FIXEDFILEINFO;
    : : : Ver : ^TVER;
    : : : begin
    : : : with Result do
    : : : begin
    : : : Version := 0;
    : : : MinorVersion := 0;
    : : : Release := 0;
    : : : Build := 0;
    : : : end;
    : : : HRes := FindResource(HInstance, '#1', RT_VERSION);
    : : : if HRes = 0 then
    : : : Exit;
    : : : HGlob := LoadResource(HInstance, HRes);
    : : : if HGlob = 0 then
    : : : Exit;
    : : : Ver := LockResource(HGlob);
    : : : if not Assigned(Ver) then
    : : : Exit;
    : : : V := Pointer(Integer(@Ver^.BoundAdd) + Ver^.BoundAdd + 2);
    : : : with V^, Result do
    : : : begin
    : : : Version := dwFileVersionMS shr 16;
    : : : MinorVersion := dwFileVersionMS and $FF;
    : : : Release := dwFileVersionLS shr 16;
    : : : Build := dwFileVersionLS and $FF;
    : : : end;
    : : : end;
    : : :
    : : : function GetFileVersionInfoRec(const AFilename: string): TVersionRec;
    : : : var
    : : : FileName: string;
    : : : InfoSize, Wnd: DWORD;
    : : : VerBuf: Pointer;
    : : : FI: PVSFixedFileInfo;
    : : : VerSize: DWORD;
    : : : begin
    : : : with Result do
    : : : begin
    : : : Version := 0;
    : : : MinorVersion := 0;
    : : : Release := 0;
    : : : Build := 0;
    : : : end;
    : : : // GetFileVersionInfo modifies the filename parameter data while parsing.
    : : : // Copy the string const into a local variable to create a writeable copy.
    : : : FileName := AFileName;
    : : : UniqueString(FileName);
    : : : InfoSize := GetFileVersionInfoSize(PChar(FileName), Wnd);
    : : : if InfoSize <> 0 then
    : : : begin
    : : : GetMem(VerBuf, InfoSize);
    : : : try
    : : : if GetFileVersionInfo(PChar(FileName), Wnd, InfoSize, VerBuf) then
    : : : if VerQueryValue(VerBuf, '', Pointer(FI), VerSize) then
    : : : with FI^, Result do
    : : : begin
    : : : Version := dwFileVersionMS shr 16;
    : : : MinorVersion := dwFileVersionMS and $FF;
    : : : Release := dwFileVersionLS shr 16;
    : : : Build := dwFileVersionLS and $FF;
    : : : end;
    : : : finally
    : : : FreeMem(VerBuf);
    : : : end;
    : : : end;
    : : : end;
    : : : end.
    : : : [/code]
    : : :
    : : :
    : : :
    : : I think, it is not possible to rename an active executable, because that file is locked for writing. This locking mechanism is the whole problem of updating an running executable from within itself.
    : :
    : Renaming does not interfere with locking (as I expected also). This is probably because it doesn't change the content of a file.
    :
    :
    :
    You're correct. I assumed it also applied to programs, because it applies to open data files and documents.
  • jammojammo Posts: 12Member
    Thanks guys,

    Now I have the concepts in mind, I can work with the actual implementation of it.

    I can see that the renaming of the executable is a good method for keeping older versions - on the occurence that a new version has problems (for whatever reason) - the user can then backtrack.

    Either way, I have to start looking at the separate updater program

    Thanks for your help. Really helped :)

    - J
  • sohbetisohbeti Posts: 58Member
    This post has been deleted.
Sign In or Register to comment.