admin管理员组文章数量:1122832
I'm trying to come up with a simple "poke" .NET 9 class library project that I could call from a COM client (Classic ASP) without registering it.
When I build the project though, I'm not getting the .manifest
file output. According to Microsoft Docs I should get a ProjectName.X.manifest
file on build.
I must be skipping a simple step but I'm confused with the new ComWrappers Code Generation feature introduced in .NET 8.
So then I built a simple ASP.NET 9 project following the guidelines at:
- initial project setup: Expose .NET Core components to COM
- .NET 8 source generation feature: What's new in .NET 8 - Source-generated COM interop
- more on .NET 8 source generation: Source generation for ComWrappers
In an attempt to clean up most of the clutter (attributes) from the first article, I mixed-up the steps until I got a working project:
- create a new Class Library project:
mkdir testComLib
chdir testComLib
dotnet new classlib
- adjust
Class1.cs
with the minimal code (and interface in the same file for now)
Class1.cs
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
namespace testComLib;
[GeneratedComInterface]
[Guid("e9cbe871-533e-48b5-b33f-a296a98a51cc")] // generated with 'dotnet guid' (dotnet tool install -g dotnet-guid)
partial interface IClass1
{
int Poke(int count);
}
[GeneratedComClass]
public partial class Class1 : IClass1
{
public int Poke(int count) => count + 2;
}
- set up the project to allow Unsafe blocks (build required it) and also enable RegFreeCom:
testComLib.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<EnableRegFreeCom>true</EnableRegFreeCom>
</PropertyGroup>
</Project>
The actual change here is just the two last lines in the PropertyGroup
block:
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<EnableRegFreeCom>true</EnableRegFreeCom>
Build
dotnet build
The project is built and reported success
Restore complete (0.3s)
testComLib succeeded (1.9s) → bin\Debug\net9.0\testComLib.dll
Build succeeded in 2.7s
But when I look up bin/Debug/net9.0/
I only see:
testComLib.deps.json testComLib.dll testComLib.pdb
And of course, trying to reference this from VBScript (Classic ASP) with GetObject("c:\...\bin\Debug\net9.0\testComLib.dll", "Class1")
gives me a big ActiveX component can't create object: 'GetObject'
error.
I wanted to be able to use the RegFreeCom feature to allow for easier deployment of new and production versions of the driver in the host system and also development endpoints without the need to register the DLL in the whole system.
I might be a bit rusted off with the dotnet tool
but dotnet build --verbosity diag
says it's passing -verbosity:diag
to msbuild
but I get no verbose output at all. This might help me identify why the EnableRegFreeCom
target is not triggering
EDIT
In following three guidelines:
- @pfx's comment
- somebody's answer suggestion (which they deleted as it was not complete)
- the COMServerDemo project
I shall drop the [GeneratedComInterface]
and [GeneratedComClass]
attributes in favor of provinding two guids (one for interface and another for implementation), and [ComVisible(true)]
. And add <EnableComHosting>true</EnableComHosting>
to the project.
With this I get to the same foot of the mentioned COMServerDemo
(a working build with manifest). Then all that's left is being able to call it from a VBScript environment -- which is probably being cracked by @pfx's advice.
I'm trying to come up with a simple "poke" .NET 9 class library project that I could call from a COM client (Classic ASP) without registering it.
When I build the project though, I'm not getting the .manifest
file output. According to Microsoft Docs I should get a ProjectName.X.manifest
file on build.
I must be skipping a simple step but I'm confused with the new ComWrappers Code Generation feature introduced in .NET 8.
So then I built a simple ASP.NET 9 project following the guidelines at:
- initial project setup: Expose .NET Core components to COM
- .NET 8 source generation feature: What's new in .NET 8 - Source-generated COM interop
- more on .NET 8 source generation: Source generation for ComWrappers
In an attempt to clean up most of the clutter (attributes) from the first article, I mixed-up the steps until I got a working project:
- create a new Class Library project:
mkdir testComLib
chdir testComLib
dotnet new classlib
- adjust
Class1.cs
with the minimal code (and interface in the same file for now)
Class1.cs
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
namespace testComLib;
[GeneratedComInterface]
[Guid("e9cbe871-533e-48b5-b33f-a296a98a51cc")] // generated with 'dotnet guid' (dotnet tool install -g dotnet-guid)
partial interface IClass1
{
int Poke(int count);
}
[GeneratedComClass]
public partial class Class1 : IClass1
{
public int Poke(int count) => count + 2;
}
- set up the project to allow Unsafe blocks (build required it) and also enable RegFreeCom:
testComLib.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<EnableRegFreeCom>true</EnableRegFreeCom>
</PropertyGroup>
</Project>
The actual change here is just the two last lines in the PropertyGroup
block:
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<EnableRegFreeCom>true</EnableRegFreeCom>
Build
dotnet build
The project is built and reported success
Restore complete (0.3s)
testComLib succeeded (1.9s) → bin\Debug\net9.0\testComLib.dll
Build succeeded in 2.7s
But when I look up bin/Debug/net9.0/
I only see:
testComLib.deps.json testComLib.dll testComLib.pdb
And of course, trying to reference this from VBScript (Classic ASP) with GetObject("c:\...\bin\Debug\net9.0\testComLib.dll", "Class1")
gives me a big ActiveX component can't create object: 'GetObject'
error.
I wanted to be able to use the RegFreeCom feature to allow for easier deployment of new and production versions of the driver in the host system and also development endpoints without the need to register the DLL in the whole system.
I might be a bit rusted off with the dotnet tool
but dotnet build --verbosity diag
says it's passing -verbosity:diag
to msbuild
but I get no verbose output at all. This might help me identify why the EnableRegFreeCom
target is not triggering
EDIT
In following three guidelines:
- @pfx's comment
- somebody's answer suggestion (which they deleted as it was not complete)
- the COMServerDemo project
I shall drop the [GeneratedComInterface]
and [GeneratedComClass]
attributes in favor of provinding two guids (one for interface and another for implementation), and [ComVisible(true)]
. And add <EnableComHosting>true</EnableComHosting>
to the project.
With this I get to the same foot of the mentioned COMServerDemo
(a working build with manifest). Then all that's left is being able to call it from a VBScript environment -- which is probably being cracked by @pfx's advice.
1 Answer
Reset to default 0In order to effectively output the manifest file what I needed was, in summary:
- drop the .NET 8 source generation attributes (
[GeneratedComInterface]
and[GeneratedComClass]
inClass1.cs
) - add
<EnableComHosting>true</EnableComHosting>
to thetestComLib.csproj
project file - add the
[ComVisible(true)]
attribute to both class and interface - Create a new guid and add it to the
Class1
class as well.
Thus, from my original question, the changes are:
Class1.cs
using System.Runtime.InteropServices;
namespace testComLib;
[ComVisible(true)]
// One of these InterfaceTypeAttributes:
//[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
//[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
[Guid("e9cbe871-533e-48b5-b33f-a296a98a51cc")]
partial interface IClass1
{
int Poke(int count);
}
[ComVisible(true)]
[Guid("c15579a1-f57c-4a30-a6a6-629786cb1ee2")]
public partial class Class1 : IClass1
{
public int Poke(int count) => count + 2;
}
testComLib.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<EnableComHosting>true</EnableComHosting>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<EnableRegFreeCom>true</EnableRegFreeCom>
</PropertyGroup>
</Project>
And I can get the output I wanted, at least: the build process outputs more files, including the Manifest one:
testComLib.comhost.dll
testComLib.dll
testComLib.runtimeconfig.json
testComLib.deps.json
testComLib.pdb
testComLib.X.manifest
Now, getting the COM Server to talk to ol' ASP is another story. :`(
For the record, the output manifest is (formatted by me; it is output as a single line file)
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity
type="win32"
name="testComLib.X"
version="1.0.0.0"
/>
<file name="testComLib.comhost.dll">
<comClass
clsid="{c15579a1-f57c-4a30-a6a6-629786cb1ee2}"
threadingModel="Both"
progid="testComLib.Class1"
/>
</file>
</assembly>
I would still gladly mark as the chosen answer a solution using the .NET 8 source generation approach even though it could not be the one I use (for the IUknown
limitation pointed by @pfx).
本文标签: cNET 9 RegFree COM Class Library no manifestStack Overflow
版权声明:本文标题:c# - .NET 9 RegFree COM Class Library: no manifest - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736300926a1930996.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
orInterfaceIsIDispatch
for late binding. – pfx Commented Nov 22, 2024 at 22:12IsIUnknown
,IsDual
andIsIDispatch
) and still not callable from VBS; I'm not sure what I use inGetObject(path, name)
. There's thetestComLib.dll
,testComLib.comhost.dll
andtestComLib.X.manifest
containing `ProgID="testComLib.Class1". – Avenger Commented Nov 22, 2024 at 22:22