i have the following problem. i am working on an auto update in my application which means i want to re-download the application. i am using DownloadFile method for this but the problem is of course i cannot download and exchange the file with my current application as long as the application is running and i can't run code after it's closed either.
this is what i am basically trying to do for ppl still didn't get my problem:
Private Sub closeApp()
Application.Exit()
' DOWNLOAD FILE AFTER PROGRAM CLOSED
End Sub
The way this is usually done is to have 2 separate programs. One is the program its self, the other is the updater. When you exit the program you spin up a copy of the updater and exit the actual program. the updater program is then free to download and overwrite the main application because the file isn't in use any more.
This can also be reversed, with the updater, sometimes called the "launcher" when used this way, acting as a stub that checks for updates to the main application when it starts. Once it sees that no update is needed, or after it updates the main program, it goes on to launch the main program and exits its self.
Related
I am rewriting an application for printing shipping labels that we have been using for many years, because over those many years, many programmers have added bits and pieces to it, and it has become harder and harder to maintain.
While considering design choices, I came across catching the application's StartUp event in ApplicationEvents.vb, which I thought would be a good choice for this application because the main form is only displayed if there are more than 10 labels to print at a time (displays a progress bar if so, but mostly it does one label at a time and as such the progress bar isn't desired).
Now, whether this is a good choice I'm not sure, but while playing around with it I have found a need to exit the application from this event if certain criteria aren't met (invalid command line args, network directory not found in expected location, and a few other criteria). I have been unsuccessful in figuring out how to exit from the application if something like the above were to occur. The only thing close I have found is setting the StartupEventArgs.Cancel to True, but the documentation states that this only stops the main form from loading and if set to true should point code on a different processing path.
Is there a "proper" way to exit the application in the StartUp event? I've tried using My.Application.Shutdown which doesn't exist, and RaiseEvent ShutDown() which gives the error "Derived classes cannot raise base class events."
Linked here is the main doc I have been using for research (and the related links on the linked page):
https://msdn.microsoft.com/en-us/library/t4zch4d2(VS.80).aspx
You can use End to immediately kill the process, note that:
This will prematurely kill the process
Any files being written to can become corrupted
Any other activity related to the program will be terminated
To protect against file corruption, you could use a subroutine that 'finishes up' and then terminates the program, for example:
Private Sub finishUp()
[..close files, forms, here..]
End
End Sub
I did this myself for a gameserver program I made a couple of months ago; the program needed to note in the SQL database the startup and shutdown times. I made it log the shut-down time in a subroutine similar to the one above.
Note that the same subroutine could (and probably should) be used when you need the program to close at any other time.
My application updates(running a vba script) an excel shared workbook, and since it is shared, there shouldn't be problems when someone else is using the same file at the same time. But for some reason, sometimes it simply freezes, without any error message, just freezes.
Is there a way to programatically make the application stops/closes automatically when frozen or after some minutes(In normal conditions, this updating process shouldn't take more than 1 minute)?
And, if possible, re-launch the app again automatically after some minutes for at least 5 attempts?
This way would ensure process completes succesfully.
I have had to do this same thing before but because I had an application that would look for updates to it's self on the network and then update it locally. Problem is, you cannot update the exe that is running.
What I did to get around it is to create another program that would wait a second, update the exe, then run the exe again.
Because I did this with a few different apps, I made my "Updater" generic so I could send some command line parameters and it would use those to copy and run.
If you want to try something else, you might be able to accomplish this same thing by creating a BAT file and running it. I'm not real good on BAT files so I can't help you there. But, it is another way to handle it.
This question already has answers here:
Don't lock files of application while running
(4 answers)
Closed 9 years ago.
I created a small application which users launch through a desktop shortcut pointing to a network share. Whenever I recompile the app and want to move it to the network share to make it available, it is always locked by many users who are using it, understandably. What I don't get is that I can close all the handles (net file 1234 /close) and the users are unaffected, i.e. they can still work on the app. I then copy the new file and ask them to restart.
Is there a way to "cut off" programmatically the users from the network exe file once they have launched it, so that I don't have to manually close all of the handles every the time?
They'll be affected but the way the jitter works indeed makes it a bit unlikely that their program will crash. Crashes are likely when you use Reflection in your code or the user's machine is under memory pressure from other processes and the program executes code that has not been jitted. YMMV.
The proper deployment choice here is ClickOnce. That creates a local copy of the program on the user's machine. And it automatically sees your update when they restart.
A possible band-aid is renaming the executable. Which works because Windows puts a lock on the file content, not the directory entry. Which lets you copy the update with the same name. Any user that restarts the app will now get the new version. You'll eventually be able to delete the renamed file. But do favor ClickOnce first.
Okay, this is one that has me stumped beyond belief. I have a program that is to be installed on different machines that is supposed to execute a batch file after it has completed a specific task. The batch file is configured via our webservice by the user, and the application pulls this path string down and then executes the file at that path. Should be pretty simple/straightforward, right?
The code:
Private Function ExecuteBatchFile(batchFilePath As String) As String
Try
Dim psi As New ProcessStartInfo(batchFilePath)
psi.RedirectStandardError = True
psi.RedirectStandardOutput = True
psi.CreateNoWindow = False
psi.UseShellExecute = False
Dim process As Process = process.Start(psi)
process.WaitForExit()
ExecuteBatchFile = process.ExitCode
Catch ex As Exception
StrAppStatus = "Error within execution of batch file: " & ex.Message
LogMe(StrAppStatus)
Return "Fail"
End Try
End Function
Now, for the tricky part. This code works perfectly when running in the dev environment. I have yet to have an issue. HOWEVER, when the application is installed on any computer (including the same one the IDE is installed on), when it gets to the step in it's overall process that calls this function, it does not actually launch the batch file. Keep in mind, it never throws an exception, on either side. It also does not return an exitcode to that string, as i have other logging to track that as well.
There are only two possibilities I can think of in this case. Either A:) there is a permissions issue where the application is not allowed to launch batch files on the computer it is installed on, or B:) this sub is called by a thread that was spun off from the main thread (i.e. using the MyThread = New System.Threading.Thread(AddressOf TheMainLoop) MyThread.Start() command).
Still the fact that it works 100% of the time during the compile and run phase in the IDE but not after an install is blowing my mind.
EDIT 1:
Just did a test where I placed a button on the main form itself, and the click event does the same thing as the earlier function, and it works, even after an install. This leads me to believe that it will only work if it is launched using the main thread... What do you all think?
EDIT 2:
The batch file is a very simple test batch that opens a text file, and I know that the batch file and path are both fine, because when compiled it works fine. Also, edit 1 was stating that I created a simple button that executes the same code from above, and it works fine after an install. Since that was done on the main thread, and the code from earlier was done in a separate thread spun off from the original, I was wondering if that was the cause of the issue.
The other crazy thing is that my logging catches if the file launches or not, and it almost acts as if it is launching when I have that original issue. Bah, this whole thing is just nuts.
EDIT 3:
Added the answer.
Thanks to tinstaafl, the answer was to change UseShellExecute to True. I had to remove the RedirectStandardError and RedirectStandardOutput lines, but I wasn't using them anyways. On that note, thank you everyone for your investigations, and if anyone has an idea as to why this happened, I am all ears.
I have wrote a win forms application in VB that requires some external DLLs, It installs and runs flawlessly on several machines but it does not work on one laptop! I even put Filestreams to write exceptions to a text file. While it writes intended header text to the debug file on other computers, it does not write anything to the debug file on the aforementioned laptop. My guess is that it does not even reach Form1_Load() method.
This is the structure of the program:
Import namespaces from external programs
Public Class MyApp
''Varibale declarations:
Structures and classes based on DLLs
Other declarations based on .Net Objects
Stream writer declaration and initialization for the debug file
Private Sub Form1_Load(...)
Try
Write Start and time to the debug file
execute commands
catch
write debug info
end Try
End Sub
Other events and subs
End Class
IS there a way to see what happens between the initialization of the debug file and execution of Form1_Load() ??
As I said it works perfectly on all the machines that use this except one!!
What are the things that I need to check on that machine?
Chances are that the user of the laptop is not in the Administrators group and you're trying to write to the application program folder.
Have you tried to add a placeholder line in the debug file immediately after initialization, to check that the file is actually write-able?
Is the Form's constructor reachable? If you move the "Write Start and time to the debug file" code to the constructor, does it write anything?