I have a handful of OneNote .one files. I would like to extract their contents programatically. I'm getting stuck trying to access pages.
I'm calling:
app.OpenHierarchy(#"C:\test\TestSection.one",
System.String.Empty, out strXML, CreateFileType.cftNone);
in strXML is an ID.
Then I call:
app.GetHierarchy(strXML, HierarchyScope.hsPages, strXML2);
This returns an XML block with only <one:Section.../>. It has attributes that match the ID in strXML and the path to the physical .one file.
I have verified these .one files open in OneNote. I can see that this test.one has a bunch of pages. What am I doing wrong or missing here?
I'm using Office 2013 (v.15) and VS 2013 (I had to set Embed InteropTypes to False in the OneNote Interop v.15 reference to get things to build).
Once you call app.GetHierarchy using the HiearchyScope.hsPages, you will now have all of the notebooks, sections, and pages that were stored in your TestSection.one file. Here is an example if you wanted to traverse through the hieararchy of the notebooks, sections, and pages after you have called GetHierarchy.
var notebookName = "My Notebook";
var sectionName = "My Meetings";
var xdoc = XDocument.Parse(strXML2);
var ns = xdoc.Root.Name.Namespace;
var myNotebook = xdoc.Root.Descendants(ns + "Notebook").SingleOrDefault(n => n.Attribute("name").Value == notebookName);
if (myNotebook != null)
{
var mySection = myNotebook.Descendants(ns + "Section").SingleOrDefault(s => s.Attribute("name").Value == sectionName);
if (mySection != null)
{
var pages = mySection.Descendants(ns + "Page");
// Now do something here with the pages!
// ...
}
}
Related
I am very new to the C# and .NET stuff and been experimenting with some HTML parsing and file downloading when i came across a problem.
I had previously written my code in .NET Core and it was working fine and then i realised that i need to use System.Windows.Forms to be able to access User's monitor resolution and tried transfering my code to .NET framework app to be able to add the System.Windows.Forms assembly (Apparently it is not possible in .NET Core, Please let me know if I am wrong 😁).
So Here is the code:
using System;
using System.Linq;
using HtmlAgilityPack;
using System.Net;
using System.IO;
namespace AmazingSuperAwesomeWallpaperDownloaderAppConsoleApp
{
class Program
{
static void Main(string[] args)
{
Download();
}
static void Download()
{
Console.WriteLine("Please enter the wallpaper page ID: ");
//Asks for user to input the Wallpaper ID and creates the link out of it.
var userInput = "https://SuperSecretWallpaperWebsite.com/Wallpapers/" + Console.ReadLine();
// set the html var to the website link to parse
var html = #userInput;
//gets the website html from the HTTP
HtmlWeb web = new HtmlWeb();
//Creates a var called document to load the wesite in it.
var document = web.Load(html);
var fileName = "Wallpaper.jpg";
//Creates a container, the first div to pass a certain criteria for the container will populate this container
var container = document.DocumentNode.Descendants("div").FirstOrDefault(x => x.Attributes.Contains("class") && x.Attributes["class"].Value == "wallpaperContainer");
if (container != null)
{
//Does the same thing as above and looks for the Div with details class and stores it in the title var.
var titleContainer = container.Descendants("div").FirstOrDefault(x => x.Attributes.Contains("class") && x.Attributes["class"].Value == "details");
if (title != null)
{
//Finds the first h1 tag that is in title var and stores it in titlevalue
var titleValue = titleContainer.Descendants("h1").FirstOrDefault();
if (titleValue != null)
{
//A var that is set to the innter text of the the h1 that was found in the titleValue var.
var h1TitleValue = titleValue.InnerText;
//Adds file extension to the file name which is the title
fileName = h1TitleValue + ".jpg";
Console.WriteLine("Title: " + h1TitleValue);
}
}
}
//Creates aTag container, the first aTag to pass a certain criteria for the container will populate this container
var aTagContainer = document.DocumentNode.Descendants("a").FirstOrDefault(x => x.Attributes.Contains("class") && x.Attributes["class"].Value == "downloadButton" && x.Attributes.Contains("href"));
if (aTagContainer != null)
{
//Splits the wallpaper URL from the rest of the useless url stuff
var DLink = aTagContainer.Attributes["href"].Value.Split("Url=");
using (var client = new WebClient())
{
//Finds the MyPictures folder for the logged in user and sets it to the wallpaper directory
var filePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures), "SuperAwesomeWallpaperDownloadFolder\\");
//Creates the folder in MyPicture folder
System.IO.Directory.CreateDirectory(filePath);
//Downloads the wallpaper file and saves it in the directory
client.DownloadFile(DLink[1], (filePath + fileName));
Console.WriteLine(filePath);
}
Console.WriteLine("Download Link is: " + DLink[1]);
}
}
}
}
After copying and pasting the code in a new Console app with .NET framework I get errors in
var DLink = aTagContainer.Attributes["href"].Value.Split("Url=");
saying that inside Split it should be a Char and not a string! then why did it work in .NET Core?
client.DownloadFile(DLink[1], (filePath + fileName));
Also the Download function seems to not like the way it is set up for some reason and will not work no matter what despite working fine in .NET Core.
Also I know my code is probably not as well-written, I would be happy to hear your criticism regarding that as well.
Thank you in advance kind stranger 🥰
in .net core 2.0 and above, there is an overload for split which takes a string as input however this is not the case in .net framework which takes a character for split. If you want to split a string based on another string use the sample code mentioned below.
var DLink = aTagContainer.Attributes["href"].Value
.Split(new string[] { "Url=" }, StringSplitOptions.None);
Hope it helps.
I'm looking for a way to access a linked Autocad File using the Revit API. I have SnoopDB already installed which is a huge help.
I found this which was also another step forward however I'm not able to get the points or lines of the file.
I've explored a bit and have found that I am able to access the filename and then get the hashcode of the cadlink but after that, idk how to get the goemetry within.
Any and all help is appreciated.
here is what I have so far:
UIApplication uiapp = commandData.Application;
UIDocument uidoc = uiapp.ActiveUIDocument;
Application app = uiapp.Application;
Document doc = uidoc.Document;
Selection sel = uidoc.Selection;
using (Transaction tx = new Transaction(doc))
{
try
{
tx.Start("Tracing Cad");
Reference refer = sel.PickObject(ObjectType.Element, "Select a CAD Link");
Element elem = doc.GetElement(refer);
GeometryElement geoElem = elem.get_Geometry(new Options());
Debug.WriteLine("elem.Category.Name: " + elem.Category.Name); // can grab title of CAD
foreach (GeometryObject geoObj in geoElem)
{
GeometryInstance instance = geoObj as GeometryInstance;
foreach (GeometryObject instObj in instance.SymbolGeometry)
{
Debug.WriteLine("geoObj.GraphicsStyleId: " + geoObj.GraphicsStyleId);
Debug.WriteLine("geoObj.GetHashCode(): " + geoObj.GetHashCode()); // gets hashcode of selected cad link
if (instObj.GetType().Name == "PolyLine")
// if (instObj.GetType().Name == "GeometryInstance")
{
}
else
{
Debug.WriteLine("there are no blocks found in this CAD File");
}
}
}
tx.Commit();
} catch (Exception e )
{
Debug.WriteLine(e.StackTrace);
}
The Revit API does not provide any access to the internals of a linked CAD file.
All you can do is implement some AutoCAD.NET code to read the DWG file itself, provided you have access to the DWG and AutoCAD is installed.
The Building Coder shares some samples showing how to launch AutoCAD within a Revit add-in.
I need to download files from opensubtitles.org trough my application which is written in GTK# and C#. The app is based on .NET 4.0 framework.
At first this was the code I was using:
var tZip = new FastZip();
try {
var tRequest = (HttpWebRequest)HttpWebRequest.Create(tDownloadUrl);
var tZipResponse = (HttpWebResponse)tRequest.GetResponse();
using (var tStream = tZipResponse.GetResponseStream()) {
using (var tMemStream = new MemoryStream()) {
tStream.CopyTo(tMemStream);
var tTempPath = Globals.video_location + "OSD";
Directory.CreateDirectory(tTempPath);
tZip.ExtractZip(tMemStream, tTempPath, FastZip.Overwrite.Always, null, #"\.srt$", null, false, true);
var tDirInfo = new DirectoryInfo(tTempPath);
var tFileInfo = new FileInfo(Globals.location_video);
var tSrtFile = tDirInfo.EnumerateFiles().FirstOrDefault();
if (tSrtFile == null) {
writeLog("No .srt file found in zip..");
goto text;
}
writeLog("Downloaded and unpacked: " + tSrtFile.Name);
File.Copy(tSrtFile.FullName, Globals.video_location+Globals.video_name+".srt", true);
Globals.savedTitle = Globals.video_location+Globals.video_name+".srt";
// clean up..
Directory.Delete(tTempPath, true);
writeLog("Deleted temp folder.");
return true;
}
}}
And that worked really well up until few days ago, now it is returning a bunch of html code instead of .zip file. I tried even something like this:
WebClient client = new WebClient();
client.DownloadFile(link, #"OSD\test.zip");
But everything just keeps returning bunch of html code.
The link I am usually trying to download is something like this:
http://dl.opensubtitles.org/en/download/subad/4287952
If you click on the link above it will just redirect you to the opensubtitles.org page of that particular subtitle. But if you right mouse click on that link and then select "open in new tab" or "open in new window" it will automatically start the download. (Tested in Firefox)
Also as soon as I paste that link in "Internet Download Manager" application, it will start the download of the zip file automatically.
If you can help me to resolve this problem I will truly be grateful.
Kind Regards.
I got into this problem because I was filtering the website xml directly. Like from a link such as this one: opensubtitles.org example
And in the beginning it used to work well, but then they changed something on the website and it stopped working. So what I did was build on top of this: OSHandler
That handler library is using XML-RPC so I believe there won't be any problems in the future.
I would like to read/write the window information file (extended file properties) using c#
The one found by doing the following: In window explorer right click => properties => Summary tab. I want mainly to have access to the properties:
Title
Category
Revision Number
For office document I can use the following (using Office.Interop) or using DSOFile
private static string GetExcelWorkbookPropertyValue(_Workbook workbook, string propertyName)
{
DocumentProperties builtInProperties = (DocumentProperties)workbook.BuiltinDocumentProperties;
string value = builtInProperties.Cast<DocumentProperty>().First(x => x.Name.Equals(propertyName, StringComparison.InvariantCultureIgnoreCase)).Value;
return value ?? "";
}
But what i would like is a more general solution that will work with all files.
Could someone help?
Question additional information you can also read the properties Title and Category by using Shell32
Shell32.Shell shell = new Shell32.Shell();
//set the namespace to file path
Shell32.Folder folder = shell.NameSpace(Path.GetDirectoryName(file));
//get ahandle to the file
Shell32.FolderItem folderItem = folder.ParseName(Path.GetFileName(file));
//did we get a handle ?
if (folderItem != null)
{
for (int i = 0; i < 100; i++)
{
string s = folder.GetDetailsOf(folderItem, i);
System.Diagnostics.Debug.WriteLine(s);
}
}
However I still write the properity Revision Number, however it's look like Revision number is an office document property and cannot be written (I guess it will break the tracking process of office).
What does not make sense is that I can modify it using window explorer and the property is also visible for non-office documents... I'm struggling to understand that.
This information is stored in properties. Here are some of the standard properties. I'm not sure if the .NET Framework provides a wrapper around these interfaces, though.
I am trying to merge c# documents. My idea is to have a master document and just append the other documents to this master document. Environment is in SharePoint, so basically the documents exist in the document library and I have no problem with my code being able to find the documents. Once I locate them programattically I have no clue how to open and merge them. I have been searching and seems to be like OpenXML SDK 2.0 is a way to do it, but I am not familar with that tool at all and was trying to see if their is a way to do it with the current tools I have in Visual Studio 3.5 . Either using Microsoft.Office.Interop.Word or something else. From what I understand, the actual files are stored in the content database as binary form so the physical file doesn't actually exist, so I cant just easily open them with word. Any help.
I think this link is exactly what you're looking for:
Merging Word Documents on the Server Side with SharePoint 2010
There's a little Open Xml, but nothing too bad. If you decide that this isn't giving you the control you need, you can check this article out:
Creating Documents by Using the Open XML Format SDK 2.0 (Part 3 of 3)
The following script, taken from Tortoise SVN, could help you to get a clue about how to merge .doc files. Be careful with the license if your going to distribute it.
You need to invoke the script from C# using the following:
wscript.exe "C:\<path_to_the_script>\merge-doc.js" merged.doc theirs.doc mine.doc base.doc //E:javascript
This is the script code, only for doc, there is other for docx that I have not included here, but you can take a look installing Tortoise SVN.
//
// TortoiseSVN Merge script for Word Doc files
//
// Copyright (C) 2004-2008 the TortoiseSVN team
// This file is distributed under the same license as TortoiseSVN
//
// Last commit by:
// $Author: tortoisesvn $
// $Date: 2008-12-05 17:38:43 +0100 (Fr, 05 Dez 2008) $
// $Rev: 14781 $
//
// Authors:
// Dan Sheridan, 2008
// Davide Orlandi and Hans-Emil Skogh, 2005
//
var objArgs,num,sTheirDoc,sMyDoc,sBaseDoc,sMergedDoc,objScript,word,baseDoc,WSHShell;
// Microsoft Office versions for Microsoft Windows OS
var vOffice2000 = 9;
var vOffice2002 = 10;
var vOffice2003 = 11;
var vOffice2007 = 12;
// WdCompareTarget
var wdCompareTargetSelected = 0;
var wdCompareTargetCurrent = 1;
var wdCompareTargetNew = 2;
objArgs = WScript.Arguments;
num = objArgs.length;
if (num < 4)
{
WScript.Echo("Usage: [CScript | WScript] merge-doc.js merged.doc theirs.doc mine.doc base.doc");
WScript.Quit(1);
}
sMergedDoc=objArgs(0);
sTheirDoc=objArgs(1);
sMyDoc=objArgs(2);
sBaseDoc=objArgs(3);
objScript = new ActiveXObject("Scripting.FileSystemObject")
if ( ! objScript.FileExists(sTheirDoc))
{
WScript.Echo("File " + sTheirDoc +" does not exist. Cannot compare the documents.", vbExclamation, "File not found");
WScript.Quit(1);
}
if ( ! objScript.FileExists(sMergedDoc))
{
WScript.Echo("File " + sMergedDoc +" does not exist. Cannot compare the documents.", vbExclamation, "File not found");
WScript.Quit(1);
}
objScript = null
try
{
word = WScript.CreateObject("Word.Application");
}
catch(e)
{
WScript.Echo("You must have Microsoft Word installed to perform this operation.");
WScript.Quit(1);
}
word.visible = true
// Open the base document
baseDoc = word.Documents.Open(sTheirDoc);
// Merge into the "My" document
if (parseInt(word.Version) < vOffice2000)
{
baseDoc.Compare(sMergedDoc);
}
else if (parseInt(word.Version) < vOffice2007)
{
baseDoc.Compare(sMergedDoc, "Comparison", wdCompareTargetNew, true, true);
} else {
baseDoc.Merge(sMergedDoc);
}
// Show the merge result
if (parseInt(word.Version) < 12)
{
word.ActiveDocument.Windows(1).Visible = 1;
}
// Close the first document
if (parseInt(word.Version) >= 10)
{
baseDoc.Close();
}
// Show usage hint message
WSHShell = WScript.CreateObject("WScript.Shell");
if(WSHShell.Popup("You have to accept or reject the changes before\nsaving the document to prevent future problems.\n\nWould you like to see a help page on how to do this?", 0, "TSVN Word Merge", 4 + 64) == 6)
{
WSHShell.Run("http://office.microsoft.com/en-us/assistance/HP030823691033.aspx");
}