How do I see everything stored in Office.context.document.settings? - excel

Looking through the docs, I wasn't able to find a way to view everything currently stored in settings. I'm trying to debug some memory issues, and I'm worried that giant objects have been stored in the document settings (potentially from other add-ins that have worked on this same workbook).
Is there a way to see everything stored in Office.context.document.settings without using the .get method (which requires you to know the name of the property you want)?
Thanks for your help

Which host are you looking for? For Word and Excel, there is an API to get all settings. For Word, document.settings and for Excel use workbook.settings. Other hosts don't support this API.
await Excel.run(async (context) => {
const settings = context.workbook.settings.load();
settings.load("items");
await context.sync();
for (let i = 0; i < settings.items.length; i++) {
console.log(JSON.stringify(settings.items[i])) + "\n";
}
});
For Word, just replace context.workbook with context.document.

It also wouldn't help you here since it also only surfaces settings from the current add-in. Any settings created by other add-ins are inaccessible from yours.
Your best bet is to decompress the .docx file (it's just a Zip file) and inspect the contents directly. The settings are stored as XML in the \xl\webextensions folder.

Related

VSCode extension - access timeline tab

Is there a way for a VSCode extension to access the timeline tab? I searched the docs but I couldn't find anything?
To be more specific, I'd like to watch for changes in certain files and get the diff of that change. I managed to register a listener on file changes, but I also want the actual change. This is what I have so far:
const vscode = require("vscode");
function activate(context) {
const workspacePath = vscode.workspace.workspaceFolders[0];
const watcher = vscode.workspace.createFileSystemWatcher(
new vscode.RelativePattern(workspacePath, "**/package.json")
);
watcher.onDidChange((e) => {
console.log(e); # this only prints the file path, not the content.
}
}
module.exports = {activate};
There is no Timeline API available yet. There is however, a proposed API being discussed for a while (https://github.com/microsoft/vscode/issues/84297), but the last comment is one year old.
But, if you need to detect file changes (not necessarily the file being edited by the user, but any file in the workspace) and compare its content, you need not only the FileSystemWatcher but also some lib that provides you text differencing algorithm, like jsdiff.
Hope this helps

Excel JS API - SettingCollection not persisting

I'm trying to update my Excel add-in to use the workbook SettingCollection instead of the Office.context.document.settings object. The documentation seems to suggest they are functionally equivalent, but with document.settings I can call saveAsync() and see my data persisted (in the PropertyBag in a webextensions.xml).
With ctx.workbook.settings.add('key', 'value'), I can get the settings and get them in the current session, but they don't get added to the webextensions.xml and aren't available on the next open of the add-in.
Is there a version of saveAsync for workbook settings that I'm missing? I assumed context.sync would take care of it, but I haven't had any luck.
Edit: I figured out what was causing my initial issue, but the problem is still there. When I close the browser tab with Excel Online and re-open it with my add-in, the settings are not persisting. Nothing is getting added to webextensions.xml.
Here is an example Excel.run()
window.Excel.run(async ctx => {
ctx.workbook.settings.add('hello', 'world');
await ctx.sync();
let setting = ctx.workbook.settings.getItemOrNullObject('hello');
setting.load('value');
await ctx.sync();
console.log(setting.value);
});
The setting 'hello' sets and exists the next if I relaunch my add-in, but not if I close the file and open my add-in.
there is a bug with the Excel rich API for settings, can you please try the Shared API flavor as a workaround in the meantime...
function createSetting() {
Office.context.document.settings.set("Foo", "bar");
Office.context.document.settings.saveAsync();
}
function readSetting() {
console.log(Office.context.document.settings.get("Foo"));
}

Windows 10 sharing app settings between devices with same account

Is there any possibility to do this ?
I'd like to identify the user and one easy way is to save GUID that is automatically visible on other devices with same MS Account.
You can use roaming settings for this
var roamingSettings = Windows.Storage.ApplicationData.Current.RoamingSettings;
// Create a simple setting
roamingSettings.Values["exampleSetting"] = "Hello World";
// Read data from a simple setting
Object value = roamingSettings.Values["exampleSetting"];
if (value == null)
{
// No data
}
else
{
// Access data in value
}
// Delete a simple setting
roamingSettings.Values.Remove("exampleSetting");
https://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.applicationdata.roamingsettings.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-2
Oh my...
I spent half a day reading forums and suddenly found an answer, right after posting SO Queston :( Sorry.
Microsoft has good buch of Win10 samples, and one of them describes ApplicationData.Roaming -
https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/ApplicationData
Any file that is put to this folder is synced to other devices automatically.

Overriding EmailRecieved without loosing the Base EmailRecieved functionality

I have a document library setup to recieve emails. The emails coming in have a single picture and a csv file which I use for some processing.
The override emailrecieved works perfectly but of course as I override I lose the nice SharePoint functionaliy that saves the incomming email as configured in the settings.
It was my understanding that I could call MyBase.EmailRecieved in my event for the underlying functionality to still work. This however is not working and no record of the email coming in is getting retained.
For now I am explicitly creating an audit trail but I would like to rely on SharePoints existing functionality as I believe it will be more robust.
What am I doing wrong with the MyBase.EmailRecieved call? Or what can I do instead if this doesnt work?
Thanks in advance.
When writing your own EmailReceived event receiver you will loose the default functionality.
What you will have to do is to implement this default functionality yourself. Let me give you a simple example. The following example saves all mail attachments to the list if they are *.csv files. You can do the same with the emailMessage and save it to the list as well. As you can see it is as easy as to add Files.Add to add a file to a document library.
public override void EmailReceived(SPList list, SPEmailMessage emailMessage, string receiverData)
{
SPFolder folder = list.RootFolder;
//save attachments to list
foreach (SPEmailAttachment attachment in emailMessage.Attachments)
{
if (attachment.FileName.EndsWith(".csv"))
{
var attachmentFileName = attachment.FileName;
folder.Files.Add(folder.Url + "/" + attachmentFileName, attachment.ContentStream, true);
}
}
list.Update();
}

How do I open a file with my application?

Ok, you know how in programs like Microsoft Excel, or Adobe Acrobat Reader you can click on a file in explorer and it will open with the associated program. That's what I want my application to do. Now, I know how to set up the file associations in Windows so that it knows the default program for each extension. My question is how do I get my application to open the file when I double click the file.
I've searched the web using google, I've searched the msdn site, and I've searched several forums including this one but I haven't found anything that explains how to accomplish this. I'm guessing it has something to do with the parameters of the main method but that's just a guess.
If someone can point me in the right direction I can take it from there. Thanks in advance for your help.
Shane
Setting up the associations in windows will send the filename to your application on the command line.
You need to read the event args in your applications main function in order to read the file path and be able to open it in your application.
See this and this to see how to access the command line arguments in your main method.
static void Main(string[] args)
{
System.Console.WriteLine("Number of command line parameters = {0}", args.Length);
foreach (string s in args)
{
System.Console.WriteLine(s);
}
}
When you open the file, with associations set as you described, your application will be started with the first argument containing the filepath to your file.
You can try this out in a simple way by printing out the args from your main method, after you open your application by clicking on the associated file. The 0th element should be the path to your file.
Now, if you successfully reached this point, the all you need to do now is read the contents of the given file. I'm sure you'll find more than plenty of resources here on how to do that.
I guess this is what you are looking for:
FileInfo fi = new FileInfo(sfd.FileName); //the file you clicked or saved just point
//to the right file location to determine
//full filename with location info
// opening file
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = #fi.FullName;
startInfo.WindowStyle = ProcessWindowStyle.Normal;
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
You will need to create registry-keys for your file-extension. This page describes well, which keys you'll need to set (see «3. How do I create file associations?»).

Resources