Automatic email send/receive in Outlook - outlook

Is there a way to set up Outlook (2013) to automatically send/receive emails when it is activated?
What you can do now is to intruct Outlook to periodically check the emails, and of course, it checks the emails at start time. That's fine, I am a fan... but most of the time Outlook runs minimized. Once I restore it (that is, bring Outlook in front), I would like it to perform an automatic sync, equivalent to pressing the Send/Receive Folders.
I agree this is not a critical issue at all, not even close, but for me it would make sense.

You could try using SendKeys and send F9 hotkey which performs the Send/Receive action. I would probably just do this keystroke myself, but you could programmatically attach to the Explorer.Activate event and generate this event as well. You can also add a debounce to control the frequency as to not overwhelm your Exchange server.
DateTime lastRun = DateTime.Now; // debouce control
void ThisAddIn_Startup(object sender, System.EventArgs e)
{
Application.Explorers.NewExplorer += new Outlook.ExplorersEvents_NewExplorerEventHandler(explorers_NewExplorer);
}
void explorers_NewExplorer(Outlook.Explorer explorer)
{
((Outlook.ExplorerEvents_10_Event)explorer).Activate += new Outlook.ExplorerEvents_10_ActivateEventHandler(ExplorerWrapper_Activate);
}
void ExplorerWrapper_Activate()
{
if ((DateTime.Now - lastRun).TotalMilliseconds > 500) // trigger limit 500ms
{
lastRun = DateTime.Now;
System.Windows.Forms.SendKeys.Send("{F9}"); // hotkey to send/receive
}
}

Related

Outlook VSTO AddIn How to avoid RaceOnRCWCleanup

What I am trying to achieve is to also handle drag and drop events on the calendar properly using the AppProperty Change event on the Inspector:
I update the currentAppointmentItem whenever the user interacts with the interface (Explorer.SelectionChange, NewInspector, CloseInspector, etc.)
I update the currentInspector whenever the user interacts with the interface (SelectionChange, NewInspector, CloseInspector)
Update means that I try to set/unset the event handlers appropriately and to Marshal.ReleaseComObject accordingly. Finally to null the reference.
But when the user just clicks on an AppointmentItem in the calendar no Inspector window is created. Thus I wouldn't be able to catch AppPropertyChange Events. So I decided to call GetInspector on the selected AppointmentItem in case it is not null. I try to use this to receive changes on the AppProperty Event so I can handle drag and drop events on the calendar properly
The problem: From the Microsoft documentation I understand whenever you lose a reference to currentAppointmentItem you should also use Marshal.ReleaseComObject otherwise you risk other problems.
Now I experience exceptions which I cannot catch: RaceOnRCWCleanup ... it seems that I try to release a COM object which is still in use (probably by Outlook). How can I avoid that? Is it correct to Marshal.ReleaseComObject(currentAppointmentItem)
I registered on the SelectionChange Event on the Outlook.Explorer. In there I try to register the currentAppointment with:
[...]
log.Info("Selection_Change");
if (currentExplorer == null)
{
return;
}
try
{
log.Info("Selection_Change: " + currentExplorer.Caption);
Outlook.MAPIFolder selectedFolder = currentExplorer.CurrentFolder;
if (currentExplorer.Selection.Count > 0)
{
Object selObject = currentExplorer.Selection[1];
if (selObject is Outlook.AppointmentItem)
{
currentAppointmentItem = (Outlook.AppointmentItem)selObject;
Inspectors_NewInspector(currentAppointmentItem.GetInspector);
}
[...]
Please Note: INspectors_NewInspector is also called on the Inspectors Collection.
The code of NewInspector is like
void Inspectors_NewInspector(Microsoft.Office.Interop.Outlook.Inspector Inspector)
{
try
{
log.Info("Inspectors_NewInspector");
// This function (apparently) gets kicked off whenever a user opens a new or existing item
// in Outlook (Calendar appointment, Email, etc).
// We can intercept it, modify it's properties, before letting our Ribbon know about its existance.
//
if (Inspector != null)
{
log.Info("Inspectors_NewInspector: " + Inspector.Caption);
unregisterCurrentInspector();
currentInspector = Inspector;
object item = Inspector.CurrentItem;
if (item == null)
return;
if (!(item is Outlook.AppointmentItem))
return;
unregisterCurrentAppointmentItem();
currentAppointmentItem = (Outlook.AppointmentItem)item;
currentAppointmentItem.PropertyChange += AppPropertyChanged; // Handle situations where the
// user tries to convert an appointment w/ an agreedo protocol to a recurring appointment.
// This needs to be avoided .
currentAppointmentItem.CustomPropertyChange += AppPropertyChanged;
}
((Microsoft.Office.Interop.Outlook.InspectorEvents_10_Event)Inspector).Close += Inspector_Close;
} catch (Exception ex)
{
log.Error(ex.Message);
}
}
the unregisterCurrentApppointmentItem :
private void unregisterCurrentAppointmentItem()
{
try
{
log.Info("unregisterCurrentAppointmentItem");
if (currentAppointmentItem != null)
{
currentAppointmentItem.PropertyChange -= AppPropertyChanged; // Handle situations where the
currentAppointmentItem.CustomPropertyChange -= AppPropertyChanged;
Marshal.ReleaseComObject(currentAppointmentItem);
currentAppointmentItem = null;
}
} catch (Exception ex)
{
log.Error(ex.Message);
}
}
the unregisterCurrentInspector:
private void unregisterCurrentInspector()
{
log.Info("unregisterCurrentInspector");
if (currentInspector != null)
{
((Microsoft.Office.Interop.Outlook.InspectorEvents_10_Event)currentInspector).Close -= Inspector_Close;
Marshal.ReleaseComObject(currentInspector);
currentInspector = null;
}
}
Any advice on this?
What I already tried / taken into account:
Outlook Addin: Moving Appointment in Calendar does not reflect new date/time in AppointmentItem (catch Calendar.ItemChange)
VSTO Outlook Plugin: Cannot get AppointmentItem in Item_Change event when recurring appointment is dragged and dropped by user
First of all, there is no need to simulate the NewInspector event. Instead, you need to set up event handlers correctly. It seems you just need to implement an inspector or explorer wrappers. See Implement a wrapper for inspectors and track item-level events in each inspector for more information.
it seems that I try to release a COM object which is still in use (probably by Outlook). How can I avoid that? Is it correct to Marshal.ReleaseComObject(currentAppointmentItem)
Yes, it is. But you should really use this method against objects retrieved in your code by calling properties and methods. You SHOULD NOT release objects passed as parameters by the Office applications. Take a look a the When to release COM objects in Office add-ins developed in .NET article which explains possible pitfalls and give answers to the most widely spread questions.
Why do you even need the Inspector object? Are you only using the Inspector.Close event?
Use AppointmentItem.Close / Write events.

Outlook VSTO Handling SelectionChange correctly (currently doubleclick crashes Addin)

From what I understand you need to track Activation and Deactivation of the Explorers. During activation, you need to add SelectionChange event handlers for the current explorer.
This seems to work perfectly for single clicks on AppointmentItems. But it crashes the Addin when double-clicking on an appointment series and selecting a single Appointment.
Here is the source:
On class level
private Outlook.Explorer currentExplorer = null;
private Outlook.AppointmentItem currentAppointmentItem = null;
within Startup:
currentExplorer = this.Application.ActiveExplorer();
((Outlook.ExplorerEvents_10_Event)currentExplorer).Activate +=
new Outlook.ExplorerEvents_10_ActivateEventHandler(
Explorer_Activate);
currentExplorer.Deactivate += new
Outlook.ExplorerEvents_10_DeactivateEventHandler(
Explorer_Deactivate);
The event handlers:
void Explorer_Activate()
{
currentExplorer.SelectionChange += new Outlook.ExplorerEvents_10_SelectionChangeEventHandler(Selection_Change);
}
void Explorer_Deactivate()
{
currentExplorer.SelectionChange -= new Outlook.ExplorerEvents_10_SelectionChangeEventHandler(Selection_Change); ;
}
private void Close_Explorer()
{
}
private void Selection_Change()
{
Outlook.MAPIFolder selectedFolder = currentExplorer.CurrentFolder;
if (currentExplorer.Selection.Count > 0)
{
Object selObject = currentExplorer.Selection[1];
if (selObject is Outlook.AppointmentItem)
{
currentAppointmentItem = (Outlook.AppointmentItem)selObject;
}
else
{
currentAppointmentItem = null;
}
}
}
What am I overlooking? Is the form of deregistering a problem?
Try to add try/catch blocks to the event handlers. The Outlook object model can give you unpredictable results sometimes. It is worth adding them and find where an exception is thrown.
currentExplorer.Selection.Count
Also, you may subscribe to the SelectionChange event in the NewExplorer event and don't switch between explorers when they are activated or deactivated. The event is fired whenever a new explorer window is opened, either as a result of user action or through program code.
The only thing which I added was a handler for NewInspector and InspectorClose events along with Marshal.ReleaseComObject(). The only thing which I can imagine that double clicking while debugging I got in some kind of race condition (because double clicking also triggers the Selection_Change event). But this is only a guess.
You do not need to add and remove event handlers as an explorer is activated / deactivated. Are you trying to support multiple explorers? In that case, create a wrapper class that hold the Explorer object as it member and uses its methods as event handlers.

Xamarin Forms Map Viewable Area event handler

I have a Xamarin form map on my screen and I'm using PropertyChanged event to retrieve geolocation information from my server and display the proper pins on screen.
While coding the solution I noticed the PropertyChanged event is triggered multiple times (up to 10 times) with a single zoom or drag action on the map. This causes unnecessary calls to server which I want to avoid.
Ideally I want to make only one call to server when the final PropertyChanged event is called but I cant's find an easy solution to implement this.
At this point I've added a refresh button to my page that becomes enabled when a PropertyChanged event happens and I disable it after user uses the button.
Obviously this fixed the too many calls to server but made the solution manual.
I was wondering if there is a more elegant way to make the server call but do it automatically.
Thanks in advance.
I just test the PropertyChanged event on iOS side and it just triggered one time with a single zoom or drag action on the map.
While if it really triggered multiple times, you can use a timer to call the server when the final PropertyChanged event is called, for example:
public partial class MapPage : ContentPage
{
Timer aTimer;
public MapPage()
{
InitializeComponent();
customMap.PropertyChanged += CustomMap_PropertyChanged;
}
private void CustomMap_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (aTimer != null)
{
aTimer.Enabled = false;
aTimer.Stop();
aTimer.Close();
}
aTimer = new Timer();
aTimer.Interval = 1000;
aTimer.Enabled = true;
aTimer.Elapsed += ATimer_Elapsed;
aTimer.Start();
}
private void ATimer_Elapsed(object sender, ElapsedEventArgs e)
{
aTimer.Stop();
//do web request
Console.WriteLine(sender);
Console.WriteLine("CustomMap_PropertyChanged");
}
}
In the above code, I set the Interval = 1 second, that means in 1 second, whatever how many times PropertyChanged triggered, only the last call will trigger the ATimer_Elapsed function.
The Interval can be set to any value depending on your requirement.

Inconsistent Outlook Addin Event Firing

On my development machine I have the FormInitializing and FormShowing events firing before RibbonLoad. I created a setup package in VS 2010 and installed on a vanilla Windows 7 Ultimate with Outlook 2010 installed.
The addin wasn't appearing on my meeting request form. So I setup remote debugger and to my astonishment the RibbonLoad is firing before the two form events mentioned above. A null exception is being throw b\c the code in the RibbonLoad relies on the FormRegion already being loaded. Can anyone offer any insight?
There is no defined order for certain Outlook events - the Ribbon UI and the Inspector UI are completely different components, despite them both being display in the same window. The Outlook runtime may trigger Ribbon and Inspector events in different orders. It would be your job to synchronize the two events (RibbonLoad and FormInitializing) if you need some initialization done. You cannot assume that the ordering will always be the same.
I notice this same behavior when ThisAddIn.Startup fires before ThisAddIn.CreateRibbonExtensibilityObject, but sometimes after depending on how Outlook triggers the sequencing. You can just use a static variable with sync locking to ensure your initialization code is only triggered once.
Here is an example I used to synchronize the Startup event with the RibbonLoad event:
public partial class ThisAddIn
{
static bool formInitialized = false;
static readonly object padLock = new Object();
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
lock(padLock) { if (!formInitialized ) { InitializeForm(); } }
// startup code
}
private void InitializeForm()
{
// init code
formInitialized = true;
}
protected override IRibbonExtensibility CreateRibbonExtensibilityObject()
{
lock(padLock) { if (!formInitialized) InitializeForm(); }
// Create ribbon UI
}
}

Outlook Add-In - Enable/Disable Button during Runtime/from Code

Initial Situation:
We are developing an Add-in for Outlook 2010 in C# with VS.NET 2010 based on Framework 4.0, VSTO, DevExpress WinForm Controls. In Designer we have a Ribbon with a RibbonTab, then a RibbonGroup then a RibbonButton. We're consuming WebServices from within this Outlook Add-in.
Objective:
We need to enable/disable the RibbonButtons when the WebService is available/unavailable (from/out of the code)
we've found the following links:
Links
Ribbon Object Model Overview: http://msdn.microsoft.com/en-us/library/bb608623.aspx
Ribbon Overview: http://msdn.microsoft.com/en-us/library/bb386097.aspx
Walkthrough: Updating the Controls on a Ribbon at Run Time: http://msdn.microsoft.com/en-us/library/bb608628.aspx
After hours of trying to figure out how to implement this we deciced to post/ask this question here on SO. Does anybody have a sample code? We tried the IRibbonExtensibility and CreateRibbonExtensibilityObject => we added the RibbonTab, Group and Button and added a subscription to the Click Event => The Event is fired but not handled (in button_Click(...) => System.Diagnostics.Debugger.Break() is not breaking the code execution)
Thanks!
Christian
You'll want to invalidate the Ribbon at a fairly frequent rate in order to refresh the visibility of each tab/button. You can do this by subscribing to the Click event (as you've done) and then calling RibbonObject.Invalidate();. Then add a getEnabled="yourTestFunction" parameter to each button, with public bool yourTestFunction(Office.IRibbonControl control) (Defined in the Ribbon.cs file) returning whether the web service is available or not.
Keep in mind if the web service is down, each click could hang your application for the amount of time you set on your timeout in the web service check
Edit:
Just realized the _Click event isn't mapped in the Excel COM library, so here's a bit of code that will run each time the cell selection is changed (not as frequent as every click, but hopefully good enough).
ThisAddIn.cs:
public static Excel.Application e_application;
public static Office.IRibbonUI e_ribbon;
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
e_application = this.Application;
e_application.SheetSelectionChange += new Excel.AppEvents_SheetSelectionChangeEventHandler(e_application_SheetSelectionChange);
}
void e_application_SheetSelectionChange(object Sh, Excel.Range Target)
{
e_ribbon.Invalidate();
}
private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
{
e_application.SheetSelectionChange -= new Excel.AppEvents_SheetSelectionChangeEventHandler(e_application_SheetSelectionChange);
e_application = null;
}
Ribbon1.cs:
public void Ribbon_Load(Office.IRibbonUI ribbonUI)
{
this.ribbon = ribbonUI;
ThisAddIn.e_ribbon = ribbonUI; //Add this line
}
and
public bool getEnabledTest(Office.IRibbonControl control)
{
//Whatever you use to test your Web Service
//return false;
}
Ribbon1.xml:
<button id="WebService" label="Use The Web Service" onAction="executeWebService" getEnabled="getEnabledTest" />
The following article titled Adding Custom Dynamic Menus to the Office Fluent User Interface will point you in the right direction.
The below is an example of a dynamically created menu, you can modify the tutorial to fit your particular need.
ok, thanks for the tips. Finally i solved it like this:
i declared a static ribbon object like:
public static RibbonIet ribbon {get; set; }
in the load event of the Ribbon i assign the Ribbon (this) like:
Session.Common.ribbon = this;
now i can control the RibbonButton like:
Session.Common.ribbon.buttonCreateIncident.Enabled = true;
Since the webService call is running in a seperate thread, i had to use a MethodInvoker to change enable/disable the buttons. it goes like this:
If (InvokeRequired)
{
Invoke(new MethodInvoker(() => Session.Common.ribbon.buttonCreateIncident.Enabled = true));
}
maybe this is of help for someone else.

Resources