VB.NET 与 C# 有何不同之处:Excel 在控制台应用程序结束后退出而不显式释放任何内容?

t3c*_*b0t 3 c# vb.net office-automation office-interop .net-6.0

我有两个 .net-6 控制台应用程序:

C# 中的一个

using Excel = Microsoft.Office.Interop.Excel;

Console.WriteLine("Hello, World!");

var xl = new Excel.Application();
var wb = xl.Workbooks.Open(@"c:\temp\test-2.xlsx");

wb.Close(0);
xl.Quit();

System.Runtime.InteropServices.Marshal.ReleaseComObject(wb);
System.Runtime.InteropServices.Marshal.ReleaseComObject(xl);

wb = null;
xl = null;
Run Code Online (Sandbox Code Playgroud)

另一种是 VB.NET 中的。

Imports System
Imports Excel = Microsoft.Office.Interop.Excel

Module Program
    Sub Main(args As String())
        Console.WriteLine("Hello World!")

        Dim xl = New Excel.Application()
        Dim wb = xl.Workbooks.Open("c:\\temp\\test-2.xlsx")

        wb.Close(0)
        xl.Quit()

        'System.Runtime.InteropServices.Marshal.ReleaseComObject(wb)
        'System.Runtime.InteropServices.Marshal.ReleaseComObject(xl)

        'wb = Nothing
        'xl = Nothing


    End Sub
End Module
Run Code Online (Sandbox Code Playgroud)

两个控制台中的项目配置是相同的:

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net6.0</TargetFramework>
        <RootNamespace>OfficeInteropTest</RootNamespace>        
    </PropertyGroup>

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

</Project>
Run Code Online (Sandbox Code Playgroud)

当我运行它们中的每一个时,C# 应用程序在控制台退出后不会关闭 Excel,而 VB.NET 应用程序会关闭 Excel,即使我注释掉了最后四行。

所以,我想知道它们有什么不同之处,为什么 VB.NET 看起来更适合 Office 互操作?

t3c*_*b0t 5

事实证明的怀疑是正确的。VB.NETSTAThread隐式添加。我查看了 ILCode,结果如下:

.method public static void
    Main(
      string[] args
    ) cil managed
  {
    .entrypoint
    .custom instance void [System.Runtime]System.STAThreadAttribute::.ctor()
      = (01 00 00 00 )
    .maxstack 16
    .locals init (
      [0] class Microsoft.Office.Interop.Excel.Application xl,
      [1] class Microsoft.Office.Interop.Excel.Workbook wb
    )

    // [5 5 - 5 31]
    IL_0000: nop

    // [6 9 - 6 42]
    IL_0001: ldstr        "Hello World!"
    IL_0006: call         void [System.Console]System.Console::WriteLine(string)
    IL_000b: nop
Run Code Online (Sandbox Code Playgroud)

向 C# 应用程序添加该[STATHread]属性可解决应用程序退出后 Excel 保持打开状态的问题,并使最后四行变得不必要。