custom windows form on uninstall - winforms

I want to show my custom windows form on uninstall. I am going to use a C# custom action for this. How do I make the custom action wait till the user clicks OK or Cancel? I want my custom action to complete only when the form is closed. So do the following in my custom action:
CollectUninstallData f = new CollectUninstallData();
f.Show();
return f.FormResult;
But the form blinks for a moment and the uninstall continues without waiting for the form to close. And this is logical since the GUI is in another thread. But how do I make it wait for the form to close?
I am aware that showing custom windows forms in install packages isn't cool, so if anyone can offer a more elegant solution, then I will thankfully accept it.

You have to use ShowDialog() method instead of Show(). The latter makes the form visible and returns control that's why your Custom Action stops its execution. The former shows the form as a modal dialog box and does not return until the user closes the form in any way.
CollectUninstallData f = new CollectUninstallData();
DialogResult r = f.ShowDialog();
f.Dispose();
return r;
If you want to know whether user clicked OK or Cancel, use this statement return r == DialogResult.OK ? 0 : 1. Return code of zero usually indicates success and non-zero is for failure.

Related

After reloading CN1 Form, GUI elements stop working properly

Our app allows users to submit data to our servers.
Sometimes, users will need to make 3 submission in a row. After checking that the submission works properly (and thankfully it does), we call CustomForm().show() and the Form shows correctly. (CustomForm obviously extends Form.)
We use InteractionDialogs, just as in all other iterations, to handle validation by providing feedback to the user. We do so to mimic the Android Snackbar that provides a prompt and a Button to do an action. In the 1st 2 iterations, the InteractionDialogs show and dispose properly; in the 3rd iteration, the InteractionDialogs start acting erratically.
We also noticed that once that CustomForm (or any other submission forms) is shown 3 times (either the same Form 3 times in a row, or any combo of our submission forms 3 times altogether), a different Form displaying a BrowserComponent will fail – the BrowserComponent will not show anything at all, despite using a strong, unfiltered internet connection and having worked properly prior to the submissions being done. Neither the app nor the Form housing the BrowserComponent crashes -- the BrowserComponent simply does not show anything.
Is there a limit on how many instances of a given Form can be shown, or is there a memory issue?
Please, any ideas on how to solve this?
Thank you.
EDIT: I am adding a screenshot of the EDT thread -- it seems to have invokeAndBlock() called twice and then wait() is called, even though I wrapped my call to show the Form with the BrowserComponent with this try-catch:
try {
CN.invokeWithoutBlocking(() -> {
new FormWithBrowser().show();
)};
} catch (BlockingDisallowedException ex) {
e.getMessage();
}
The other issue is how do I fix InteractionDialogs in my submission form from being affected by invokeAndBlock() and wait() as well? I also don't get any BlockingDisallowedExceptions in my logs. Does that mean that wait() is really the issue?
Thanks again.

Prompt when trying to dial a phone number using tel:// scheme on iOS 11

I am facing an issue, while trying to start a phone call from my iOS app using:
UIApplication open(_:options: completionHandler:)
iOS shows an confirmation popup/alert before starting the call with two button Call & Cancel and CompletionHandler called with a Bool parameter having true/false based on button action in iOS 10.
But now in iOS11 the problem is that the completionHandler is being called automatically before tapping on "Cancel" or "Call" button of confirmation popup, always having true value.
Is this a bug in iOS11 or is there something that I am doing wrong?
There has been a behavior change in when the closure is called in iOS 11. I cant say if this behavior will be reverted or if this is a bug.
But one of the ways you can identify when the user interacted with the popup is by adding a notification listener around UIApplicationDidBecomeActive in the completion closure of openURL(). To identify whether the call was clicked or not you will need to create another custom notification and listener on the CTCallCenter. That was the best way through which I was able to identify it, there might be better solutions though :D
completionHandler will get a call if your given URL gets open success or failure, this has nothing to do with Cancel & Call buttons on Alert
see what Apple docs has to say about it HERE
completionHandler
The block to execute with the results. Provide a
value for this parameter if you want to be informed of the success or
failure of opening the URL. This block is executed asynchronously on
your app's main thread. The block has no return value and takes the
following parameter:
success
A Boolean indicating whether the URL was
opened successfully.

Message box ok cancel, how to cancel the event when user chooses Cancel option

This must be a really dumb question to you guys.
I was trying to add a message box in my win form, here is my code.
var result = MessageBox.Show(" date range over 16 days. Do you want to continue?", "Confirm", MessageBoxButtons.OKCancel);
if(result == DialogResult.OK)
{
}
if (result == DialogResult.Cancel)
{
//when its cancel i prefer to stay on the same window
}
When I click ok button it continues, but I have no idea how to return to the same window if cancel button is clicked. Any help much appreciated.
I would think it will stay in the same form, if you don't have a command for closing the existing form when the messagebox is open?
The MessageBox in itself will not redirect on its own to anywhere else, it will just return control to the calling code without focusing another form or opening/closing anything. You have to explicitly write code for that to happen.
So, my guesses would be, and where I would start looking for something rare:
The cancel handler contains some code that redirects the focus/closes/opens something else, anything different from the OK case
Previous code to the call changes something that it should not do before checking the result.
Anything external is "stealing" the focus or closing the window, like a timer or anything running in the background.
To be more helpful, what is your code in the cancel's if?

Create Console like Progress Window

I am replacing many batch files, that do almost the exact same thing, with one WPF executable. I have the program written, but I am having troubles with my "console" like display.
Within the program I call an executable to perform a task. This executable sends it's output messages to the console. I am able to redirect those to my "console" like display with the following.
Process p = new Process();
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.FileName = MyExecutable;
p.StartInfo.Arguments = MyArguments;
p.Start();
while (!p.StandardOutput.EndOfStream)
{
string _output = p.StandardOutput.ReadLine();
// This is my display string ObservableCollection
_displayString.Add(new DisplayData { _string = _output, _color = System.Windows.Media.Brushes.Black, _fontSize = 12 });
// This is to redirect to a Console & what I want to get rid of
Console.WriteLine(_output);
}
p.WaitForExit();
When the executable is done running I use a MessageBox to ask the user if they want to run the executable again. The problem is that when the MessageBox is up the user is unable to scroll on my "console" like window to make an informative decision. To temporarily work around this I launch a console at start up, see this, and write the output stream from the process running the executable to the console so the user can scroll through the information and make a decision.
I am using a listbox to display a collection of textblocks, see this. I am not attached to anything for making the display, or MessageBox'es.
How can I make a "console" like display that will take a user input (MessageBox, direct input, etc...), but also allow them to scroll through the data before they make their decision?
EDIT:
As to the comments I have been receiving I am not clear on what I am trying to accomplish. I have a batch file that runs a executable multiple times with different arguments per run. There is a lot of setup before and between the executable calls. I have created an executable to replace many flavors of a similar batch file with drop down menus for the user to change settings at run time. When the user likes their settings they click a "Start" button, and away it goes doing setups and prompting questions as it goes and then finally runs executable for the first time.
My issue is when the called executable, inside mine, is done running the user needs to decide if they want to run it again for different reasons. I need to prompt the user "Run again - 'Yes' or 'No'?", and that is where I am running into problems. A MessageBox doesn't allow me to scroll on my Progress Window. I have tried a Modeless dialog box, but with Show() the program continues on, and ShowDialog() is the same issue as the MessageBox.
Any suggestions on how to do this would be appreciated.
You are in Windows, but trying to use DOS paradigm. Windows is event-based system! You need to write "event handlers" but not put all your code in one function.
However, there is a trick, which allows to show Modal (read "blocking your code") dialog in Modeless (read "not blocking your window"). Not sure how to implement this in WPF, but idea is to re-enable your window (which acts as parent for your dialog). You need to do this in your dialog event handler (WM_INITDIALOG equivalent?).
Also (in WinAPI) you may run dialog with NULL as parent window.

Implementing a true modal dialog in Silverlight 5

I'm looking for a good way to implement a truly modal dialog in Silverlight 5. Every example that I find that claims to create a modal dialog really isn't modal in that the calling code waits until the dialog is closed.
I realize this is a challenge because we can't actually block the UI thread because it must be running in order for the dialog (ChildWindow) to function correctly. But, with the addition of the TPL in SL5 and the higher level of adoption Silverlight has seen over the past few years, I'm hoping someone has found a way around this.
A good representative scenario I am trying to solve is an action (say clicking a button or menu item) that displays a login dialog and must wait for the login to complete before proceeding.
Our specific business case (whether logical or not) is that the application does not require user authentication; however, certain functions require "Manager" access. When the function is accessed (via button click or menu item selected, etc), and the current user is not a manager, we display the login dialog. When the dialog closes, we check the user's authorization again. If they are not authorized, we display a nice message and reject the action. If they are authorized, we continue to perform the action which typically involves changing the current view to something new where the user can do whatever it is they requested.
For the sake of closure...
What I ended up with is a new TPL-enabled DialogService with methods like:
public Task<Boolean?> ShowDialog<T>()
where T : IModalWindow
The method creates an instance of the dialog (ChildWindow), attaches a handler to the Closed event and calls the Show method. Internally, it uses a TaskCompletionSource<Boolean?> to return a Task to the caller. In the Closed event handler, the DialogResult is passed to the TrySetResult() method of the TaskCompletionSource.
This lets me display the dialog in a typical async way:
DialogService.ShowDialog<LoginDialog>().ContinueWith(task =>
{
var result = task.Result;
if ((result == true) && UserHasPermission())
{
// Continue with operation
}
else
{
// Display unauthorized message
}
}, TaskScheduler.FromCurrentSynchronizationContext());
Or, I could block using the Task.Wait() method - although this is problematic because, as I mentioned in the original post, it blocks the UI thread, so even the dialog is frozen.
Still not a true modal dialog, but a little bit closer to the behavior I am looking for. Any improvements or suggestions are still appreciated.

Resources