Results 1 to 14 of 14

Thread: [RESOLVED] How to install an exe on itself ?

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Nov 2016
    Location
    Jurbise - Belgium
    Posts
    203

    Resolved [RESOLVED] How to install an exe on itself ?

    Hi,
    When I compile a new version of my software it is advisable to copy the .exe at the same place because the folder also contains own user files.
    Of cause the software cannot copy the .exe to itself because it is in use.
    I give a message saying a new release is available which also gives the path where the .exe should be downloaded.
    But often the user downloads at another place and is not happy because he has lost his childs.

    How can I download myself onto myself, or start another .exe which does the job ?
    Thanks for your help.

  2. #2
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,853

    Re: How to install an exe on itself ?

    Hi Herve_be,

    It's been a while ago, but I actually used to do this. I had to put several "checks" in it to get it all working, but here's the gist of it.

    * Make a copy of myself (the EXE).
    * Execute that copy.
    * Copy waits until main copy has terminted.
    * Main program terminates.
    * Copy kills main copy.
    * Copy downloads update (and places it where main copy was, same name).
    * Copy executes new program.
    * Copy terminates.
    * New program detects copy, and keeps trying to kill until successful.
    * New program shows its menu/interface, and we're back.

    That's all from memory as I abandoned the whole idea several years ago. But it did work.

    At this point, my users are all savvy enough to just download an update, delete the old, and replace it with the new. Also, many like keeping the old versions just as a double-check that everything is going to work correctly.

    Good Luck,
    Elroy
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  3. #3

    Thread Starter
    Addicted Member
    Join Date
    Nov 2016
    Location
    Jurbise - Belgium
    Posts
    203

    Re: How to install an exe on itself ?

    Thank you but I don't understand why you use a copy of the program, it could be another simple "Upgrader" program as this

    Main program detects there is a new version.
    Main program downloads the Upgrader.
    Main program starts the Upgrader.
    Upgrader waits for main program to terminaite : my question is "how does it knows the main program is finished ?
    Upgrader downloads main program new version.
    Upgrader starts main program new version.
    Upgrader terminates.

    It is not necessary to kill the Upgrader.
    My problem is that my users do not download the new version at the same place (directory) as the old one so the associated files are also elsewhere.

  4. #4
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,853

    Re: How to install an exe on itself ?

    Hi Herve,

    Well, if you've got an "Upgrader", then it seems that most of your problems are solved. The only problem you have is that you can't kill a program's EXE while it's running. Therefore, you need a second EXE to help you out. I suppose there are several ways to get this done, but it seems that you have the solution at hand.

    Good Luck,
    Elroy
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  5. #5
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,853

    Re: How to install an exe on itself ?

    Ahhh, I also see that you're wanting to figure out if the other program is running.

    I can see a couple of solutions.

    1) Here's a KillProcess procedure. You could certainly use it. Also, it could be fairly easily modified to just detect to see if the program is still running. It does use the WMI, and dilettante will pop on and say that the WMI may not always be present, but I've never had a problem with it.

    Code:
    
    Public Sub KillProcess(ByVal sProcessName As String)
        ' Kill process using Visual Basic 6 0 and WMI.
        ' The full .exe name (including the .exe) is supplied, but no path.
        ' Example: KillProcess "excel.exe"
        ' BE CAREFUL:  No prompt for saving takes place.
        '              ALSO, it kills all occurrences.
        Dim oWMI As Object
        Dim ret As Long
        Dim oServices As Object
        Dim oService As Object
        Dim sServiceName As String
        Dim bFoundOne As Boolean
        '
        On Error Resume Next
            sProcessName = LCase$(sProcessName)
            Set oWMI = GetObject("WinMgmts:")
            Set oServices = oWMI.InstancesOf("win32_process")
            '
            Do
                For Each oService In oServices
                    sServiceName = LCase$(Trim$(CStr(oService.Name)))
                    If sServiceName = sProcessName Then
                        ret = oService.Terminate
                        bFoundOne = True
                    End If
                Next oService
                If Not bFoundOne Then Exit Do
                If Err Then Exit Do
                bFoundOne = False
            Loop
        On Error GoTo 0
    End Sub
    
    Okay, being called to a meeting. I'll post more later.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  6. #6

    Thread Starter
    Addicted Member
    Join Date
    Nov 2016
    Location
    Jurbise - Belgium
    Posts
    203

    Re: How to install an exe on itself ?

    How does the Upgrader knows that the main program is not running thus it can kill it ?

  7. #7
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,672

    Re: How to install an exe on itself ?

    Quote Originally Posted by Elroy View Post
    * Make a copy of myself (the EXE).
    * Execute that copy.
    * Copy waits until main copy has terminted.
    * Main program terminates.
    * Copy kills main copy.
    * Copy downloads update (and places it where main copy was, same name).
    * Copy executes new program.
    * Copy terminates.
    * New program detects copy, and keeps trying to kill until successful.
    * New program shows its menu/interface, and we're back.
    Hi, Elroy.
    You can rename already running EXE.
    1. Rename myself;
    2. Download the new EXE with the actual name;
    3. Run the new exe;
    4. Wait until the old exe will be terminated and delete it (in the new EXE code).

    You can pass handle or PID of process in any IPC (for example command line).

  8. #8
    Frenzied Member
    Join Date
    Dec 2012
    Posts
    1,470

    Re: How to install an exe on itself ?

    This is how I used to do it. I would remotely copy the new version to the customer's server. When a user connected to the server, it would compare it's own file date to the file date on the server. If the server file date was newer, it would create a batch file to rename the old file to ".bak" and copy the newer file from the server. If it was one of the sub programs, that was it. If it was the main program, the user would be instructed to restart.
    Code:
    Private Function CheckFileVer(FileName$) As Boolean
        Dim ThisFileName$, ThatFileName$, Runfile%, Response%
        Dim ThisFileDate As Double, ThatFileDate As Double
        Dim sErr As String
        Const sProc As String = "CheckFileVer"
        On Error GoTo CheckFileVerErr
        ThisFileName$ = App.Path + "\" + FileName$
        ThatFileName$ = DataPath + FileName$
        ThisFileDate = FileDateTime(ThisFileName$)
        ThatFileDate = FileDateTime(ThatFileName$)
        If ThisFileDate < ThatFileDate Then
            Response% = MsgBox(ThisFileName$ + " is Dated: " + vbCrLf + Format$(ThisFileDate, "dd-mmm-yy hh:nn:ss") _
            + vbCrLf + "A newer version:" _
            + vbCrLf + ThatFileName$ + " Dated: " + vbCrLf + Format$(ThatFileDate, "dd-mmm-yy hh:nn:ss") _
            + vbCrLf + "is available." + vbCrLf + "DOWNLOAD IT?", 4)
            If Response% = 6 Then
                If FileName$ = VBApp + ".exe" Then
                    Runfile% = OpenFile(App.Path + "\Update.Bat", 1, 0, 80)
                    If Runfile% = 0 Then
                        MsgBox "Problem incurred creating Update File", 16, "ABORT UPDATE"
                        Exit Function
                    Else
                        Print #Runfile%, "copy %1 %2"
                        Print #Runfile%, "pause New file will now be copied!"
                        Print #Runfile%, "copy %3 %1"
                        Print #Runfile%, "REM When finished close this window and restart the program!"
                        Print #Runfile%, "exit"
                        Close #Runfile%
                    End If
                    Shell App.Path + "\Update.Bat " + ThisFileName$ + " " + App.Path + "\manta.old " + ThatFileName$, 1
                    End
                ElseIf FileName$ = "BackMan.exe" Then
                    FileCopy ThatFileName$, ThisFileName$
                ElseIf FileName$ = "Mantacct.exe" Then
                    FileCopy ThatFileName$, ThisFileName$
                End If
            End If
        End If
        CheckFileVer = True
        Exit Function
    CheckFileVerErr:
        sErr = msModule & gsDelimiter & sProc _
            & gsDelimiter & Err.Number & gsDelimiter & Err.Description
        Call LogError(sErr)
    End Function
    J.A. Coutts

  9. #9
    Hyperactive Member
    Join Date
    Aug 2017
    Posts
    380

    Re: How to install an exe on itself ?

    Here's an example of The trick's suggestion:

    Quote Originally Posted by Bonnie West View Post
    This example shows how a single EXE can replace a currently running instance of itself with a new version (for simplicity, this demo just copies the old EXE). It relies on the fact that executables can be renamed even while they're running. This example also shows how the old version can instruct the new version to delete the old executable file after it terminates. Compile the following code first before trying it:

    Code:
    Option Explicit 'In a standard module
    
    Private Const DELETE_THIS As String = " /DeleteThis "
    
    Private Declare Sub Sleep Lib "kernel32.dll" (Optional ByVal dwMilliseconds As Long)
    
    Private Sub Main()
        Dim sExeFileName As String, sTmpFileName As String
    
        If ProcessCmdLineArgs(" " & Command$ & " ") Then Exit Sub
    
        sExeFileName = App.Path & "\" & App.EXEName & ".exe"
        sTmpFileName = App.Path & "\" & App.EXEName & ".tmp"
    
       'If sTmpFileName exists, delete it
        On Error Resume Next
        Select Case (GetAttr(sTmpFileName) And vbDirectory) <> vbDirectory
            Case True:  SetAttr sTmpFileName, vbNormal:  Kill sTmpFileName
        End Select
        On Error GoTo 0
    
       'Rename this EXE
        MsgBox "Before renaming...", vbInformation
        Name sExeFileName As sTmpFileName
    
       'Replace old EXE with new EXE
        MsgBox "Before copying...", vbInformation
        FileCopy sTmpFileName, sExeFileName
    
       'Tell new EXE to delete old EXE
        MsgBox "Before starting new EXE & deleting old EXE...", vbInformation
        Shell sExeFileName & DELETE_THIS & """" & sTmpFileName & """", vbNormalFocus
    End Sub
    
    Private Function ProcessCmdLineArgs(ByRef sCmdLine As String) As Boolean
        Dim nTries As Integer, StartPos As Long, EndPos As Long, sFileName As String
    
        StartPos = InStr(1&, sCmdLine, DELETE_THIS, vbTextCompare)
    
        If StartPos Then
            StartPos = InStr(StartPos + Len(DELETE_THIS), sCmdLine, """")
            EndPos = InStr(StartPos + 1&, sCmdLine, """")
    
            If EndPos Then
                sFileName = Mid$(sCmdLine, StartPos + 1&, EndPos - StartPos - 1&)
    
                If LenB(sFileName) Then
                    On Error Resume Next
                    SetAttr sFileName, vbNormal
    
                    For nTries = 1 To 10
                        Err.Clear
                        Kill sFileName
                        If Err Then Sleep 500&: DoEvents Else Exit For
                    Next
    
                    ProcessCmdLineArgs = MsgBox("End demo?", vbQuestion Or vbYesNo) = vbYes
                End If
            End If
        End If
    End Function

  10. #10
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,853

    Re: How to install an exe on itself ?

    Okay, I'm back.

    One thing I've run into is that my executable typically resides on a network. I've found that, when multiple people are running it, under certain circumstances, you can rename it and even delete it. However, when you do so, you crash all the other people who were using it. The one thing you can't do is copy over it with another file of the same name.

    Herve_be, I'm not sure those are concerns for you. If not, then ignore that concern.

    Now, regarding figuring out if you (your workstation) is running the program, there are a few different approaches, all requiring API calls. If you know the name (actually title) of a form that'll always be loaded, you could search for it. If you're sure of the executable's name, you could search for that in your running processes list.

    Maybe that'll help.

    Good Luck,
    Elroy

    @Trick: Yeah, back when I was still doing this, I did use a bit of a Command$ trick to get it all done.
    Last edited by Elroy; Jan 25th, 2018 at 11:21 AM.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  11. #11

    Thread Starter
    Addicted Member
    Join Date
    Nov 2016
    Location
    Jurbise - Belgium
    Posts
    203

    Re: How to install an exe on itself ?

    Hi,
    I did like this, it works fine :
    - the main program checks for a new version;
    - if it find one it starts an Upgrade program;
    - main program ends.

    Upgrade program
    Code:
    On Error Resume Next
    Do
        Kill App.Path & "\RVReefTools.exe"
        DoEvents
    Loop While Err.Number = 75 ' loops while the main program is still running and cannot be killed
    ...
    URLDownloadToFile(0, URL, App.Path & "\" & FileName, BINDF_GETNEWESTVERSION, 0) ' Download new version
    ...
    Shell(App.Path & "\RVReefTools.exe", vbNormalFocus) ' Starts new version

  12. #12
    PowerPoster
    Join Date
    Nov 2017
    Posts
    3,116

    Re: How to install an exe on itself ?

    Herve, I'll just throw in one thing to be careful of here. What if your URLDownloadToFile call fails to download the new .exe? Then the user is left in a state where the main executable is no longer present, because you deleted it in the Do-Loop.

    It shouldn't be too much work to shuffle steps around and try to download the upgraded exe first (to a filename like RVReefTools.exe.new), and then only if that download is successful delete the .exe file and then rename the downloaded file.

    Code:
    On Error Resume Next
    URLDownloadToFile(0, URL, App.Path & "\" & FileName & ".new", BINDF_GETNEWESTVERSION, 0) ' Download new version
    ...
    If download worked then
      ...
      Do
          Kill App.Path & "\RVReefTools.exe"
          DoEvents
      Loop While Err.Number = 75 ' loops while the main program is still running and cannot be killed
      ...
      'Add code to rename downloaded file to remove the .new from the end of the filename
      ...
      Shell(App.Path & "\RVReefTools.exe", vbNormalFocus) ' Starts new version
    End If

  13. #13

    Thread Starter
    Addicted Member
    Join Date
    Nov 2016
    Location
    Jurbise - Belgium
    Posts
    203

    Re: How to install an exe on itself ?

    For the moment, if a new version is available, you cannot work with the old one anymore : it tells you that you must download the new version then ends.
    So keeping the old version is useless.
    Before ending it also opens a WEB page explaining "what's new" and also giving a link to download the program manually.
    If URLDownloadToFile call fails to download the new .exe you can still download it from the web page, as when you install it for the first time.

  14. #14

    Thread Starter
    Addicted Member
    Join Date
    Nov 2016
    Location
    Jurbise - Belgium
    Posts
    203

    Re: How to install an exe on itself ?

    But you are right, I changed so

    Code:
    Private Sub Form_Load()
    On Error GoTo ErrorHandler
    ...
    Call DeleteUrlCacheEntry(URL)
    If URLDownloadToFile(0, URL, App.Path & "\RVReefTools.new", BINDF_GETNEWESTVERSION, 0) = 0 Then
        On Error Resume Next
        Do
            Kill App.Path & "\RVReefTools.exe"
            DoEvents
        Loop While Err.Number = 75
        On Error GoTo ErrorHandler
    
        Name App.Path & "\RVReefTools.new" As App.Path & "\RVReefTools.exe"
        ProcessID = Shell(App.Path & "\RVReefTools.exe", vbNormalFocus)
    Else
        MsgBox ("Le logiciel n'a pas pu être téléchargé."), vbCritical
    End If
    End
    
    ErrorHandler:
        MsgBox ("Erreur " & Err.Number & " (" & Err.Description & ")" & Chr$(10) & " ligne " & Erl), vbCritical
    End
    End Sub

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width