How to use Office from Visual Studio C#?

2019-03-18 14:54发布

问题:

The technique for adding a reference to the COM interop of Office in Visual Studio is to go to:

  1. References
  2. Add Reference
  3. Select the COM tab
  4. Select Microsoft Office 11.0 Object Library

And magically named reference appears:

Microsoft.Office.Core

The Project.csproj file shows the details of the reference:

<COMReference Include="Microsoft.Office.Core">
   <Guid>{2DF8D04C-5BFA-101B-BDE5-00AA0044DE52}</Guid>
   <VersionMajor>2</VersionMajor>
   <VersionMinor>3</VersionMinor>
   <Lcid>0</Lcid>
   <WrapperTool>primary</WrapperTool>
   <Isolated>False</Isolated>
</COMReference>

And the project is checked into source control and all is well.


Then a developer with Office 2007 gets the project from source control, and cannot build it because such a reference doesn't exist.

He (i.e. me) checks out the .csproj file, deletes the reference to

Microsoft Office 11.0 Object Library

and re-adds the COM reference as

Microsoft Office 12.0 Object Library

And magically a named reference appears:

Microsoft.Office.Core

The Project.csproj file shows the details of the reference:

<COMReference Include="Microsoft.Office.Core">
  <Guid>{2DF8D04C-5BFA-101B-BDE5-00AA0044DE52}</Guid>
  <VersionMajor>2</VersionMajor>
  <VersionMinor>4</VersionMinor>
  <Lcid>0</Lcid>
  <WrapperTool>primary</WrapperTool>
  <Isolated>False</Isolated>
</COMReference>

And the project is checked into source control and all is well.


Then a developer with Office 2003 gets the project from source control, and cannot build it because such a reference doesn't exist.

He (i.e. not me) checks out the .csproj file, deletes the reference to

Microsoft Office 12.0 Object Library

and re-adds the COM reference as

Microsoft Office 11.0 Object Library

And magically a named reference appears:

Microsoft.Office.Core

The Project.csproj file shows the details of the reference:

<COMReference Include="Microsoft.Office.Core">
  <Guid>{2DF8D04C-5BFA-101B-BDE5-00AA0044DE52}</Guid>
  <VersionMajor>2</VersionMajor>
  <VersionMinor>3</VersionMinor>
  <Lcid>0</Lcid>
  <WrapperTool>primary</WrapperTool>
  <Isolated>False</Isolated>
</COMReference>

And the project is checked into source control and all is well.

Then the project is built, pressed onto CDs, and sent to the customers who have Office 2007.

And all is not well.


In the olden days (i.e. before .NET dll hell), we would reference the Office objects using a version independant ProgID, i.e.:

"Excel.Application"

which resolves to a clsid of the installed Office, e.g.

{00024500-0000-0000-C000-000000000046}    

of which a class is then constructed using a call to COM (language-netural pseudo-code):

public IUnknown CreateOleObject(string className)
{
    IUnknown unk;

    Clsid classID = ProgIDToClassID(className);
    CoCreateInstance(classID, null, 
          CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER, 
          IUnknown, out unk);

    return unk;
}

Questions

1) What is the approved technique to automate the installed Office applications?

2) What are the Office 2003 Primary Interop Assemblies useful for?

3) If i use the Office 2003 Primary Interop Assemblies, do i have to have office 2003 installed?

4) If i build with the Office 2003 Primary Interop Assemblies, are my customers tied to Office 20003 forever?

5) Are there any Office 2007 Primary Interop Assemblies?

6) If i install the Office 2007 Primary Interop Assemblies do i have to have Office 2007 installed?

7) What is wrong with using standard COM interop to drive Excel, Word, or Outlook? e.g.:

[ComImport]
[Guid("00024500-0000-0000-C000-000000000046")]
public class Excel
{
}

8) What is one achieving when one adds a

  • Reference to items on the COM tab,
  • as opposed to using [ComImport],
  • as opposed to using the Office 2007 Primary Interop Assemblies?

9) Is adding a reference using the COM tab identical to using COM interop, except that it needs a type library before you can see it?

10) Are the Office 2003 Primary Interop Assemblies backwards and forwards compatible with: - Office 14 - Office 2007 - Office 2003 - Office XP - Office 2000 - Office 97 - Office 95

If a customer, and a developer, installs a new version of Office, will it still work?

11) Do we have to ship the Office 2003 Primary Interop Assemblies with our application?

12) Does the customer have to install the Office 2003 Primary Interop Assemblies before they can use our application?

13) If a customer installs the Office 2003 Primary Interop Assemblies do they have to have Office installed?

14) If a customer installs the Office 2003 Primary Interop Assemblies do they have to have Office 2003 installed?

15) Are the Office 2003 Primary Interop Assembles a free, lite, redistributable version of Office 2003?

16) If my development machine has Office 2007, can i use the Office 2003 PIAs, and ship to a customer with Office XP installed?

回答1:

Wow that's a huge number of questions. I think that in general if your app is using the PIAs then you're assuming that your target audience has some version of Office installed. The PIAs will be installed in the GAC when the target user installs Office. If they don't have Office installed then why are you targeting Office?

Yes, the Office dlls are the correct way to automate Office. There's a list of the assemblies here, including some for Office 2007.



回答2:

The answer is to "Copy Local" whatever assembly dll you get for the interop. Once you have the assembly dll in your output folder, add a reference to it, and check it into source control.

Now everyone has the referenced assembly dll.



回答3:

do you use VSTO (Visual studio tools for office)?

http://msdn.microsoft.com/en-us/office/aa905533.aspx



回答4:

An old thread, and probably most people would be happy with CopyLocal=True, however here's another way.. Use both (or more..? thinking Office 2010 if the problem still exists..) references in your project files, and either ignore or just tell MSBuild to ignore the "MSB3284" warning (Library not found). So include this in your .csproj file:

<COMReference Include="Microsoft.Office.Core">
   <Guid>{2DF8D04C-5BFA-101B-BDE5-00AA0044DE52}</Guid>
   <VersionMajor>2</VersionMajor>
   <VersionMinor>3</VersionMinor>
   <Lcid>0</Lcid>
   <WrapperTool>primary</WrapperTool>
   <Isolated>False</Isolated>
</COMReference>

Followed by:

<COMReference Include="Microsoft.Office.Core">
   <Guid>{2DF8D04C-5BFA-101B-BDE5-00AA0044DE52}</Guid>
   <VersionMajor>2</VersionMajor>
   <VersionMinor>4</VersionMinor>
   <Lcid>0</Lcid>
   <WrapperTool>primary</WrapperTool>
   <Isolated>False</Isolated>
</COMReference>

I would be interested to see if Microsoft provides a NuGet library for this - just to get everyone on to the same approach. I think that would remove the necessity for people to search the web for these answers... I believe this would be against Microsoft Office's license so they are the only ones to supply it.

BTW with copy local you have to be careful not to redistribute these library by mistake.