Microsoft Office Development Environment Setup Script

If you are new to Office Web Add-in Development, then this post is for you. Even if you are not new and you need to setup a new development environment, this post is for you too.

Now, as far as manually setting up a new Office web add-in development environment, there are a few sources for helping you get started. There is the official guide here:

Set up your development environment

And I have also written one here:

How to-Configure VSCode for Office Development

NOTE: Mine is a tad more complicated, but essentially walks you through setting up for full fledged development, including source control with Git. That article was actually more for me when I wrote it.

BUT WAIT, THERE’S MORE…

However, after a co-worker and fellow Office Developer (Marty Andren) and I got to talking about this topic, I had an idea to create a script essentially automating the entire process. That was how the Microsoft Office Development Setup script, or MODES was born. The script is posted in the following repository:

https://github.com/davecra/modes

The MODES script is provided as-is for folks who need to setup an Office development environment. It is a simple run it and done. Once you have completed this script you will have:

NOTE: This also installs http-server, a simple local web server that I hope to use in a forthcoming blog post that expands on a previous post demonstrating how easy it is to build a Web Add-ins from scratch.

NOTE: The script installs everything as local user, so there is no need for administrative permissions.

On the MODES GitHub post, you can follow the README directions to download and run the PowerShell script. If you are unfamiliar with PowerShell, you can just follow the steps and should walk you through what you need to do fairly quickly and easily.

If the above script cannot be run on your system (as a script), you can try to perform the steps manually by Copy/Pasting the following GIST into a PowerShell window and pressing enter:


Add-Type -assembly "system.io.compression.filesystem";$vscode_url = "https://aka.ms/win32-x64-user-stable";$vscode_output = $env:USERPROFILE + "\downloads\vscode.exe";$node_url = "https://nodejs.org/dist/latest/win-x64/node.exe";$node_output = $env:USERPROFILE + "\downloads\node.exe";$node_install_path = $env:USERPROFILE + "\node";$npm_url = "https://nodejs.org/dist/npm/npm-1.4.9.zip";$npm_output = $env:USERPROFILE + "\downloads\npm.zip"
Invoke-WebRequest -Uri $vscode_url -OutFile $vscode_output
Invoke-WebRequest -Uri $node_url -OutFile $node_output
Invoke-WebRequest -Uri $npm_url -OutFile $npm_output
Start-Process -FilePath $vscode_output -ArgumentList ('/VERYSILENT', '/MERGETASKS=!runcode') -Wait
md $node_install_path
copy $node_output $node_install_path
[io.compression.zipfile]::ExtractToDirectory($npm_output, $node_install_path)
[Environment]::SetEnvironmentVariable("Path", [Environment]::GetEnvironmentVariable("Path", [EnvironmentVariableTarget]::User) + ";" + $node_install_path, [EnvironmentVariableTarget]::User)
$env:Path += ";" + $node_install_path
cd $node_install_path
Start-Process -FilePath npm -ArgumentList ('install', '-g', 'npm') -WindowStyle Hidden -Wait
Start-Process -FilePath npm -ArgumentList('install', '-g', 'yo', 'generator-office') -WindowStyle Hidden -Wait
Start-Process -FilePath npm -ArgumentList('install', '-g', 'http-server') -WindowStyle Hidden -Wait
$yo_file = $node_install_path + "\yo.ps1"
ren $yo_file "yo.ps1.old"

view raw

modes_gist.ps1

hosted with ❤ by GitHub

This GIST is a “minified” version of the script on GitHib (no comments, no output and some lines are combined). So if you run this GIST, you will need to do give it time to complete as there is no feedback.

 

 

Yo! Create an add-in from your Script Lab code

Let’s say you created the trappings of an add-in with Script Lab and now you want to make it into a stand-alone add-in. You can export your code (just the manifest and html), copy and paste it into an existing project, or upload to GitHub to share it, but you cannot easily convert it into a fully functional Web Add-in project from Script Lab. I took the time to figure this out, so you do not have to. wlEmoticon-hotsmile.png These steps will show you how to export your solution from Script Lab, import into VSCode, apply a Yeoman Office template and then begin testing it in Office Online with, ah… minimal effort (more or less). wlEmoticon-confusedsmile.png

Here are the steps:

      1. First install Script Lab in Excel. You can follow my post for that here: Start Developing in OfficeJS Today with Script Lab
      2. Next, we will load one of the sample. On the Script Lab ribbon, click Code. yo-scriptlab1
      3. Click the Samples button and then select Basic API Call.
      4. Next, click the Share button ( yo-scriptlab2 )and click Export for publishing, this will download a ZIP file in an Internet Explorer download dialog. Click Openyo-scriptlab3
      5. If you get a warning open the file, click Allow: yo-scriptlab4
      6. Select these two files, right-click and then click Copy:
        • basic-api-call.html
        • basic-api-call-manifest.xml.
      7. Leave the ZIP folder and download window open for now.
      8. Next, create a folder on your computer, call it “sample-1” then Paste (press CTRL+V) the two files into the folder. You can now close the ZIP folder you copied from and the download window.
      9. Next, you will need to have VSCode installed and configured for Office development. You can following my post for that here: How to Configure VSCode for Office Development.
      10. Open VSCode and press [CTRL+`] to open the Integrated Terminal.
      11. Change to the “sample-1” folder you created above, using the command: cd c:\\sample-1
      12. Type the following command: yo office sample-1
      13. You will then select the option as detailed below: yo-scriptlab5
      14. Once completed, on the File menu, click Open Folder. Browse to the sample-1 folder and click Select location.
      15. Delete the following files and folder:
        • app.js
        • app.css
        • index.html
        • rousource.html
        • and the function-file folder
      16. If you want to use Chrome as your debug environment, I would suggest this step which you will click to open the bsconfig.json file and add the following line: “browser”:”chrome” like this:
        {
        "browser": "chrome",
        "ui": {
        "port": 3000
        },
        "server": {
        "routes": {
        "/node_modules": "node_modules"
        }
        },
        "https": true,
        "watch": true,
        "files": "*.*"
        }
      17. Click to open the basic-api-call.html file and remove the following Script Lab lines:
        <!-- ScriptLab-Specific Runtime Helpers -->
        <script src="https://script-lab.azureedge.net/runtime-helpers.js?hash=aa0d3ff3e68d9a8b0d5d"></script&gt;
        <script>
        ScriptLab._strings = {"unexpectedError":"An unexpected error occurred","authenticationWasCancelledByTheUser":"Authentication was cancelled by the user","officeVersionDoesNotSupportAuthentication":"Your current version of Office does not support displaying an authentication dialog. Please update to a newer version, or try Office Online, if you would like to run this snippet."};
        </script>
      18. Save, close, then rename the file to index.html.
      19. Click to open the basic-api-call-manifest.xml and then CTRL+click to open the sample-1–manifest.xml in a side by side window (on the right).
      20. Copy the following lines from the left pane and replace the same lines by pasting them in the right pane:
        <!-- IMPORTANT! Id must be unique for your add-in, if you reuse this manifest ensure that you change this id to a new GUID. -->
        <Id>80434bc0-cc22-48a5-90de-88f3ea35b7ef</Id>
        <!--Version. Updates from the store only get triggered if there is a version change. -->
        <Version>1.0.0.0</Version>
        <ProviderName>Created with Script Lab</ProviderName>
        <DefaultLocale>en-US</DefaultLocale>
        <!-- The display name of your add-in. Used on the store and various places of the Office UI such as the add-ins dialog. -->
        <DisplayName DefaultValue="Basic API call" />
        <Description DefaultValue="Executes a basic Excel API call"/>
        view raw manifest.xml hosted with ❤ by GitHub
      21. Save and close all open files. You can now delete the basic-api-call-manifest.xml file.
      22. Your project is now ready. Press [CTRL+`] to open the Integrated Terminal and type: npm start. Make sure it launches on port 3000 or your add-in will not load: yo-scriptlab6
      23. Your browser will open, if you have a wanting page, click Advanced and then click Proceed to the website. You will not see your index.html.
      24. Open a new tab and browse to https://office365.com and then sign in with your credentials.
      25. From the Office menu, click Excel, then open a new blank workbook.
      26. On the Insert tab, click Office Add-ins.
      27. In the upper right of the dialog, click Upload my add-in. Click Browse and then select the file: c:\<path>\sample-1\sample-1-manifest.xml.
      28. Your adding will now be loaded. On the Home tab, you can click to open the taskpane, click the button and it should highlight the selected cell.

One major caveat is that this is not a preferred way to make a Web Project. This is bare bones and really just to get you going with minimal effort (if you can call ~30 steps minimal effort). The important thing to know is that all your code in going to be embedded in script tags inside the the HTML file and not in a separate JS file (as preferred – a.k.a. Separation of Concerns). So keep that in mind as you perform this work. If eventually your project turns into something much bigger, you will need to do some housekeeping.

So, ~30 steps… It would be nice if there were a way to do this more simply, but for now, this is the best way to do this. I have had a discussion with the product team in charge of Script Lab and they agree with such a feature, so I will update this post if it becomes available at some future point. wlEmoticon-hotsmile.png

How to Configure VSCode for Office Development

I thought I had written this some time ago, but I guess I did not. So here goes…

NOTE: First, I want to state that if you are creating applications for the full Office clients, it might be best to continue using Visual Studio 2017 as you are able to debug directly in these clients with much more ease than you can from VSCode.

Some might find it hard to believe, but I have been geeking out hard and using VSCode to develop OfficeJS (Office 365 Web Add-ins). I find it a very useful, light client, where I am able to focus on just the basics. When combined with tools like Node Package Manager (NPM), browser sync, Yoeman and Git, you have a surprisingly robust development environment what makes doing things delightfully easy. wlEmoticon-hotsmile.png But it was not always this way, I had a learning curve and it took me a while to get it all setup and running correctly. I am not saying it was hard, just… different. So I channeled my inner geek and much to his delight, it turned out for the better.

So as I stated the challenge was getting it all setup. This is going to be very different, especially if you are coming from the Visual Studio 2017 world (much more so, from the VBA world). So, here are the step by step instructions I use for getting my VSCode development environment all configured for Office Development:

  1. Download and install VSCode: https://code.visualstudio.com/ .
  2. Download and install Node to get Node Package Manager (NPM): https://nodejs.org/en/download/. On this page you will want to download the Windows/MSI/64-bit version.
  3. Download and install Git: https://git-scm.com/download. On this page you will want to make sure you select to install the latest which is from the link in the upper right of the page.
  4. Now we have the basic packages we need in order to begin development. What we need to do now is install the Yeoman generator. To do this:
    • Open VSCode
    • Press CTRL+`. This will open the console window. Alternatively you can go to the View menu and click Integrated Terminal
    • Switch to the Terminal in the Console and then type the following command: npm install global yo
  5. Now you are ready to start generating OfficeJS add-ins from VSCode, and these steps will walk you through the first one:
    • Type: yo office sample-1
    • Once you do this the scaffold generator will kick in and ask you a few questions. Answer them as I have, in bold, below:? Would you like to create a new subfolder for your project? No
      ? Which Office client application would you like to support? Excel
      ? Would you like to create a new add-in? Yes, I need to create a new web app and manifest file for my add-in.
      ? Would you like to use TypeScript? No
      ? Choose a framework: Jquery
      ? Would you like to open it now while we finish creating your project? Yes
    • Once complete you will not have a solution folder called sample1 under your user profile c:\users\<yourname>\sample-1, but the project will not be open in VSCode, yet…
    • To open your project on the File menu, click Open Folder and then browse to and open the sample1 folder, then press Select Folder. NOTE: If you are coming from Visual Studio where the tree of solution files appears on the right side of the screen, the “Explorer” in VSCode appears on the left and it is actually a listing of ALL files and ALL folders in the solution directory.
    • You will see the code files for your project on the left hand side in the Explorer. The key files of importance to you, getting started will be:
      • sample-1-manifest.xml – this is your manifest for publishing your add-in.
      • index.html – this is your primary page or “task pane” for your add-in.
    • In this example I will not have you edit any of the files, but the basics are completely provided to build a solution. At this point we will check this into Git. Press CTRL+SHIFT+G. This will open the Source Control repository page. Click the icon to the right of the words Source Control, to Initialize Repository. This will open the folder to your solution, simply click Initialize Repository. You can now work with Git to manage your project. I will not go into more detail, but if you are interested, please watch this video: https://git-scm.com/video/what-is-git
    • Finally, we are ready to debug. But first, if you are on Windows 10, and you use Edge or Internet Explorer as your default browser, I would strongly suggest using the Google Chrome browser because the debug tools are so much better. However, there is one change you need to make:
      • Open the bsconfig.json file in the Explorer
      • At the top of the configuration you need to place this line: “browser”: “chrome”, so that the file looks like this:
        {
            "browser": "chrome",
            "ui": {...
    • To debug, press CTRL+` to open or return to the Integrated Terminal. Type: npm start. This will open your project in Chrome. You might get a warning that the site is not trusted, click Advanced and select to trust anyway / continue.
    • Open another tab and browse to office365.com. Once there, log into your account. On the Office menu in the upper left, click Excel. On the Insert menu, click Office Add-ins. In the upper right of the dialog, click Upload my add-in. Click Browse and then select the file: c:\users\<yourname>\sample-1\sample-1-manifest.xml. Your add-in will now load on the Home tab, switch there, and press Show Taskpane.

This looks like a lot of work and I know for most of you that are like me, coming from a Visual Studio and/or VBA background, this is very alien. You might consider this a step backwards or it might seem like it is time to hang up the spurs. wlEmoticon-disappointedsmile.png But give it some time, especially if you are just getting into OfficeJS, it will grow on you. In the meantime, here are some of my other blog entries around this to help you:

Please let me know if you have questions or would like some help with any of this. What I hope to be able to do at some point is to add posts on:

  • Importing a Script Lab project into a Yo Office scaffold
  • A video on the steps outlined in this post. I have done videos for internal training at Microsoft before, but never on my own for my blog. So this will be new territory if I can get around to it.
  • Other samples posts to getting started with various projects.

If you have any ideas of what you would like to see, please let me know.

OfficeJS.dialogs version 1.0.8

I have recently updated the OfficeJS.dialogs to version 1.0.8. I have also updated the Node Package Manager version as well. You can get it by running the following command in the VSCode Terminal Window:

npm install officejs.dialogs

With this latest version comes a few bug fixes, some cleanup of the code, cleaner JSDoc documentation and a PrintPreview dialog. The PrintPreview started out as a proof of concept but it actually works for me – in the browser anyway. I am not sure how well it will work in any of the full clients as I have not tested it there yet. If anyone has a chance to test it, please let me know if you encounter any issues.

Here is a sample of the PrintPreview dialog:

print

Here is some code to implement it:


// this example takes the currently composed email message in Outlook,
// grabs its body HTML and then displays it in the Print Preview dialog.
var mailItem = Office.cast.item.toItemCompose(Office.context.mailbox.item);
mailItem.saveAsync(function(asyncResult) {
var id = asyncResult.id;
mailItem.body.getAsync(Office.CoercionType.Html, { asyncContext: { var3: 1, var4: 2 } }, function(result) {
var html = result.value;
PrintPreview.Show(html, function() {
Alert.Show("Print cancelled");
});
});
});

view raw

printpreview.js

hosted with ❤ by GitHub

 

easyEws v1.0.7 is now released

This has been slow coming, but I have just released v1.0.7 of easyEws. As per usual, it is on NPM and on GitHub. You can get the latest with the command:

npm update easyews

Or, you can install it into your solution with the command:

npm install easyews

In this version the JSDOC information is now full incorporated so you get great inline help with each command. I enhanced the library so that it works better with inline help and so I changed how the class is setup and exposed. I have updated the README.md on GitHub, but I still am working on examples and such, that will be done later. And I added new functionality, a moveItem command which can be used to move any item from one folder to another. This was a added due to feedback I received on LinkedIn.

Please feel free to reach out to me with any questions or suggestions.

 

OfficeJS.dialogs v1.0.7 Published

So, I kind of skipped v1.0.6, which I promised in this post yesterday. There were some unchecked changes on a different laptop that I forgot in v1.0.6, so I published v1.0.7 this morning with all the updates. Some notable update:

  • Moved from CloseDialog() to CloseDialogAsync() on all the dialogs using the original close method. This is to workaround the issue described in the post yesterday.
  • Fixed dialog flashing by hiding the body until the form is ready to be shown. Before you might get a flash of all the controls on the form as they were not hidden before.
  • Internal clean-up and message handling. In the message pump between the dialogs.html and dialogs.js, I cleaned up the pump to use internally standardized messages.
  • Fixed some JSDoc information that was wrong. And there is likely still more. wlEmoticon-disappointedsmile.png
  • Fixed some things that were not working correctly with the progress dialog.
  • Small tweeks and comments, code clean-up

The latest version is now on GitHub. I have also completed all the documentation and updated it to the latest usage information, code examples and screenshots.

I also published the latest version to NPM. Simply type this in you code terminal window:

npm -install officejs.dialogs

CDN Update

I still have a published CDN for OfficeJS.dialogs, but at this point I am going to suggest against using it. I have encountered a number of issues with my message pump when loaded cross-domain. Specifically:

  • you will be able to show a MessageBox, but the Update() method will not work
  • you will be able to show a Progress dialog, but the Update() method will not change the dialog. The progress bar will never advance.

What is happening is that I was going to need for **you** the  developer to provide me your own proxyHTML file (pointing to my CDN/proxy.js library) that I will do the following:

  • Add an iframe, load my html file in that iFrame, post the dialog settings to the iFrame where my dialog in the iFrame gets it, and writes it to localStorage on the CDN domain.
  • Window.replace the contents with my dialogs.html from the CDN. And since the localStorage now has the dialog settings, configure the dialog.
  • So far at this point everything worked. From HERE is where I am pushing my CORS and JavaScript to the edge of sanity…
  • I then create an hidden iFrame in my dialog and then load your proxy html file. I attach to the body change event inside the iFrame.
  • I then start a message pump in the proxy looking for changes to localStorage.
  • If a new message comes from your code with an Update() on MessageBox or Progress, I then get it from the localStorage in a message and write it to the body, therefore updating the iFrame in my dialog, thereby triggering the change event I latched on to, allowing me to write that value to the CDN localStorage where the message pump in dialog will get the message and update the form.

That hurt my brain writing that out. And maybe that is more for my posterity since it took me Binging the Internet to death (I don’t use to the G word folks wlEmoticon-hotsmile.png), just to get that far. My pretzel, I mean head hurts.

Bottom line, I want to get OfficeJS.dialogs to work cross-domain. I am not sure if the above method is the right approach. I have asked far brighter minds than my own and watched Autie Anne’s Syndrome set in almost immediately. So, if any of you have some ideas on how I can establish 2-way communication between domains like this (without using some crazy huge library), please let me know. wlEmoticon-smile.png

Using NPM to Publish and Update Packages

This blog post is more for me than you. I come from an era when command line was the only way to get things done. The folks that were able to do that in the 1980’s and early 1990’s, were called…

nerd

Well, for some reason, after advancements in GUI (Graphical User Interfaces) we are back to command-line interfaces. I have heard an argument that this makes it easier to build in voice command interfaces, but I do not see myself saying: “npm install”. I believe it came about because it is easier to create a command line interface quickly for free than it is to create a graphical one. Just sayin’. wlEmoticon-winkingsmile.png

With that said, lets get down the business. I published OfficeJs.dialogs to NPM and found a few last minutes bugs and needed to update it. Well, this seemed easy enough, but I was getting some error about my git working directory:

git working directory dialogs not clean

This turns out to happen because I needed to do both a push and a pull. Not sure why, but I did a push and sync and that did not resolve the issue. I had to do a pull from git too:

menu

Next, I had to then do a version update. To do this you type this in the Terminal window in VS Code once it is pointed to the repository folder:

npm version patch

This will add a single point to the version, so for me that was from 1.0.1 to 1.0.2. Next, you issue a single command:

npm publish

This will publish version 1.0.2 (in my case) to the node module in the sky (npmjs.com). Next, I then went to my project where I am using it and then issue this command:

npm update officejs.dialogs

And just like that, I had the latest version. Seems simple enough, but it took a while for me to research this and get it working. And since these are all command lines without a graphical ability to “hunt and peck” for the right menu item, I am writing it down for posterity. I will likely be referring to this post for myself again in the future.