dotnet / project-system

The .NET Project System for Visual Studio
MIT License
969 stars 387 forks source link

Incorrect COMReference entry when using Office interop #5735

Open JohnyL opened 4 years ago

JohnyL commented 4 years ago

To include Excel interop libraries in .NET Core app, I do the following: Dependencies -> Add Reference -> COM -> Microsoft Excel 14.0 Object Library. When I do this, I get the following ItemGroup:

<ItemGroup>
    <COMReference Include="Microsoft.Office.Excel.dll">
        <Guid>00020813-0000-0000-c000-000000000046</Guid>
        <VersionMajor>1</VersionMajor>
        <VersionMinor>7</VersionMinor>
        <WrapperTool>tlbimp</WrapperTool>
        <Lcid>0</Lcid>
        <Isolated>false</Isolated>
    </COMReference>
</ItemGroup>

However, I get the following runtime error:

Unhandled exception. System.IO.FileNotFoundException: Could not load file or assembly 'office, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c'. The system cannot find the file specified.

In order to work, I have created .NET Framework app, added COM reference there and copied its COMReference - and it works:

<ItemGroup>
    <COMReference Include="Microsoft.Office.Interop.Excel">
        <Guid>{00020813-0000-0000-C000-000000000046}</Guid>
        <VersionMajor>1</VersionMajor>
    <VersionMinor>7</VersionMinor>
    <Lcid>0</Lcid>
    <WrapperTool>primary</WrapperTool>
    <Isolated>False</Isolated>
    <EmbedInteropTypes>True</EmbedInteropTypes>
    </COMReference>
</ItemGroup>

As noted here, in order to fix the situation, the project system needs to add <EmbedInteropTypes>True</EmbedInteropTypes>.

drewnoakes commented 4 years ago

Repro steps:

  1. New netcoreapp3.1 console application
  2. Right-click Dependencies node
  3. Select "Add Reference..."
  4. Select "COM"
  5. Select "Microsoft Excel 16.0 Object Library"
  6. Reference a type within code (e.g. Microsoft.Office.Interop.Excel.Chart)
  7. Try to run the console app. It fails as described.
  8. Add <EmbedInteropTypes>True</EmbedInteropTypes>
  9. Running now works

netcoreapp3.1

  <ItemGroup>
    <COMReference Include="Microsoft.Office.Excel.dll">
      <Guid>00020813-0000-0000-c000-000000000046</Guid>
      <VersionMajor>1</VersionMajor>
      <VersionMinor>9</VersionMinor>
      <WrapperTool>tlbimp</WrapperTool>
      <Lcid>0</Lcid>
      <Isolated>false</Isolated>
    </COMReference>
  </ItemGroup>

net471

  <ItemGroup>
    <COMReference Include="Microsoft.Office.Core">
      <Guid>{2DF8D04C-5BFA-101B-BDE5-00AA0044DE52}</Guid>
      <VersionMajor>2</VersionMajor>
      <VersionMinor>8</VersionMinor>
      <Lcid>0</Lcid>
      <WrapperTool>primary</WrapperTool>
      <Isolated>False</Isolated>
      <EmbedInteropTypes>True</EmbedInteropTypes>
    </COMReference>
    <COMReference Include="Microsoft.Office.Interop.Excel">
      <Guid>{00020813-0000-0000-C000-000000000046}</Guid>
      <VersionMajor>1</VersionMajor>
      <VersionMinor>9</VersionMinor>
      <Lcid>0</Lcid>
      <WrapperTool>primary</WrapperTool>
      <Isolated>False</Isolated>
      <EmbedInteropTypes>True</EmbedInteropTypes>
    </COMReference>
    <COMReference Include="VBIDE">
      <Guid>{0002E157-0000-0000-C000-000000000046}</Guid>
      <VersionMajor>5</VersionMajor>
      <VersionMinor>3</VersionMinor>
      <Lcid>0</Lcid>
      <WrapperTool>primary</WrapperTool>
      <Isolated>False</Isolated>
      <EmbedInteropTypes>True</EmbedInteropTypes>
    </COMReference>
  </ItemGroup>
JohnyL commented 4 years ago

Beg your pardon - I forgot to mention that this happens in .NET Core.

JohnyL commented 4 years ago

I have found out that if you use <WrapperTool>tlbimp</WrapperTool>, then interop types won't be embedded and Excel DLL is copied into app's folder, but if you use <WrapperTool>primary</WrapperTool>, then types will be embedded and Excel DLL is not copied into app's folder (of course, <EmbedInteropTypes>true</EmbedInteropTypes> must exist).

shanselman commented 4 years ago

I'm hitting this, just as above, in Sept of 2020. @davkean

Seems like you can't do Office Interop with Core unless you do the com reference manually?

Tooling does this (wrong:)

    <COMReference Include="Microsoft.Office.PowerPoint.dll">
      <Guid>91493440-5a91-11cf-8700-00aa0060263b</Guid>
      <VersionMajor>2</VersionMajor>
      <VersionMinor>12</VersionMinor>
      <WrapperTool>tlbimp</WrapperTool>
      <Lcid>0</Lcid>
      <Isolated>false</Isolated>
    </COMReference>
  </ItemGroup>

Correct:

    <COMReference Include="Microsoft.Office.Interop.PowerPoint">
      <Guid>{91493440-5a91-11cf-8700-00aa0060263b}</Guid>
      <VersionMajor>2</VersionMajor>
      <VersionMinor>12</VersionMinor>
      <WrapperTool>primary</WrapperTool>
      <Lcid>0</Lcid>
      <Isolated>false</Isolated>
      <EmbedInteropTypes>True</EmbedInteropTypes>
    </COMReference>
  </ItemGroup>
JohnyL commented 4 years ago

@shanselman Your correct variant is correct. 😉 This is what COMReference should have: 1) The value of <WrapperTool> must be primary. 2) <EmbedInteropTypes>True</EmbedInteropTypes> must be present. 3) The .dll extension in the end of file name (in Include attribute) is arbitrary.

cartermp commented 4 years ago

As per a chat with @shanselman this is popping up in multiple places:

https://github.com/dotnet/msbuild/issues/4332 https://github.com/dotnet/msbuild/issues/3986

Is the root problem the VS tooling or the MSBuild issue?

davkean commented 4 years ago

This is a CPS bug, we should get a Developer feedback item filed and moved to them.

tmeschter commented 3 years ago

@JohnyL, @shanselman: I've investigated and established several issues at this point:

  1. The Include differs from what was generated in a .NET Framework project.
  2. The EmbedInteropTypes metadata is not being added.
  3. Once added, EmbedInteropTypes is not fully respected in a .NET Core 3.1 project.

We're going to fix 1 & 2 in the project system (though 1 is minor as the Include is just a friendly name for the benefit of the developer). Issue 3 is being tracked by dotnet/msbuild#5959.

tmeschter commented 3 years ago

For .NET Core 3.1 projects, you can workaround the problem with EmbedInteropTypes not being fully respected by adding <Private>false</Private> metadata to the item.

.NET 5 projects do not seem to have the same issue.

qrli commented 3 years ago

Also encountered this. The solution mentioned here works, except for Workbook.Queries and WorkbookQuery, which will be magically missing when <WrapperTool>primary</WrapperTool>. But they can be successfuly resolved when <WrapperTool>tlbimp</WrapperTool>

I just upgraded to .NET 5.0.

ricphiri commented 3 years ago

It's April 2021, using .Net 5 and the problem still exists. I just used the solution in @shanselman's post to work on Excel.

For quick reference:

Are there any plans to fix this in the tooling?

ULTRAKKK1004 commented 2 years ago

I had same issue using .net5 and .net6

But now I can use excel when using .net5/6

  1. Don't use Nuget Microsoft.Office.Interop.Excel pakage -> nuget's microsoft.office.interop.excel package is fine when using .net framework but .net5/6
  2. Just add "excel.exe file" to Reference. That's ok.
  3. Of cource, you should use using things. (using Microsoft.Office.Interop.Excel;)
JohnyL commented 2 years ago

@ULTRAKKK1004 Beg your pardon, but understood nothing what you were trying to say.

ULTRAKKK1004 commented 2 years ago

@JohnyL check url below. https://smithkorea.blogspot.com/2022/04/solved-could-not-load-file-or-assembly.html

You are making winform app using .net core, Right? I've just checked it works.

Just add Excel.exe file to Reference. (It's Not Nuget-Microsoft.Office.Interop.Excel, just Excel.exe file)

image

image

JohnyL commented 2 years ago

@ULTRAKKK1004 This doesn't work either: FSharp_Excel_does_not_work

ULTRAKKK1004 commented 2 years ago

@JohnyL Hmm. Let me know your environment.(I've just checked you used F#........) In F# case, it doesn't work....I checked... My case was C#.

I tested vs2022/vs2019, c#, .net core3.1, winform/console. Office version is 2019.

c# console: image

c# winform: image

ULTRAKKK1004 commented 2 years ago

@JohnyL fine. in f# case, add more files.....to reference... office.dll and Microsoft.Office.Interop.Excel.dll (they are in office folder)

office.dll and Microsoft.Office.Interop.Excel.dll image

Adding to Reference Manager image

Result.(same code with JohnyL but it works.) image

ashwiniuchit commented 2 years ago

Add below references for the project.

image

ULTRAKKK1004 commented 2 years ago

@ashwiniuchit Oh. Thanks

mathewseduardo commented 7 months ago

March 2024, There is my solution (net core 7, Excel v16):

`

tlbimp 9 1 00020813-0000-0000-c000-000000000046 0 false true

`

Its works, in Win 64 bits.

Flohack74 commented 4 months ago

@shanselman while the COMReference works fine for my local build machine, it breaks when Excel is not installed, which is the case for our CI machines in Azure Devops. How can we achieve to build this correctly, given that its impossible to install Office/Excel on those agents? Thanks for any insights :)