问题
I'm trying to follow links in a OneNote page to get the content of the linked page via the OneNote API. The HTML link looks like this: (removed some text)
onenote:..\Partners\Cloud.one#Integrated%20Asset%20Manager%20(IAM)§ion-id={DEDAE503-E375-49F2-B93D-F38B4121C70C}&page-id={7BF5121A-0B6C-4B08-9EAE-8FF2030257EE}&end&base-path={full-path-here}
Trying to do OneNoteApplication.GetPageContent with the linked page-id throws an error for page not found. If I do a GetHierarchy the ID's for the page look very different:
{A98F0819-709E-016D-37A3-45218AD83E06}{1}{E19545547677840986606520149590302900659675241}
Has anyone found a way to convert between the different types of IDs or to use the HTML style ID to navigate within the API?
回答1:
I agree they don't match up, using OMSpy on one of my pages:
From the page:
<snip>section-id={3261B7D6-C082-4CF3-9A1A-32095643EB84}&
page-id={88491E75-B449-492B-BB2E-AF076D2D1911}</snip>
The linked section:
<one:Section name="Inbox" ID="{DD778267-D782-04EC-074E-CA69C2E54808}{1}{B0}"
The linked page:
<one:Page ID="{DD778267-D782-04EC-074E-CA69C2E54808}{1}
{E19538523858253232680620176633479485833791061}
I wonder whether FindPages()
would work?
This (rather out of date) article mentions the GUIDs, but only refers to the 2 API calls that invoke the OneNote UI, which is probably useless for you.
I'd be interested to have the answer to this myself so please update if you gain any further insights.
回答2:
You basically cannot convert between these two IDs. They are different IDs. The ID in the hyperlink is a permanent ID, whereas the IDs used in the API are runtime IDs. Runtime IDs will differ from machine to machine, from session to session.
There is another issue with the approach. Note that the hyperlink has a lot more info than just the page ID. The relative path to the section, page name, section id and the absolute path to the section's parent folder. OneNote will use all these information to locate a page that it thinks is the best match for the hyperlink. The resulting page may not have the ID in the link. There may actually be multiple pages or no pages with that ID. ID may also not even be used if a match with the names are found. For instance if OneNote finds a page named Integrated Asset Manager (IAM)
in the section named Cloud.one
that doesn't have the ID in the link, it will still navigate to it. Therefore taking the page ID from a link and querying that page wouldn't be the right approach even if the API used permanent IDs instead of runtime IDs.
What you can do instead is to ask OneNote to navigate to the said hyperlink using application.NavigateToUrl
and then get the current page ID and get the XML for it. Note that the URL may not resolve into a valid page (e.g. if the page was deleted or you closed the notebook etc.). In that case you can handle the error from the NavigateToUrl
method.
回答3:
NavigateToUrl would not work for my application because it causes the current page to change for the user and I want the application to work behind the scenes. So what I had to do was a bit of a kluge, but basically I had to back into the correct page id by looping through the pages in the section and apply the GetHyperlinkToObject method to convert to the correct page id.
static private string FindPageById(string startingID, string pageId)
{
string strXML;
XmlDocument xmlDoc = new XmlDocument();
onApp.GetHierarchy(startingID, HierarchyScope.hsPages, out strXML);
xmlDoc.LoadXml(strXML);
foreach (XmlElement element in xmlDoc.SelectNodes("//one:Page", nsmgr))
{
string thisPageId = element.GetAttribute("ID");
string hyperlink;
onApp.GetHyperlinkToObject(thisPageId, "", out hyperlink);
HRef href = GetHref(hyperlink); // parses out the string into an object
if (href.PageId == pageId)
return thisPageId;
}
return "";
}
来源:https://stackoverflow.com/questions/20960183/converting-between-onenote-ids-for-internal-vs-html-links