Developing in Linux on Windows

I have been working more and more with Linux lately. The job as a Program Manager has put some of my skills to the test. Oddly, I actually taught a semester of Linux back in my “college professor days.” And despite the kicking and screaming, funny enough, I am close to becoming a novice beginner at it.

Last year, I took the deep dive, spending nearly 100% of my personal time in Linux – command line and UI wise. I had an Ubuntu VM in the cloud that I worked with and repurposed on one of my old laptops with a distro of Elementary OS (essentially a MacOS like shell on top of Ubuntu).

Well, recently, I have been playing about with the Windows Subsystem for Linux. In the early days this was what I called a novelty. You could open a command prompt and start bashing out Linux commands and feeling totally geeky šŸ¤“. However, recently, I found that you can now run Linux Applications in a window from Windows 11. This was a bit of a game changer, as now I can run Linux and Windows (side-by-side).

So, I just got through developing and testing an Office JS add-in (which I just published to the store) from Linux using VS Code and Microsoft Edge. It will hopefully be released soon, and I will blog it here (Send to Trello for Outlook Add-in).

Here is how I did it:

  1. First, I would suggest installing Windows Terminal. I can spend a whole blog post on this and might, but it allows you to run CMD, PowerShell and BASH all side by side in tabs. It is awesome.
  2. Open Terminal and install WSL. From a PowerShell tab type “wsl –install”. By default, this will put Ubuntu 20 (behind the scenes) on your system.
  3. Once installed and you restart the Windows Terminal App, you should see Ubuntu as an option for opening a new Tab.
  4. Select that. If it is your first time, you will need to supply it with a username and password.
  5. Once setup, you simply need to start installing apps:
    • Type: “sudo apt update” to start updating the apps, this is like “Windows Update” for Linux.
    • Next, type: “sudo apt install x11-apps -y” to get the basic software installed.
    • Next, you will want to install Microsoft Edge:
      • To install Edge use the code from this page: https://www.microsoftedgeinsider.com/en-us/download?platform=linux-deb (scroll down past the ‘download’ links).
      • Before you run it, you will want to type: “sudo su” and sign in. This signs you in as SUPER USER so that you can do things as an administrator.
      • After it is installed type “exit” to return to normal user mode.
    • Finally, install VS Code, like this: in the Terminal Window, type: “microsoft-edge” which will open Edge. From there go to Bing, search for “install VSCode on Linux” and it should not be too difficult to follow the steps you find. But to help out a bit… šŸ˜Š Follow the steps for Ubuntu, here: https://code.visualstudio.com/docs/setup/linux.
  6. Now you can type “code” in the Linux command prompt and VSCode for Linux will open in a separate window. From there you can build your application and test it in Edge for Linux as well. That is what I did.

The coup-de-grace, it places these applications right on your START menu:

So, a friend asked me…”Uh, so.. like.. why?” I answered, “Uh… Because, I can!” šŸ¤“

It has been a fun journey, learning something new and as it turns out, it has come in handy quite a few times in the new role as different aspects of the system we are developing cross paths with Linux. I also have a sneaky suspicion that this Windows/Linux integration lines are going to get a bit more “blurred” in the coming years (100% personal opinion).

An Asynchronous MessageBox

Recently, I had a project I was working on where we needed to be able to notify the user of a possible problem during a long running process. The results would not be ruined, or wrong, just likely incomplete. In this particular case we were collecting several pieces of information and sometimes one of those pieces were not available (say, for example the server was down, the file was missing, or it took too long). We wanted to let the user know the process had encountered an issue, but not stop it. Yet we wanted to also give them the option to retry it. So we presented an Abort, Retry, Cancel dialog like this one:

messagebox

The problem is that with a traditional MessageBox the entire process would be frozen. If this happens immediately after the user heads off to lunch, when they get back there would be no report, no data and most of the process would not have been run yet, for example.

What I needed was for the process to continue, but to allow the user to be able to take action before the process completed on anything that was found. For example, they see this error above and think: “oh crap, I forgot to copy over the report file.” So they put the correct file in place and hit “Retry.”

Therefore, I created the AsyncMessageBox class:


using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
namespace NonModalMessageBox
{
/// <summary>
/// Provides an asyncronous MessageBox. You can use this static class to
/// present a message to the usser while your code can continue to run.
/// You can attach to the AsynMessagebox.MessageboxClosed event to get the
/// result from the dialog once the user does close it.
/// </summary>
public static class AsyncMessageBox
{
private static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
private static readonly uint SWP_NOMOVE = 0x0002;
private static readonly uint SWP_NOSIZE = 0x0001;
private static readonly uint SWP_SHOWWINDOW = 0x0040;
[DllImport("user32")]
private static extern IntPtr FindWindow(string PstrClassName, string PstrCaption);
[DllImport("user32")]
private static extern void SetWindowPos(IntPtr PintWnd, IntPtr PintWndInsertAfter, int PintX, int PintY, int PintCx, int PintCy, uint uFlags);
public delegate void MessageBoxClosedHandler(object PobjSender, MessageBoxClosedEventArgs PobjEventArgs);
public static event MessageBoxClosedHandler MessageBoxClosed;
private static bool MbolAlreadyShowing = false;
/// <summary>
/// Shows an asyncronous dialog
/// Fires the MessageBoxClosed event when it is closed.
/// This is a static messagebox, so only one can be displayed at a time
/// Once called, the event handler is detached
/// </summary>
/// <param name="PstrText">The message in the message box</param>
/// <param name="PstrCaption">The cpation on the message box</param>
/// <param name="PobjButtons">The buttons for the message box</param>
/// <param name="PobjIcon">The icon for the messafe box</param>
/// <param name="PobjDefault">The default button selected in the messagebox</param>
/// <returns></returns>
public static bool Show(string PstrText, string PstrCaption = "", MessageBoxButtons PobjButtons = MessageBoxButtons.OK, MessageBoxIcon PobjIcon = MessageBoxIcon.None, MessageBoxDefaultButton PobjDefault = MessageBoxDefaultButton.Button1)
{
try
{
if (MbolAlreadyShowing) return false; // failed – already displayed
DialogResult LobjResult = DialogResult.None;
// start a thread to show the dialog
new Thread(() => {
MbolAlreadyShowing = true;
LobjResult = MessageBox.Show(PstrText, PstrCaption, PobjButtons, PobjIcon, PobjDefault);
MbolAlreadyShowing = false;
}).Start();
// start a separate thread to wait for the result from above
new Thread(() => {
// now make it topmost
IntPtr LintHwnd = FindWindow("#32770", PstrCaption);
SetWindowPos(LintHwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
// Stay here until we get a result
while (LobjResult == DialogResult.None)
{
Thread.Sleep(10);
Application.DoEvents();
}
// create a hidden form so we can invoke back to the UI thread
// otherwise anyone attached to the event handler will get an
// exception if they try anything with the UI
using (Form LobjForm = new Form { ShowInTaskbar = false, Opacity = 0 })
{
LobjForm.Show(); // show hidden form – ui thread
// fire the event
LobjForm.Invoke(new Action(() => {
MessageBoxClosed?.Invoke(new object(), new MessageBoxClosedEventArgs(LobjResult));
MessageBoxClosed = null; // important to release this
}));
LobjForm.Close(); // close hidden form
}
}).Start();
return true; // created
}
catch
{
return false; // failed
}
}
}
/// <summary>
/// Event arguments for an AsyncMessageBox
/// </summary>
public class MessageBoxClosedEventArgs
{
public DialogResult Result { get; private set; }
public MessageBoxClosedEventArgs(DialogResult PobjResult)
{
Result = PobjResult;
}
}
}

Under the covers this uses a traditional MessageBox, but on background thread. You need to attach to the MessageBoxClosed event before you make the AsyncMessageBox.Show() call if you want to get the result. Here is how you use this method:


AsyncMessageBox.MessageBoxClosed += (o, e) =>
{
// handle the user response here
if(e.Result == DialogResult.Retry)
{
// retry code here
}
};
AsyncMessageBox.Show("There was an issue accessing 'quaterly report.xlsx'.",
"Quarterly Report Generator",
MessageBoxButtons.AbortRetryIgnore,
MessageBoxIcon.Exclamation);

Anyway, thought this might be useful, so I have shared it. wlEmoticon-hotsmile.png

Goodbye ModNotebooks, Hello OfficeLens

I like taking notes, the old fashioned way (by hand in a notebook, on… paper), but I like finding them the new way (using search on my PC). I love OneNote and how easy it is to keep an online notebook with all sorts of data. For example, due to archival rules some of my email starts to “disappear” from my work account after a couple of years. But some emails I like to keep – little nuggets of wisdom, notices, personal information and such I like to keep around. So, I export them to OneNote, where I can keep them safe.

So, I was living this duplicitous life of daily note taking with pen and paper but also filling my online notebook with all sort of information. I wanted to find a way to bridge these two. A few years back I was at a Microsoft convention and ran into a member of the OneNote team that turned me on to a small startup firm called: ModNotebooks. Their website is now gone, this is all you see:

mod.PNG

What they did was to send you a very high quality notebook, you would fill it up and ship it off to them. In the back of the notebook was a folder with a mail pouch and prepaid postage. They would receive it, scan it in for you and then dump the contents into your OneNote file behind the scenes. I filled 7 notebooks with them. But alas, their business model did not work, I am guessing, and they have gone out of business.

Now, I am left with my seeming duplicity again.Ā wlEmoticon-disappointedsmile.png How do I get back to having my handwritten notes in OneNote again? Enter, OfficeLens.

I have actually been using this app for some time to scan travel receipts to PDF to turn in for expense reimbursement. And while I have always known I can use it for OneNote notes, I never tried it – namely because I had a better thing in ModNotebooks – or so I thought. Being forced to use something is sometimes what it takes. So, I gave OfficeLens a shot.

First, you download it to your phone. It comes on all three platforms (Windows Phone, iOS, and Android). Next, you hook up your Microsoft account (Live/Hotmail/MSN) and then you start scanning. It automatically finds the page and draws a border around it:

20170717_145127000_iOS.png

When you click the button at the bottom, it shows you what it got:

20170717_143239000_iOS.png

In the lower left, you can click the (+1), to add more page (up to 10 at a time – my only complaint – more on that later)* Once complete with your scanning, you click Done at the top right. This will take you to the “Export To” page.

20170717_143248000_iOS.png

From here I select OneNote and it asks me where I want to put it in my Notebook and when I click Save, it begins to upload it to my OneNote notebook:

And once it is in OneNote, it is fully text searchable, based on my handwriting. Yes, I said “fully text searchable” from my handwriting. Here is what it looks like once it gets to the final destination and I perform a search:

OneNote.PNG

Amazing, eh?

So, my only complaint is that the tool only allows you to scan in 10 pages at once. I wish there was a way to override this, for two reasons:

  1. I take a lot of notes and I fill 10 pages quickly. I have to get into the habit of scanning every week at this point to keep up. It is not impossible, but it would be nice to skip a few weeks and then scan them all in – in bulk. Right now, I have to upload it in several different batches of 10.
  2. I recently was working with legal documents and needed to print them out, sign them, scan them in and then send them off. The document had 11 pages. 11. 11! So, I had to scan 10 pages, then scan the last one and then find PDF merge software to merge them all together. That was NOT fun.

With that said, Au Revoir ModNotebooks. You were great while you lasted. I will likely be going back to using Moleskin’s and then using OfficeLens to digitize. We shall see… TUL (the “u” is long, so “tool”) has some nice notebooks too – I love their fine-point pen:

20170717_152827116_iOS

If you have any suggestions, please leave comments below.Ā wlEmoticon-hotsmile.png

Going back to taking notes by hand…

 

Humor, That is Still Valid (Sadly)

A Texan dies and goes to Hell. The devil is excited as he has never met a Texan before. So he runs down to the lowest depths to find the Texan sitting with his boots propped up and a big grin on his face. The devil shocked, as others are wailing in pain and asks the Texan what he is so happy about. The Texan coolly replies, ā€œWell, Devil, I thought it would be much worse, but this reminds me of Texas in June.ā€ This steams the Devilā€¦

So the devil heads back to the control room and turns up the dial a few more notches. Almost instantly the wails of pain raise across all of hell. He returns to the Texan who has removed his shirt, but still had that damn grin on his face. So the devil asks why he is still so happy as he obviously sees the others around him writhing in agony. The Texan coolly replies,ā€ Well, Devil, it did get a bit warmer, but it feels like Texas in July. And that is my favorite month.ā€ Now the devil is incensed.

So the devil goes back to the control room and cranks up the heat as high as it will go. The instant deafening roar of screaming is almost too much for the devil. But he gets back to the Texan who is in nothing but his boxers. Without being asked, the Texan states, ā€œDevil, did you know my birthday is in August and this feels great!ā€ The devil blew his lid in anger.

So the devil heads back, feeling dejected by this first representative from the great state of Texas; but he hatches a new plan. We walks to the control panel and turns it down as low as it would go. All smug now, the devil returns to the Texan to find snow piled in the corners, kids throwing snow balls, laughing and playing, icicles hanging from the ceilingā€¦ but what was this? The Texan was running around in circles, jumping up and down and whopping an hollering. The devil stopped him for a moment and asked what had gotten into him. The Texan replied, ā€œThe Texas Rangers just won the World Series!ā€

Just moved

With Microsoft moving away from spaces.live.com, I have migrated my site to WordPress. So far so good. It looks like the migration went without a hitch. I customized the default site they gave me and still have many more options to review… Way more capability than spaces ever had.

Still here ā€“ justĀ overwhelmedā€¦

I have not had a lot of time lately to do much of anything. Two weeks ago I was in sunny Orlando for Convergence 2008. That was a FUN event, but quite tiring as I was manning the Microsoft Office SharePoint Server (MOSS) booth. Talk about a product that gets people excited…MOSS makes them crazy. Smile

This week I am finalizing training material for the Troubleshooting and Supporting Microsoft Office 2007 in the Enterprise workshop [link coming soon]. In two weeks I deliver the workshop listed above to a customer here in Dallas and then two weeks later I will be delivering it again in Chicago. I am told from that point I will be delivering it about every 4 to 6 weeks. Surprised

Additionally, I have been working on a tool inside Microsoft for detecting add-ins in the Enterprise Environment (Microsoft Office System Add-in Scanner). When that tool is ready we will likely add it to the web somewhere with a white paper or something. Currently, the tool is still in beta and being used at about a half dozen customer sites.

The feedback from the tool and the workload with the workshop and my standard case load is keeping me buried at Microsoft. Oh, and personally I have a lot going on. My son is going to be 6 this summer, he is finishing up kindergarten and there is a whole book to talk about there – more on this later…

Anyway, you get the point… lots going on. Hot

williamWilliam Craig (5 y/o).Ā 

More on Gadgets….

My latest gadget project (which I have eluded to in previous posts) is called "Mycrocuts." My partner (a fellow Microsoftie – Matt Dyor) and I are still working on tweaking the specifications and making some changes to the data structure and advanced features. We started work on this back in September 2007 and at the current rate it may be another month or more before we release it to the world…as I have more information I will share it. I am chomping at the bit to share this with the community, but we want to make sure we get it working JUST right before we release it.

Where have IĀ beenā€¦

It has been a little over two months since I have updated my blog. But I am still here. smile_regularĀ 

I have been and am still working on a new gadget that is a joint project with a fellow Microsoftie. I have been fairly hush-hush about it, but it is now in a trial phase. For now we are still keeping it quiet. I hope that in the next month or so we can open this up to everyone on the web.

Several months ago, a fellow employee who really liked the idea of The Magic Folder came to me with an idea to create a somewhat related gadget, but with a very interesting spin. We started working together on hashing out the specifications and then completed the first fully functional Beta this week…we even entered it into a Science Fair at Microsoft (held today).

While it did not win the Science Fair, it did draw considerable excitement. I cannot wait to share it with everyone. smile_teeth In closing, I will leave you with a screen shot of the gadget and a short blurb on what it is about:

It is a gadget that helps you keep track of things and spans the desktop and the network.

image

Stay tuned – more coming soon… smile_wink