首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在关闭OneNote互操作控制台应用程序时干净地关闭C#

如何在关闭OneNote互操作控制台应用程序时干净地关闭C#
EN

Stack Overflow用户
提问于 2022-02-12 18:57:26
回答 1查看 150关注 0票数 1

我对C#和Visual比较陌生,对Microsoft.Office.Interop.OneNote完全陌生。我已经开始了一个控制台应用程序的工作,它使用this answer中的代码作为起点,这是对关于writing to a OneNote app using C# and interop的一个问题的回答。我的应用程序确实成功地从OneNote笔记本中检索了内容,但我不知道如何关闭该应用程序,使OneNote完全关闭。每当我在Visual中运行该应用程序,然后关闭控制台时,下次尝试打开OneNote时,我就会收到一条消息:“对不起。OneNote正在清理上次打开的程序。请稍候。”大约30秒后,后面跟着一条消息:“看起来OneNote现在启动有问题。如果您一直看到这条消息,请重新启动计算机并再次启动OneNote。对不起。”

在重新启动或清空C:\user%userprofile%\appdata\local\temp的内容之前,不可能再次打开OneNote。

使用什么适当的代码来彻底关闭OneNote,以及/或我应该如何关闭Visual中的应用程序?(就像我说的,我是个菜鸟。)

这是我的代码:

代码语言:javascript
复制
using System;
using Word = Microsoft.Office.Interop.Word;
using OneNote = Microsoft.Office.Interop.OneNote;
using System.Runtime.InteropServices;
using System.Xml.Linq;
using System.Linq;

namespace OneNote_to_Word
{
    class Program
    {
        static OneNote.Application onenoteApp = new OneNote.Application();
        static XNamespace ns = null;

        static void Main(string[] args)
        {
            GetNamespace();
            string notebookId = GetObjectId(null, OneNote.HierarchyScope.hsNotebooks, "Notebook Name");
            string sectionId = GetObjectId(notebookId, OneNote.HierarchyScope.hsSections, "done");
            string firstPageId = GetObjectId(sectionId, OneNote.HierarchyScope.hsPages, "140506");
            GetPageContent(firstPageId);
            Console.Read();
        }
        static void GetNamespace()
        {
            string xml;

            onenoteApp.GetHierarchy(null, OneNote.HierarchyScope.hsNotebooks, out xml);
            var doc = XDocument.Parse(xml);
            ns = doc.Root.Name.Namespace;
        }

        static string GetObjectId(string parentId, OneNote.HierarchyScope scope, string objectName)
        {
            string xml;
            onenoteApp.GetHierarchy(parentId, scope, out xml);

            var doc = XDocument.Parse(xml);
            var nodeName = "";

            switch (scope)
            {
                case (OneNote.HierarchyScope.hsNotebooks): nodeName = "Notebook"; break;
                case (OneNote.HierarchyScope.hsPages): nodeName = "Page"; break;
                case (OneNote.HierarchyScope.hsSections): nodeName = "Section"; break;
                default:
                    return null;
            }

            var node = doc.Descendants(ns + nodeName).Where(n => n.Attribute("name").Value == objectName).FirstOrDefault();

            return node.Attribute("ID").Value;
        }
        static string GetPageContent(string pageId)
        {
            string xml;
            onenoteApp.GetPageContent(pageId, out xml, OneNote.PageInfo.piAll);
            var doc = XDocument.Parse(xml);
            var outLine = doc.Descendants(ns + "Outline").First();
            var content = outLine.Descendants(ns + "T").First();
            string contentVal = content.Value;
            //content.Value = "modified";
            //onenoteApp.UpdatePageContent(doc.ToString());
            Console.WriteLine(contentVal);
            return null;
        }
    }
}
EN

回答 1

Stack Overflow用户

发布于 2022-02-12 21:09:27

至少对于.NET < 5,我需要在main()末尾添加以下行:

代码语言:javascript
复制
    Marshal.FinalReleaseComObject(onenoteApp);
    onenoteApp = null;
    GC.Collect(); // Start .NET CLR Garbage Collection
    GC.WaitForPendingFinalizers(); // Wait for Garbage Collection to finish

所以main()现在看起来如下:

代码语言:javascript
复制
static void Main(string[] args)
    {
        GetNamespace();
        string notebookId = GetObjectId(null, OneNote.HierarchyScope.hsNotebooks, "My Notebook");
        string sectionId = GetObjectId(notebookId, OneNote.HierarchyScope.hsSections, "done");
        string firstPageId = GetObjectId(sectionId, OneNote.HierarchyScope.hsPages, "140506");
        GetPageContent(firstPageId);
        Marshal.FinalReleaseComObject(onenoteApp);
        onenoteApp = null;
        GC.Collect(); // Start .NET CLR Garbage Collection
        GC.WaitForPendingFinalizers(); // Wait for Garbage Collection to finish
    }

然而,在.NET 5中,当我尝试使用Marshal.FinalReleaseComObject()时,Visual抱怨说“这个调用站点在所有平台上都是可访问的,‘Marshal.FinalReleaseComObject(对象)’只支持在:‘windows’上”。可以通过将这一行放在包含类main() (cf )的上方来解决这个问题。this answer):

代码语言:javascript
复制
[System.Runtime.Versioning.SupportedOSPlatform("windows")]
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71094917

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档