Container Office in Hong Kong: https://commons.wikimedia.org/wiki/File:Container_office.jpg

Caution 1: This article was written just for fun. Microsoft never guarantees the Office works best in the Windows container environment. Also, Microsoft can break the feature described in this article without any notice at any time. So, please don’t too rely on this article.

Caution 2: You cannot run the Microsoft Office container for any kind of internet and intranet services due to license restrictions of the software. Please refer to the license description at Microsoft. Either this container works or not, please test this feature just for fun.

A Story About Office Automation

Microsoft Office is the best seller software for a long time. And this software became essential in every people’s life.

Microsoft Office is famous for its fluent and unique interfaces. Not only that, but Office also shines when users can adopt automation features. However, these automation features are not suitable for traditional server scenarios. Both performance and license aspects.

As an alternative, Microsoft releases OOXML format SDK to the public, and lots of third parties and open source projects adopted OOXML and publishes its SDKs. No matter what, Microsoft Office always wins because they develop their features. So if you want to stick with the latest highlights of Office, you will have to install the Microsoft Office inevitably.

A quick question comes up here; If the Microsoft Office can run in a Windows container, is it neat, right? But we don’t know does the Windows container supports Microsoft Office. Also, the installation will not easy in an automated way.

Digging Up

Recently, the beginning of Windows Server 2019 (1809), a Full-fledged version of Windows container image, has published. This image contains almost all of the components for supporting and running the Office. Sadly, despite this condition, users still cannot interact with the application within a container. However, with this image, the app can persist and process its message loop.

Also, the recent version of Microsoft Office can be customized and automated with the Office Deployment Toolkit (a.k.a. ODT). You can write your own ODT configuration file with XML syntax, and this will work fine on the container.

In this article, I tested with the Windows Server version 1903 container.

Writing ODT File

At first, I wrote an ODT file named config.xml to install a 32-bit version of Office 2019 automatically.

<Configuration>

<Add OfficeClientEdition="32" Channel="PerpetualVL2019">

<Product ID="ProPlus2019Volume">

<Language ID="ko-kr" />

</Product>

</Add>

<Display Level="None" AcceptEULA="TRUE" />

<Property Name="AUTOACTIVATE" Value="1"/>

</Configuration>

There is no unusual thing, but the point is, I used the 32-bit version of Office 2019 as a perpetually licensed version, not Office 365.

Writing Dockerfile

I wrote a Dockerfile that downloads the ODT from the Microsoft Download Center and runs the installation based on the config.xml file.

FROM mcr.microsoft.com/windows:1903 AS build

ADD

RUN odtsetup.exe /quiet /norestart /extract:C:\\odtsetup WORKDIR C:\\odtsetupADD https://download.microsoft.com/download/2/7/A/27AF1BE6-DD20-4CB4-B154-EBAB8A7D4A7E/officedeploymenttool_11617-33601.exe odtsetup.exeRUN odtsetup.exe /quiet /norestart /extract:C:\\odtsetup FROM mcr.microsoft.com/windows:1903 AS download WORKDIR C:\\odtsetup

COPY --from=build C:\\odtsetup\\setup.exe .

ADD config.xml .

RUN setup.exe /download C:\\odtsetup\\config.xml FROM mcr.microsoft.com/windows:1903

MAINTAINER rkttu WORKDIR C:\\odtsetup

COPY --from=build C:\\odtsetup\\setup.exe .

COPY --from=download C:\\odtsetup\\Office .

ADD config.xml .

RUN setup.exe /configure C:\\odtsetup\\config.xml WORKDIR /

RUN rmdir /s /q C:\\odtsetup https://stackoverflow.com/questions/10837437/interop-word-documents-open-is-null

RUN powershell -Command new-object -comobject word.application

RUN mkdir C:\\Windows\\SysWOW64\\config\\systemprofile\\Desktop RUN powershell -Command new-object -comobject word.applicationRUN mkdir C:\\Windows\\SysWOW64\\config\\systemprofile\\Desktop VOLUME C:\\data

I tried many times to implement this Dockerfile. When I tried to install the Office 365 x64, the installer goes weird or simply fails and return non-zero code, which leads to building image fail.

The last two lines are required to run the Microsoft Office application correctly in the container. I will explain it.

I cannot see what’s going on because there is no user interface, but the Word.Application COM object should initiate at least one time for continuing the rest steps.

COM object should initiate at least one time for continuing the rest steps. If the Desktop directory does not exist in the user profile directory, the COM object returns null reference when the open file method called. I added a related link to the Stackoverflow web site.

Please remember, as I said at the first paragraph, Microsoft can update the Office, and this may lead to breaking change, which affects this article.

Let’s build the Office container with a command. Be sure to check the Docker Desktop for Windows is running.

docker build -t o365full:latest .

Writing an app that converts DOCX document into PDF file

After the container image built successfully, you can put the C# application, which uses the Office Primary Interop Assembly (a.k.a. PIA) interface, and converting the DOCX document into PDF file.

// Requires office.dll and word interop pia.dll from GACusing Microsoft.Office.Interop.Word;

using System;

using System.IO;

using System.Linq;namespace OfficePIATest

{

internal static class Program

{

[STAThread]

public static void Main(string[] args)

{

var input = args.ElementAtOrDefault(0) ?? string.Empty;

var output = args.ElementAtOrDefault(1) ?? string.Empty;if (!File.Exists(input))

{

Console.Error.WriteLine("Cannot open the file `{0}`.", input);

Environment.Exit(1);

return;

}if (string.IsNullOrWhiteSpace(output))

{

Console.Error.WriteLine("Invalid output path.");

Environment.Exit(2);

return;

}var outputDir = Path.GetDirectoryName(output);

if (!Directory.Exists(outputDir))

Directory.CreateDirectory(outputDir);var wordApp = new Application();

Console.Out.WriteLine("word app initialized.");Document wordDocument = null;

var t = new System.Threading.Tasks.Task(() => wordDocument = wordApp.Documents.Open(input));

t.Start();

t.Wait();if (wordDocument == null)

{

Console.Error.WriteLine("Word document is null reference.");

Environment.Exit(3);

return;

}

else

Console.Out.WriteLine("Word document opened.");wordDocument.ExportAsFixedFormat(output, WdExportFormat.wdExportFormatPDF);

Console.Out.WriteLine("Export performed.");wordDocument.Close(WdSaveOptions.wdDoNotSaveChanges,

WdOriginalFormat.wdOriginalDocumentFormat,

false); //Close document

Console.Write("Closing document");wordApp.Quit(); //Important: When you forget this Word keeps running in the background

Console.Out.WriteLine("Quitting word app.");

}

}

}

To build this code, you need Office PIA DLLs. When you install the Office, PIA will automatically place it into the %windir%\Assembly\GAC_MSIL directory. Plus, you need the Office assembly and Microsoft.Office.Word library, respectively.

Also, there is an important point when you build this code. You should compile this application as x86 application — or — set the 32-bit preferred application. We installed the 32-bit Microsoft Office into a container, so we should respect this configuration.

Build your executable file and add it with a sample document file into a container. Add the below line at the end of the Dockerfile, and add the Sample directory and place your sample documents for testing.

Let’s assume that the executable file name is ‘OfficePIATest.exe,’ and the sample document placed in the directory ‘Sample’ has a name ‘demo.docx.’

ADD sample .

Then let’s build the docker image.

docker build -t o365full:latest .

Please refer to this GIST code for reference.

Testing

You can run a container with a directory mount. The sample application will create the PDF file on the mounted directory.

docker run -v %cd%\data:c:\data --rm -it --name=o365fulltest o365full:latest cmd

In the container environment, let’s run this command.

OfficePIATest.exe C:\demo.docx C:\data\test.pdf

Then the PDF file created like below!

Voila! Microsoft Word in the container converting the sample document into a PDF file.

Conclusion

You can convert the Word document into PDF more efficiently and effectively in various ways. But as you can see, this container can run the application which relies on the Office PIA assembly.

I said earlier, despite, Office is not a server application, and you cannot use the Office like this way, so you cannot, and you should not use this Windows container.

But Windows container quite more evolved, so there are more applications can be transformed into the Windows container. I want to share this fun factor with you with a small portion of the article.

If you have any feedback or suggestion, please write down as a response. 😀