how to show msgbox if any process is closed - vb.net

This is my code, it works only on form load or click.
But I need to show this msgbox when process close while my app running.
Dim p() As Process
p = Process.GetProcessesByName("notepad")
If p.Count > 0 Then
' Process is running
MsgBox("Running!")
Else
' Process is not running
MsgBox("Not running!")
End If

So, you want to monitor the status->Running or status->NotRunning of a process,
while your Application is executing.
This requires a method that continuously updates the Status of a monitored foreign process.
How this method works, depends on you application functionality:
Is invisible and becomes visible/operable when the monitored process
starts?
Operates indipendently from this foreign process, but takes special
actions when this other process becomes active?
Executes visible and its only purpose is to monitor the foreign
process?
Other
First take a look to:
Check if process is done in VB.Net
application closes itself when another program closes?
Wait for a specefic program to open before continue VB.NET
I suggest you learn how to instantiate a BackgroundWorker.
It's a very straightforward and helpful tool to use if you don't want to manually control an Asynchronous task.
A BackgroundWorker can be instructed to notify your main process (application) that a defined condition has changed.
When this condition is met, the BW raises an Event, letting you know what happend or changed.
Then you decide how to proceed, or - if it is the case - you can terminate the activity of the BackgroundWorker.
Give it a try.

Related

Is there any way to pause a Windows shutdown so that a forms.closing method can complete?

I am trying to put some information in a database when windows begins to shutdown. In my application I am handling the Form.Closing event. However, Windows will go ahead and shut down and my Method doesn't have time to complete. Is there any way to pause the shutdown long enough to handle the shutdown? Here is my method that I am currently using.
Private Sub frmMain_Closing(sender As Object, e As FormClosingEventArgs) Handles Me.Closing
If e.CloseReason = CloseReason.WindowsShutDown Then
_logger.Debug("Hit frmMain_Closing1")
NewEvent(Events.SystemShutdownNormal)
System.Threading.Thread.Sleep(10000)
_logger.Debug("Hit frmMain_Closing 2")
End If
End Sub
Every time I am logging twice to a log file using the _logger.Debug("Hit...") However, only the first time I call it is getting written to the file. I have tried the method of setting e.Cancel = True, but that didn't seem to work.
Sorry for this misformation.
In short, there is no way to delay or cancel a Windows shutdown. It will tap all processes "nicely" to exit, then go through and kill any ones that haven't.
You can delay shutdown until your process finishes. To do this, you need to use ShutdownBlockReasonCreate().
You should be hooking the WM_QUERYENDSESSION message in order to get the opportunity to do something. You'll need to override the WinProc, deal with the message, and then call the base WinProc. Take a look at https://msdn.microsoft.com/en-us/library/microsoft.win32.systemevents.sessionending(v=vs.110).aspx (scroll down to remarks.)
Keep in mind that Windows won't wait forever, but this will give you a bit of advance notification.. hopefully enough that you have a chance to do whatever you need to do. Prioritize the important stuff first, in the hopes that it finishes before the process is killed.
Once you've hooked WM_QUERYENDSESSION, you should call
ShutdownBlockReasonCreate() to block shutdown until your app is finished closing. Once finished, call ShutdownBlockReasonDestroy(). For more information, see this MSDN article (scroll down to "Applications that must block shutdown should use the new shutdown reason API").
The PInvoke declares can be found here and here.

Wait until all background jobs have terminated, C

I know how waitpid(-1...) allows me to wait until all children have finished, such as waitpid(-1, &status). But how can I wait until all background processes are finished? Someone suggested that I can use the same waitpid (in a loop?) to achieve this but I don't see how.
To be clear, I'm implementing a shell, and need to add a new built-in command wait, which waits until all background jobs have terminated before returning to the prompt.
I read somewhere else on SO that "You will also want to call waitpid() with the WNOHANG option regularly - say, immediately before you display the shell prompt. This will allow you to detect when the background process has exited or stopped " But again, child != background. So even that I don't believe.
Edit:
I ended up just doing while(wait(NULL) > 0); and that's it, it worked. But what I'm still confused about is don't I WANT to make a distinction between foreground and background because the wait I'm implementing only waits for the background processes, and all children are equal in the eye of wait() or waitpid().
So again, the children I'm waiting for by using wait() or waitpid() aren't necessarily background processes. Am I wrong?
Since you ask in the context of implementing a shell, and evidently your shell supports enough job control to have a concept of background processes, it is reasonable to suppose that your implementation will have a table in which it tracks background jobs. That table can and should track the PID of the process associated with each job.
Having those PIDs in hand, you can waitpid() for specific background jobs until there are no more in the table, or you can waitpid(-1) to collect
any and every job, in a loop, until there are no more background jobs in the table.
If you want to implement background process (and job control) and catch their termination (at least) you must set a signal handler for SIGCHLD, and call wait(-1) inside it. This will let your shell receive asynchronous notifications of background processes termination. You may have a look at Catching SIGCHLD for example and discussion about this.

NotesTimer causes the whole lotus client to flicker

I have a timer that talks to java objects through LS2J. It has only to call some getters of the java objects and to update the GUI with new values. This causes the GUI in iNotes Client to show the "Busy" cursor very shortly when the timer ticks. I is really annoying because it occurs even when another window is open and even in the designer.
I actually have to expect that the functionality in the timer event will get more complicated in the future, so I don't want to solve the problem by making my handler lighter.
Is there a way to tell iNotes client not to show this cursor or even an alternative way to make this regular check without timers?
The NotesTimer class in Notes client (not iNotes) does take over the foreground when it triggers, so there will be a bit of a delay if you do something that takes time to execute. It's possible to set up the Notes client to execute background scheduled agents in local database replicas, so that might be an option. You can to the heavy lifting in background and deposit the results somewhere -- say, in a profile document -- that can be accessed quickly by the UI code.
Alternately, you could try a XPages in the client application. I believe it can do partial refreshes while other stuff is going on.
For the record, I simplified the functionality of the Java call by preparing the data so that the timer only has to read the results. I also made the timer run every 3 seconds instead of 1.
Now I don't see any flicker!

thread does not start until sub is completed VB.NET

I have the following sub in my program:
public sub RunThis()
Me.Hide()
NEWFORM.Show()
Dim t = New Thread(Sub() Me.printToPowerPoint(saveLocation, printlist))
t.SetApartmentState(ApartmentState.STA)
t.IsBackground = True
t.Start()
While t.isAlive
end while
NEWFORM.close()
Me.Close()
end sub
Running this my program hangs. Does anyone have a solution for this problem.
I am new to threading.
As you probably know, in WinForm projects, the UI can only be dealt with from a single thread. This is affectionately known as the UI thread. That's why, any time you need to access or modify a UI element, you must call the control or form's Invoke method. The Invoke method causes the given delegate to be run on the UI thread. However, doing so will not interrupt any processing that is already being performed by the UI thread. If the UI thread is currently busy, when you call Invoke, it will hang until the UI thread is no longer busy, then it will execute the given delegate.
So, in your code, you are starting a new thread which inside it is trying to invoke a method back on the UI thread. However, immediately after starting the new thread, you then enter a loop which keeps the UI thread busy until the other thread is done. So, when your new thread invokes back to the UI thread, the UI thread is busy and both threads are effectively hung forever.
DoEvents is a keyword you can call from within a lengthy process or loop in the UI thread to signal that you want to, essentially, pause your current processing thereby freeing up the UI thread to process any waiting window messages (painting events, click events, invoke requests, etc.). As soon as all those pending window messages are processed, it will return to doing whatever the next statement is after you called DoEvents. Therefore, if calling DoEvents inside the loop causes it to work properly, that means that your new thread must be invoking back onto the UI thread, or waiting for some other window message to be processed before continuing.
Calling DoEvents is dangerous and widely panned as being bad practice. Typically, if you need to call DoEvents, it's a sign that you need to rethink your design. Usually there is a better way to do what you are doing.
In your case, it looks like starting the new thread is utterly pointless. Unless you have abbreviated you code, it appears that as soon as you start the new thread, you simply put the UI thread on hold waiting for the other thread to finish. If that's the case, it would make much more sense to simply do the work on the UI thread itself rather than starting a new one. In the code you provided, no two threads will ever be effectively be doing processing at the same time, so it's no better than a single thread.

Thread Getting Interrupted in VB.NET

I am running code in a thread upon opening an Excel workbook that takes some time to execute. If I attempt to close the workbook while the thread is still executing, giving me the standard prompt to Save or cancel, my thread is interrupted (not sure if "interrupted" is technically the right term) when I click Cancel. More generally, it seems that UI interactions/updates cause the thread to be interrupted.
Is there a way to either 1) prevent the thread from being halted by a UI update/user interaction, or 2) allow the thread to resume after being interrupted?
Nothing fancy about the code:
Private Shared Sub Test()
Dim t As New Thread(AddressOf DoSomethingThatTakesAWhile)
t.Start()
End Sub
I made a bunch of progress on this, but ultimately could not get this to work using my original approach. So, I switched to .Net Framework 4.0 and used Tasks (System.Threading.Tasks namespace) to handle the job. Tasks worked beautifully and intuitively, and removed much of the complexity around thread management.