Making an existing VS add-in office-ready

M

Mark

This was originally posted in the vs extensibility group, but I was directed
over here. Any tips would be appreciated...

Thanks
Mark

Hi Jialiang...

I guess I should ask my questions differently. I did more research and
found that EnvDTE._DTE *is* the VS-specific implementation.

I tried loading it in Word with COM Add-ins, and Word put up a dialog box
saying the dll wasn't a valid add-in - but not why.

I tried attaching a debugger to Word and then loading it with a breakpoint
in my OnConnect(), but when I tried COM Add-ins, the debugger threw an error
saying the app was requesting a different framework than I was debugging
(VS2005, so framework 2.0).

I tried using Filemon to see what was accessed when Word tried to use COM
Add-ins; to my surprised I saw no entries in Filemon for my dll. Only
userenv.log, but nothing in that log had anything to do with my .dll.

So my questions:
1) What kind of object is passed to OnConnect() when the call is coming from
an Office application?

2) What kind of actions does it support? The examples show adding a button
to a toolbar, but my plugin a) tried to add new entries to the File menu and
b) tries to inject a handler on File > Save As...

3) As I mentioned before, the only things in _DTE we're using are
ActiveDocument, ItemOperations.OpenFile(), and a handler on Save As... Does
the OnConnect() object passed in by Office support these basic features?

4) What version of the framework is Word trying to launch when it does a COM
add-in? I have my dll registered with regasm.

5) In Word with the COM Add-ins, is there any way of finding out what
exactly it didn't like about the dll?

Thanks
Mark
 
J

Jialiang Ge [MSFT]

Hello Mike

I have replied to you with the answers for the questions in the original
vsx thread. For your conveniences, I paste the reply here. Regarding the
vsx -> Office case, I think that we can continue the discussion in either
newsgroup.


Hello Mark

I performed more researches of writing shared add-in for Office, and find
this KB article that can answer one of your questions:

PRB: Visual Studio .NET Shared Add-in Is Not Displayed in Office COM
Add-ins Dialog Box
http://support.microsoft.com/kb/316723
(Please note: the term "Visual Studio .NET Shared Add-in" in this article
means a Shared Add-in written using Visual Studio. It is not an add-in to
be loaded and run in Visual Studio)

It explains the "Path of add-in is not a valid Office add-in." error from
Office when the add-in is written in .NET language. The Office user
interface (UI) does not provide options to directly load a .NET shared
Add-in DLL; to do this, run Setup for the .NET Shared Add-in. The setup
project is created together with the creation of Shared Add-in project in
Visual Studio / Other Project Types / Extensibility / Shared Add-in.
However, the setup project is not available in a Visual Studio Add-in
project (Visual Studio / Other Project Types / Extensibility / Visual
Studio Add-in) due to the different setup model. In order that a Visual
Studio Add-in can also be used in Office, I think that we need to write
such a setup project by ourselves.

After trials and tests, I finally built a shared add-in for both Visual
Studio and the Office applications. The steps are shared at the bottom of
the message. Please go through them and let me know whether they are useful.


===================================
Answers for the questions

1) What kind of object is passed to OnConnect() when the call is coming
from
an Office application?

It is the Application interface of the current Office application. For
example, if the host is Office Word and if you are writing .NET code, the
interface passed to OnConnect is Microsoft.Office.Interop.Word.Application.
http://msdn.microsoft.com/en-us/library/microsoft.office.interop.word.applic
ation.aspx

If the host application is Office Excel, the interface is
Microsoft.Office.Interop.Excel.Application.
http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.appli
cation.aspx

If the host application is Visual Studio, the interface is EnvDTE._DTE
http://msdn.microsoft.com/en-us/library/envdte._dte.aspx

These interfaces (Word.Application, Excel.Application, EnvDTE._DTE) are
related to their own object models (Word Object Model, Excel Object Model,
Visual Studio Object Model) and are completely not compatible with each
other.

2) What kind of actions does it support? The examples show adding a button
to a toolbar, but my plugin a) tried to add new entries to the File menu
and
b) tries to inject a handler on File > Save As...

To add a new entry to File menu (specifically, the file menu before Office
2007. In Office 2007, the UI model is changed completely: Ribbon UI, and
its programming model is also changed. If you want more info about
customizing Office Ribbon UI, please refer to this article
http://msdn.microsoft.com/en-us/library/aa338202.aspx, or please open a new
discussion thread), we can extend the sample in
http://support.microsoft.com/kb/302901:

First we get the File menu object using Application.CommandBars["File"]
(The KB sample retrieves the Standard toolbar using oStandardBar =
oCommandBars["Standard"];), then we add a control to the menu in the same
way as what the KB sample does for the Standard toolbar (MyButton =
(CommandBarButton)oStandardBar.Controls["My Custom Button"];).

To inject a handler on File > Save As,

For Office 2003 menu:
Please refer to this discussion that I once handled one year ago.
http://www.eggheadcafe.com/software/aspnet/31049219/documentbeforesave-event
.aspx
It has three workarounds for your references.

For Office 2007 Ribbon:
http://blogs.msdn.com/vsto/archive/2008/07/03/catching-save-or-saveas-in-wor
d-2007.aspx

3) As I mentioned before, the only things in _DTE we're using are
ActiveDocument, ItemOperations.OpenFile(), and a handler on Save As... Does
the OnConnect() object passed in by Office support these basic features?

Office applications provide the same functionality as these, but in a
different object model. For Word, the active document is referred by
Application.ActiveDocument (its type is
Microsoft.Office.Interop.Word.Document); For Excel, the active workbook is
referred by Application.ActiveWorkbook (its type is
Microsoft.Office.Interop.Excel.Workbook).

To open a file (OpenFile), for Word, it is Application.Documents.Open; for
Excel, it is Application.Workbooks.Open.

4) What version of the framework is Word trying to launch when it does a
COM
add-in? I have my dll registered with regasm.

Office Add-in supports all the versions of .NET framework. The most
commonly used version is .NET runtime 2 (i.e .NET framework 2, 3, 3.5). The
tool regasm is the right one to register a .NET assembly as COM. You can
also specify the Register option to be vsdrpCOM in a setup project of the
add-in (see my sample below).

5) In Word with the COM Add-ins, is there any way of finding out what
exactly it didn't like about the dll?

Do you mean the error "Path of add-in is not a valid Office add-in"? Please
refer to the KB article http://support.microsoft.com/kb/316723 and my
analysis at the beginning of the message.

===================================
Additional Readings:

Visual Studio Add-ins vs. Shared Add-ins
(The comparison between Visual Studio Add-ins and Shared Add-ins)
http://msdn.microsoft.com/en-us/library/ms165620.aspx


===================================
Build a shared add-in for Visual Studio and Office applications

Step1. Create a Visual Studio Add-in (Visual Studio / Other Project Types /
Extensibility / Visual Studio Add-in) named SharedAddin. In the resulting
Connect.cs file, change these lines:

private DTE2 _applicationObject;
private AddIn _addInInstance;

_applicationObject = (DTE2)application;
addInInstance = (AddIn)addInInst;

to

private object _applicationObject;
private object _addInInstance;

_applicationObject = application;
_addInInstance = addInInst;

This step is very necessary because the interfaces EnvDTE.DTE2 and
EnvDTE.AddIn are not valid is the host is an Office application. Changing
the type as object allows us to detect the type in runtime.

Step2. Add the references of Word and Excel PIA

Right click the project / Add References / COM, and add "Microsoft Excel
12/11.0 Object Library" and "Microsoft Word 12/11.0 Object Library".

At the beginning of Connect.cs, add these "using" lines:
using Word = Microsoft.Office.Interop.Word;
using Excel = Microsoft.Office.Interop.Excel;

Step3. Detect the host application in runtime.

Add these codes in OnConnection:

if (application is Excel.Application)
{
MessageBox.Show("The Host Application is Office Excel");
}
else if (application is Word.Application)
{
MessageBox.Show("The Host Application is Office Word");
}
else if (application is DTE2)
{
MessageBox.Show("The Host Application is Visual Studio");
}

The code snippet detects the current host application, and pops up a
message box when the Add-in is loaded.

Step4. Add a setup project so that the Visual Studio Add-in can be ported
to the Office applications.

Add a Visual Studio Add New Project / Other Project Types / Setup and
Deployment / Setup Project named SharedAddinSetup. Right-click the
resulting project, and select Add / Project Output / Primary output of
SharedAddin. After doing this, select "Primary output from SharedAddin
(Active), and open its Property. Find the option "Register" and set it to
be vsdrpCOM.

Right-click the setup project again, and select View / Registry. Add these
keys:

[HKEY_CURRENT_USER\Software\Microsoft\Office\Word\Addins\SharedAddin.Connect
]
Add a DWORD value "LoadBehavior = 3", two string values "Description" =
"SharedAddin Description", "FriendlyName" = "SharedAddin Name" to the key.

[HKEY_CURRENT_USER\Software\Microsoft\Office\Excel\Addins\SharedAddin.Connec
t]
Add a DWORD value "LoadBehavior = 3", two string values "Description" =
"SharedAddin Description", "FriendlyName" = "SharedAddin Name" to the key.

Step5. Build both SharedAddin and SharedAddinSetup projects. (If UAC is
enabled, you would probably need to run Visual Studio as administrator)

Step6. Install the resulting setup.exe. In step2 of the setup, select to
install the add-in for "Just me". Open Office Word, Excel and Visual Studio
after the setup. On my side, I get the message boxes "The Host Application
is Office Excel/Word/Visual Studio" as expected. In other words, the Shared
Add-in for Visual Studio, Word, Excel is built successfully.

If you want to extend the sample to do more things like addin a command
bar, we can do it in

if (application is Excel.Application)
{
MessageBox.Show("The Host Application is Office Excel");
}
else if (application is Word.Application)
{
MessageBox.Show("The Host Application is Office Word");
}
else if (application is DTE2)
{
MessageBox.Show("The Host Application is Visual Studio");
}

using the host application's object model respectively. Please note: Word
and Excel shared the object model of Command Bar. Visual Studio has its own
Command Bar object model.


I sincerely hope that the above information can get you started to make the
existing VS add-in office ready. If you have any other questions or
concerns, please feel free to tell me.

Regards,
Jialiang Ge ([email protected], remove 'online.')
Microsoft Online Community Support

=================================================
Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

This posting is provided "AS IS" with no warranties, and confers no rights.
=================================================
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top