C# Outlook Addin setCurrentFormPage throw exception - c#

I am developing a plugin for outlook with VSTO and i am trying to put a separate form region to show as the current form page in the open inspector but throw an exception. here is the code
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
this.Application.Inspectors.NewInspector += InspectorsOnNewInspector;
this.Application.Explorers.NewExplorer += Explorers_NewExplorer;
}
private void Explorers_NewExplorer(Outlook.Explorer explorer)
{
}
private void InspectorsOnNewInspector(Outlook.Inspector inspector)
{
MessageBox.Show("ola");
// exception ocurrs in this line
inspector.SetCurrentFormPage("OutlookAddIn.RequestFormRegion");
}
private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
{
}
Thanks in advance.

I managed to put it to work with the following code
private void InspectorsOnNewInspector(Outlook.Inspector inspector)
{
MessageBox.Show("ola");
if (!(inspector.CurrentItem is Outlook.TaskItem)) return;
var taskItem = (Outlook.TaskItem) inspector.CurrentItem;
taskItem.Open += (ref bool cancel) =>
{
try
{
inspector.SetCurrentFormPage("OutlookAddIn.RequestFormRegion");
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
}
};
}

Related

Global error handling doesn't work in WPF

I want to handle all unexpected errors in a WPF application. When I look at, there are different events for different situation to capture and control error. Also I added these in application constructor method
public App()
{
AppDomain.CurrentDomain.FirstChanceException += OnFirstChanceException;
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
Dispatcher.UnhandledException += OnDispatcherUnhandledException;
TaskScheduler.UnobservedTaskException += OnUnobservedTaskException;
}
However, I try that for checking handling but they didn't work. What is the reason?
private void btnStart_Click(object sender, RoutedEventArgs e) //2021112242
{
throw new StackOverflowException();
}
Every exception event has his own callback method & event object
// Dispatcher.UnhandledException
private static void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
}
// TaskScheduler.UnobservedTaskException
private static void OnTaskSchedulerUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
{
}
// AppDomain.CurrentDomain.UnhandledException
private static void OnCurrentDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
}
// AppDomain.CurrentDomain.FirstChanceException
private static void OnCurrentDomainUnhandledException(object sender, FirstChanceExceptionEventArgs e)
{
}
App has an event for this called DispatcherUnhandledException. This works in most cases but when the exception is thrown from a separate thread it gets a little hairy.
public partial class App
{
public App()
{
// Globally handle errors/exceptions for a friendly close.
DispatcherUnhandledException += DispatcherOnUnhandledException;
}
private void DispatcherOnUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
try
{
e.Handled = true;
e.Exception.Display("An unhandled exception occurred, the application will now close.");
e.Exception.Log(); // log the problem.
Shutdown(-1); // assume not recoverable.
}
catch
{
Shutdown(-1);
}
}
}

Control/Sync variable between multiple threads c#

I am having some timing issues with the following code. Basically I have "recordingOn", when True, it's suppose to start writing frames to file. In the below program, when I sometimes do Stop_Button_Click, I get an exception on "writer1.Write(frame1);" line, this is likely because it's doing so after I've already done dispose(). How do I synchronize this? thanks!
private bool recordingOn = false;
private void ConnectCameras_Button_Click(object sender, EventArgs e)
{
if (!captureInProgress) //Start cameras streaming
{
camera1Capture.ImageGrabbed += ProcessFrame;
camera1Capture.Start();
}
else //Stop cameras streaming
{
camera1Capture.Stop();
imageBox1.Image = null;
camera1Capture.ImageGrabbed -= ProcessFrame;
}
captureInProgress = !captureInProgress;
}
private void ProcessFrame(object sender, EventArgs arg)
{
camera1Capture.Retrieve(frame1);
imageBox1.Image = frame1;
if (recordingOn)
{
try
{
writer1.Write(frame1);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
private void Stop_Button_Click(object sender, EventArgs e)
{
// Doing other stuff...
recordingOn = false;
writer1.Dispose();
}
The basic issue is of shared variable across multiple threads. Please use lock to control access to shared variable. Lock ensures that at one time only one thread can access a variable.
private bool recordingOn = false;
private static object _lock = new Object();
private void ConnectCameras_Button_Click(object sender, EventArgs e)
{
if (!captureInProgress) //Start cameras streaming
{
camera1Capture.ImageGrabbed += ProcessFrame;
camera1Capture.Start();
}
else //Stop cameras streaming
{
camera1Capture.Stop();
imageBox1.Image = null;
camera1Capture.ImageGrabbed -= ProcessFrame;
}
captureInProgress = !captureInProgress;
}
private void ProcessFrame(object sender, EventArgs arg)
{
camera1Capture.Retrieve(frame1);
imageBox1.Image = frame1;
lock (_lock)
{
if (recordingOn)
{
try
{
writer1.Write(frame1);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
private void Stop_Button_Click(object sender, EventArgs e)
{
// Doing other stuff...
lock (_lock)
{
recordingOn = false;
writer1.Dispose();
}
}

How can i update listView or labels and report to backgroundworker progress changed without using invoke?

I'm not sure if invoke is the right way to use it. It's working fine but i wonder if i should use invoke or some other way to update gui controls ? And if i want to report to more then 1 gui control ?
Now i'm updating label2 and a listView controls using invoke.
When should i use invoke and when not and then how to update this gui controls without invoking ?
private string pathtosearch;
private int countfiles;
public Form1()
{
InitializeComponent();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
DirSearch(pathtosearch);
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
}
void DirSearch(string sDir)
{
try
{
foreach (string d in Directory.GetDirectories(sDir))
{
foreach (string f in Directory.GetFiles(d))
{
Invoke((MethodInvoker)delegate
{
countfiles += 1;
label2.Text = countfiles.ToString();
});
}
DirSearch(d);
}
}
catch (System.Exception excpt)
{
Invoke((MethodInvoker)delegate
{
ListViewCostumControl.lvnf.Items.Add(excpt.Message);
});
}
}
private void button1_Click(object sender, EventArgs e)
{
DialogResult result = folderBrowserDialog1.ShowDialog();
if (result == DialogResult.OK)
{
label1.Text = folderBrowserDialog1.SelectedPath;
pathtosearch = folderBrowserDialog1.SelectedPath;
}
}
private void button2_Click(object sender, EventArgs e)
{
if (textBox1.TextLength > 0)
backgroundWorker1.RunWorkerAsync();
}
Use the ReportProgress method to send Message to UI and ProgressChanged event to handle the message.
private void backgroundWorker1_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
{
var ex = e.UserState as Exception;
if(ex!= null)
ListViewCostumControl.lvnf.Items.Add(ex.Message);
else
label2.Text = e.ProgressPercentage.ToString();;
}
void DirSearch(string sDir)
{
try
{
foreach (string d in Directory.GetDirectories(sDir))
{
foreach (string f in Directory.GetFiles(d))
backgroundWorker1.ReportProgress(countfiles++);
DirSearch(d);
}
}
catch (System.Exception excpt)
{
backgroundWorker1.ReportProgress(countfiles, excpt);
}
}
ReportProgress can overloaded with two argument: one numeric to report simple "Progress", an thesecond called UserData of type object. if you want send rich information, insert in this argument your custom object or any other existing with the required properties, and on the other side - in ProgressChanged event, "cast" it again to the appropriate type, example:
ReportProgress:
backgroundWorker1.ReportProgress(countfiles, Tuple.Create(currFile, "Copying...", timeRem));
ProgressChanged event:
var data = e.UserState as Tuple<string, string, TimeSpan>;

How to Make Camera ON / OFF with PictureBox

IDE : Visual Studio 2010 Express
Lib : Emgu CV 2.2
Level : Beginner
I've make Camera ON when Clicking PictureBox and viceversa, but it giving error :
Object reference not set to an instance of an object
Here the Event Handler :
private void pictureBoxCapture_Click(object sender, EventArgs e)
{
try
{
if (Clicked == true) //i dont know how to make it right
{
Application.Idle -= ProcessFrame;
}
else
{
Application.Idle += ProcessFrame;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Calling from :
private void ProcessFrame(object sender, EventArgs e)
{
//Cap = new Emgu.CV.Capture();
ImageFrame = Cap.QueryFrame();
pictureBoxCapture.Image = ImageFrame.ToBitmap();
}
how to set if else parameter likely, any advice?
Create a class level Boolean variable, then toggle it in your PictureBox's click event.
public partial class Form1 : Form
{
bool Clicked; //Create this Class level variable to be used in your handler
public Form1()
{
InitializeComponent();
}
private void pictureBoxCapture_Click(object sender, EventArgs e)
{
Clicked =! Clicked; //Toggle your Boolean here
try
{
if (Clicked)
{
Application.Idle -= ProcessFrame;
FaceDetect();
}
else
{
Application.Idle += ProcessFrame;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
I expect your error is not being thrown by the picturebox click event but the ProcessFrame() event. It will have the habit of firing once after you have removed the Application.Idle -= ProcessFrame; however there will be no image in the event argument to work with. Instead use this code as your ProcessFrame() event:
private void ProcessFrame(object sender, EventArgs e)
{
//Cap = new Emgu.CV.Capture();
ImageFrame = Cap.QueryFrame();
//Look for image content if null do nothing
if(ImageFrame != null)
{
pictureBoxCapture.Image = ImageFrame.ToBitmap();
//do any other operations on the image
}
}
Cheers,
Chris

How to execute function when software ended with normal close (X) or un expected error thrown

I would like to execute a function when the running application terminated via normal close way (right top X) or un expected error happened and software terminated.
How can i do this at c# 4.5 WPF application
Thank you
In your App.xaml.cs -
Override OnStartUp method and hook UnhandledException event of
Current AppDomain, it will get called whenever application was
about to close because of some unhandled exception.
Override OnExit method for normal close of application.
Create CleanUp method and call the method from above two methods.
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
AppDomain.CurrentDomain.UnhandledException += new
UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
}
private void CleanUp()
{
// Your CleanUp code goes here.
}
protected override void OnExit(ExitEventArgs e)
{
CleanUp();
base.OnExit(e);
}
void CurrentDomain_UnhandledException(object sender,
UnhandledExceptionEventArgs e)
{
CleanUp();
}
You could handle the Exit event of the app's Application subclass main instance
and the UnhandledException event of the current AppDomain instance like so:
public partial class App : Application {
public App() {
this.Exit += App_Exit;
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
}
void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) {
MessageBox.Show("Exception " + e.ExceptionObject.GetType().Name);
}
void App_Exit(object sender, ExitEventArgs e) {
MessageBox.Show("Bye bye");
}
}
Please note that given the following (simulated by clicking some buttons)
scenarios for unhandled exceptions:
which handle their respective click events like so:
private void buttonThrowNice_Click(object sender, RoutedEventArgs e) {
throw new Exception("test");
}
private void buttonStackOverflow_Click(object sender, RoutedEventArgs e) {
this.buttonStackOverflow_Click(sender, e);
}
private void buttonFailFast_Click(object sender, RoutedEventArgs e) {
Environment.FailFast("my fail fast");
}
private void buttonOutOfMemory_Click(object sender, RoutedEventArgs e) {
decimal[,,,,,] gargantuan = new decimal[int.MaxValue,int.MaxValue,int.MaxValue,int.MaxValue, int.MaxValue, int.MaxValue];
Debug.WriteLine("Making sure the compiler doesn't optimize anything: " + gargantuan.ToString());
}
The UnhandledException event of the AppDomain class only handles:
regular exceptions
the OutOfMemoryException
whereas the:
failfast
and the StackOverflow exception
are not caught.

Categories

Resources