/// <summary>
        /// Make a call into the OneNote application which is protected against recoverable errors.
        /// </summary>
        /// <param name="cmd">lambda function calling into the OneNote application object</param>
        /// <returns>Return value of the lambda function</returns>
        /// <typeparam name="Tresult">Return type of the protected lambda method</typeparam>
        /// <example>string id = onenote.ExecuteMethodProtected(o =&gt; {return o.Windows.CurrentWindow;});</example>
        private Tresult ExecuteMethodProtected <Tresult>(Func <Application, Tresult> cmd)
        {
            int retries = MAX_RETRIES;

            while (retries-- > 0)
            {
                try
                {
                    return(cmd.Invoke(_on));
                }
                catch (COMException ce)
                {
                    if ((uint)ce.ErrorCode == 0x8001010A && retries >= 0)
                    {                       // RPC_E_SERVERCALL_RETRYLATER
                        TraceLogger.Log(TraceCategory.Info(), "OneNote busy. Retrying method invocation ...");
                        Thread.Sleep(1000); // wait until COM Server becomes responsive
                    }
                    else
                    {
                        TraceLogger.Log(TraceCategory.Error(), "Unrecoverable COM exception while executing OneNote method: {0}", ce.Message);
                        TraceLogger.Log(TraceCategory.Error(), ce.StackTrace);
                        TraceLogger.Log(TraceCategory.Error(), "Re-throwing exception");
                        throw;
                    }
                }
                catch (Exception e)
                {
                    TraceLogger.Log(TraceCategory.Error(), "Exception while executing OneNote method: {0}", e.Message);
                    TraceLogger.Log(TraceCategory.Error(), e.StackTrace);
                    throw;
                }
            }
            return(default(Tresult));
        }
示例#2
0
        /// <summary>
        /// Get images for ribbon bar buttons
        /// </summary>
        /// <param name="imageName">name of image to get</param>
        /// <returns>image stream</returns>
        public IStream GetImage(string imageName)
        {
            MemoryStream mem = new MemoryStream();

            switch (imageName)
            {
            case "pageTags.png":
                Properties.Resources.tag_32x32.Save(mem, ImageFormat.Png);
                break;

            case "managePageTags.png":
                Properties.Resources.settings_32x32.Save(mem, ImageFormat.Png);
                break;

            case "findPageTags.png":
                Properties.Resources.tagSearch_32x32.Save(mem, ImageFormat.Png);
                break;

            default:
                TraceLogger.Log(TraceCategory.Warning(), "Unknown image requested: {0}", imageName);
                Properties.Resources.tag_32x32.Save(mem, ImageFormat.Png);
                break;
            }

            return(new COMReadonlyStreamAdapter(mem));
        }
        /// <summary>
        /// Show a singleton WPF dialog.
        /// </summary>
        /// <typeparam name="T">dialog type</typeparam>
        /// <typeparam name="M">view model type</typeparam>
        /// <param name="viewModelFactory">factory lambda function to create a view model</param>
        /// <returns>dialog result</returns>
        public static bool?ShowDialog <T, M>(Func <M> viewModelFactory)
            where T : System.Windows.Window, IOneNotePageWindow <M>, new()
            where M : WindowViewModelBase
        {
            bool?retval = null;
            var  thread = new Thread(() =>
            {
                try {
                    System.Windows.Window w = new T();
                    w.Closed   += (s, e) => w.Dispatcher.InvokeShutdown();
                    w.Topmost   = true;
                    M viewmodel = viewModelFactory();
                    ((IOneNotePageWindow <M>)w).ViewModel = viewmodel;
                    var helper = new WindowInteropHelper(w)
                    {
                        Owner = (IntPtr)viewmodel.OneNoteApp.CurrentWindow.WindowHandle
                    };
                    BringWindowIntoView(w);
                    retval = w.ShowDialog();
                    Trace.Flush();
                } catch (Exception ex) {
                    TraceLogger.Log(TraceCategory.Error(), "Exception while creating dialog: {0}", ex);
                    TraceLogger.ShowGenericErrorBox(Properties.Resources.TagEditor_Error_WindowCreation, ex);
                }
            });

            thread.SetApartmentState(ApartmentState.STA);
            thread.IsBackground = true;
            thread.Start();

            thread.Join();
            return(retval);
        }
        /// <summary>
        /// Create a new instance of a OneNote proxy.
        /// </summary>
        /// <param name="onenote">OneNote application object</param>
        internal OneNoteProxy(Application onenote)
        {
            _on = onenote;

            TaggingService = new BackgroundTagger(this);
            TaggingService.Run();
            TraceLogger.Log(TraceCategory.Info(), "OneNote application proxy constructed successfully");
            TraceLogger.Flush();
        }
        /// <summary>
        /// Find pages by full text search
        /// </summary>
        /// <param name="query">  query string</param>
        /// <param name="scopeID">
        /// OneNote id of the scope to search for pages. This is the element ID of a
        /// notebook, section group, or section. If given as null or empty string scope is
        /// the entire set of notebooks open in OneNote.
        /// </param>
        /// <returns>XML page descriptors</returns>
        public XDocument FindPages(string scopeID, string query)
        {
            TraceLogger.Log(TraceCategory.Info(), "query={0}; Scope = {1}", query, scopeID);

            return(ExecuteMethodProtected <XDocument>(o =>
            {
                string outXml;
                o.FindPages(scopeID, query, out outXml, false, fDisplay: false, xsSchema: OneNoteSchema);
                return XDocument.Parse(outXml);
            }));
        }
        /// <summary>
        /// Get the XML descriptor of nodes in the OneNote hierarchy
        /// </summary>
        /// <remarks>Only basic information (as of OneNote 2010) is returned.</remarks>
        /// <param name="nodeID">id of the starting node</param>
        /// <param name="scope"> scope of the nodes to return</param>
        /// <returns>XML document describing the nodes in the OneNote hierarchy</returns>
        /// <exception cref="COMException">Call to OneNote failed</exception>
        public XDocument GetHierarchy(string nodeID, HierarchyScope scope)
        {
            TraceLogger.Log(TraceCategory.Info(), "Start Node = {0}; Scope = {1}", nodeID, scope);

            return(ExecuteMethodProtected <XDocument>(o =>
            {
                string outXml;
                o.GetHierarchy(nodeID, scope, out outXml, OneNoteSchema);

                return XDocument.Parse(outXml);
            }));
        }
        /// <summary>
        /// Find OneNote pages which have meta-data with a given key.
        /// </summary>
        /// <param name="scopeID">
        /// search scope. The id of a node in the hierarchy (notebook, section group, or
        /// section) below which to search for content. If null or empty string, the search
        /// scope is the entire set of notebooks open in OneNote. for the search.
        /// </param>
        /// <param name="metadataKey">Key (name) of the meta-data</param>
        /// <returns>page descriptors of pages with the requested meta-data</returns>
        public XDocument FindPagesByMetadata(string scopeID, string metadataKey)
        {
            TraceLogger.Log(TraceCategory.Info(), "Scope = {0}; metaKey = {1}", scopeID, metadataKey);

            return(ExecuteMethodProtected <XDocument>(o =>
            {
                string outXml;
                o.FindMeta(scopeID, metadataKey, out outXml, false, OneNoteSchema);

                return XDocument.Parse(outXml);
            }));
        }
示例#8
0
        /// <summary>
        /// Show a WPF window.
        /// </summary>
        /// <typeparam name="W">window type</typeparam>
        /// <typeparam name="M">view model type</typeparam>
        /// <param name="viewModelFactory">factory method to generate the view model in the UI thread of the WPF window</param>
        public void Show <W, M>(Func <M> viewModelFactory)
            where W : System.Windows.Window, IOneNotePageWindow <M>, new()
            where M : WindowViewModelBase
        {
            var thread = new Thread(() =>
            {
                try
                {
                    lock (_SingletonWindows)
                    {
                        System.Windows.Window w;
                        if (_SingletonWindows.TryGetValue(typeof(W), out w))
                        {
                            w.Dispatcher.Invoke(() =>
                            {
                                w.WindowState = WindowState.Normal;
                                BringWindowIntoView(w);
                            });
                            return;
                        }
                        w           = new W();
                        w.Closing  += (o, e) => UnregisterWindow(typeof(W));
                        w.Closed   += (s, e) => w.Dispatcher.InvokeShutdown();
                        M viewmodel = viewModelFactory();
                        ((IOneNotePageWindow <M>)w).ViewModel = viewmodel;
                        var helper = new WindowInteropHelper(w)
                        {
                            Owner = (IntPtr)viewmodel.OneNoteApp.CurrentWindow.WindowHandle
                        };

                        w.Show();
                        BringWindowIntoView(w);
                        _SingletonWindows.Add(typeof(W), w);
                    }
                    // Turn this thread into an UI thread
                    System.Windows.Threading.Dispatcher.Run();
                }
                catch (ThreadAbortException ta)
                {
                    TraceLogger.Log(TraceCategory.Warning(), "Window Thread aborted: {0}", ta);
                }
                catch (Exception ex)
                {
                    TraceLogger.Log(TraceCategory.Error(), "Exception while creating dialog: {0}", ex);
                    TraceLogger.ShowGenericErrorBox(Properties.Resources.TagEditor_Error_WindowCreation, ex);
                }
            });

            thread.SetApartmentState(ApartmentState.STA);
            thread.IsBackground = true;
            thread.Start();
        }
示例#9
0
 /// <summary>
 /// Occurs whenever an add-in loads.
 /// </summary>
 /// <param name="custom">
 /// An empty array that you can use to pass host-specific data for use when the
 /// add-in loads.
 /// </param>
 public void OnStartupComplete(ref Array custom)
 {
     TraceLogger.Log(TraceCategory.Info(), "Startup Arguments '{0}'", custom);
     try {
         XMLSchema s = _onProxy.OneNoteSchema; // cache the schema
     } catch (Exception ex) {
         TraceLogger.Log(TraceCategory.Error(), "{0} initialization failed: {1}", Properties.Resources.TaggingKit_About_Appname, ex);
         TraceLogger.Flush();
         throw;
     }
     TraceLogger.Log(TraceCategory.Info(), "{0} initialization complete!", Properties.Resources.TaggingKit_About_Appname);
     TraceLogger.Flush();
 }
示例#10
0
        /// <summary>
        /// Handle the connection to the OneNote application.
        /// </summary>
        /// <param name="app">        The instance of OneNote which added the add-in</param>
        /// <param name="ConnectMode">
        /// Enumeration value that indicates the way the add-in was loaded.
        /// </param>
        /// <param name="AddInInst">  Reference to the add-in's own instance</param>
        /// <param name="custom">
        /// An empty array that you can use to pass host-specific data for use in the add-in
        /// </param>
        public void OnConnection(object app, ext_ConnectMode ConnectMode, object AddInInst, ref Array custom)
        {
            try {
                TraceLogger.Log(TraceCategory.Info(), "Connection mode '{0}'", ConnectMode);

                _onProxy       = new OneNoteProxy(app as Microsoft.Office.Interop.OneNote.Application);
                _dialogmanager = new AddInDialogManager();
                TraceLogger.Flush();
            } catch (Exception ex) {
                TraceLogger.Log(TraceCategory.Error(), "Connecting {0} failed: {1}", Properties.Resources.TaggingKit_About_Appname, ex);
                TraceLogger.Flush();
                throw;
            }
        }
示例#11
0
        /// <summary>
        /// Occurs whenever OneNote shuts down while an add-in is running.
        /// </summary>
        /// <param name="custom">
        /// An empty array that you can use to pass host-specific data for use in the add-in.
        /// </param>
        public void OnBeginShutdown(ref Array custom)
        {
            TraceLogger.Log(TraceCategory.Info(), "Beginning {0} shutdown; Arguments '{1}'", Properties.Resources.TaggingKit_About_Appname, custom);
            if (_dialogmanager != null)
            {
                _dialogmanager.Dispose();
                _dialogmanager = null;
            }

            if (_onProxy != null)
            {
                _onProxy.Dispose();
                _onProxy = null;
            }
        }
示例#12
0
        /// <summary>
        /// log a message.
        /// </summary>
        /// <param name="category">logging category</param>
        /// <param name="message"> logging message</param>
        /// <param name="args">    parameters for the logging message</param>
        internal static void Log(TraceCategory category, string message, params object[] args)
        {
#if TRACE
            Trace.Write(category.CallerName, category.Category);
            Trace.Write(" (");
            Trace.Write(category.Line);
            Trace.Write(") | ");
            try
            {
                Trace.WriteLine(string.Format(message, args));
            }
            catch (Exception ex)
            {
                Log(TraceCategory.Error(), "Logging failed {0}", ex);
            }
#endif //TRACE
        }
示例#13
0
        /// <summary>
        /// Show an error box for an exception.
        /// </summary>
        /// <param name="message">Message to describe the failing operation</param>
        /// <param name="ex">     exception</param>
        internal static void ShowGenericErrorBox(string message, Exception ex)
        {
            TraceLogger.Log(TraceCategory.Error(), "{0}: {1}", message, ex);
            Trace.Flush();
            MessageBoxResult result = MessageBox.Show(string.Format(Properties.Resources.TaggingKit_ErrorBox_GenericSevereError,
                                                                    message,
                                                                    ex.Message,
                                                                    TraceLogger.LogFile),
                                                      string.Format(Properties.Resources.TaggingKit_ErrorBox_Title,
                                                                    Properties.Resources.TaggingKit_About_Appname),
                                                      MessageBoxButton.OKCancel,
                                                      MessageBoxImage.Error);

            if (result == MessageBoxResult.OK)
            { // browse to the troubleshooting tips
                string wikipage = "Troubleshooting-Tips";

                COMException ce = ex as COMException;
                if (ce != null)
                {
                    switch ((uint)ce.ErrorCode)
                    {
                    case 0x80042019:
                        wikipage = "0x80042019";
                        break;

                    case 0x8004200C:
                        wikipage = "0x8004200C";
                        break;
                    }
                }
                try
                {
                    Process.Start(new ProcessStartInfo(string.Format(Properties.Resources.TaggingKit_Wiki_Page, wikipage)));
                }
                catch (Exception ex1)
                {
                    TraceLogger.Log(TraceCategory.Error(), "Failed to open web browser: {0}", ex1);
                }
            }
        }
 public void Dispose()
 {
     if (!_disposed)
     {
         _disposed = true;
         // We do not lock the window collection because closing a window also
         // attempts to lock that collection.
         foreach (System.Windows.Window w in _SingletonWindows.Values.ToArray())
         {
             try {
                 w.Dispatcher.Invoke(() =>
                 {
                     TraceLogger.Log(TraceCategory.Info(), "Closing Window: {0}", w.Title);
                     w.Close();
                 });
             } catch (Exception e) {
                 TraceLogger.Log(TraceCategory.Error(), "Closing window failed: {0}", e);
             }
         }
     }
 }
示例#15
0
 /// <summary>
 /// handle disconnection of the OneNote application.
 /// </summary>
 /// <param name="RemoveMode">
 /// Enumeration value that informs an add-in why it was unloaded
 /// </param>
 /// <param name="custom">
 /// An empty array that you can use to pass host-specific data for use after the
 /// add-in unloads.
 /// </param>
 public void OnDisconnection(ext_DisconnectMode RemoveMode, ref Array custom)
 {
     TraceLogger.Log(TraceCategory.Info(), "Disconnecting; mode='{0}'; Arguments: '{1}'", RemoveMode, custom);
     if (_dialogmanager != null)
     {
         _dialogmanager.Dispose();
         _dialogmanager = null;
     }
     Trace.Flush();
     GC.Collect();
     GC.WaitForPendingFinalizers();
     if (RemoveMode == ext_DisconnectMode.ext_dm_HostShutdown ||
         RemoveMode == ext_DisconnectMode.ext_dm_UserClosed)
     {
         // a dirty hack to make sure the ddlhost shuts down after an exception
         // occurred. This is necessary to allow the add-in to be loaded
         // successfully next time OneNote starts (a zombie dllhost would prevent that)
         TraceLogger.Log(TraceCategory.Info(), "Forcing COM Surrogate shutdown");
         Trace.Flush();
         Environment.Exit(0);
     }
 }
示例#16
0
        /// <summary>
        /// register the logging utility with the tracing system.
        /// </summary>
        internal static void Register()
        {
            FileStream log = new FileStream(LogFile, FileMode.OpenOrCreate);
            // Creates the new trace listener.
            TextWriterTraceListener listener = new TextWriterTraceListener(log);

            Trace.Listeners.Add(listener);

#if DEBUG
            string config = "Debug";
#else
            string config = "Release";
#endif

            Log(TraceCategory.Info(),
                "{0} logging activated.\r\n\tAddin-Version: {1}\r\n\t.net Framework Version: {2}\r\n\tConfiguration: {3}",
                Properties.Resources.TaggingKit_About_Appname,
                Assembly.GetExecutingAssembly().GetName().Version,
                Environment.Version,
                config
                );
            Flush();
        }
示例#17
0
 /// <summary>
 /// Action to open the "Related Pages" UI
 /// </summary>
 /// <param name="ribbon">OneNote ribbon bar</param>
 public void relatedPages(IRibbonControl ribbon)
 {
     TraceLogger.Log(TraceCategory.Info(), "Show related pages tracer");
     _dialogmanager.Show <RelatedPages, RelatedPagesModel>(() => new RelatedPagesModel(_onProxy));
 }
示例#18
0
 /// <summary>
 /// Occurs whenever an add-in is loaded or unloaded.
 /// </summary>
 /// <param name="custom">
 /// An empty array that you can use to pass host-specific data for use in the add-in.
 /// </param>
 public void OnAddInsUpdate(ref Array custom)
 {
     TraceLogger.Log(TraceCategory.Info(), "{0} update initiated; Arguments '{1}'", Properties.Resources.TaggingKit_About_Appname, custom);
 }
示例#19
0
 /// <summary>
 /// Action to open a tag management dialog.
 /// </summary>
 /// <param name="ribbon"></param>
 public void manageTags(IRibbonControl ribbon)
 {
     TraceLogger.Log(TraceCategory.Info(), "Show settings editor");
     AddInDialogManager.ShowDialog <TagManager, TagManagerModel>(() => new TagManagerModel(_onProxy));
 }
示例#20
0
 /// <summary>
 /// Action to open the search tags UI
 /// </summary>
 /// <param name="ribbon">OneNote ribbon bar</param>
 public void findTags(IRibbonControl ribbon)
 {
     TraceLogger.Log(TraceCategory.Info(), "Show tag finder");
     _dialogmanager.Show <FindTaggedPages, FindTaggedPagesModel>(() => new FindTaggedPagesModel(_onProxy));
 }
示例#21
0
 /// <summary>
 /// Action to open a tag editor dialog.
 /// </summary>
 /// <remarks>Opens the page tag editor</remarks>
 /// <param name="ribbon">OneNote ribbon bar</param>
 public void editTags(IRibbonControl ribbon)
 {
     TraceLogger.Log(TraceCategory.Info(), "Show tag editor");
     _dialogmanager.Show <TagEditor, TagEditorModel>(() => new TagEditorModel(_onProxy));
 }
示例#22
0
 /// <summary>
 /// Get the ribbon definition of this add-in
 /// </summary>
 /// <param name="RibbonID">identifier of the ribbon</param>
 /// <returns>ribbon definition XML as string</returns>
 public string GetCustomUI(string RibbonID)
 {
     TraceLogger.Log(TraceCategory.Info(), "UI configuration requested: {0}", RibbonID);
     return(Properties.Resources.ribbon);
 }