Skip to content

Conversation

@JesseCol
Copy link
Contributor

@JesseCol JesseCol commented Oct 23, 2025

  • Added create-addon --template=cs command that creates a C# add-on and installs the node-api-dotnet package.
  • Updated samples/electron to use a C# add-on as well. The sample uses AoT and works both unpackaged and packaged.
  • winsdk restore automatically updates package versions in Directory.packages.props to match winsdk.yaml.
  • Also I updated the icons for the samples/electron app.

The command and output looks like this:

PS D:\work\w> npx winsdk node create-addon --name myCsAddon --template=cs
📁 Creating addon directory: myCsAddon
✅ C# addon 'myCsAddon' created successfully!
📁 D:\work\w\myCsAddon

Next steps:
  1. npm run build-myCsAddon
  2. See myCsAddon/README.md for usage examples

Here's how to use it from Javascript:

// Load the C# module
const myCsAddon = require('./myCsAddon/build/Release/myCsAddon');

// Call exported methods (note: C# method names are converted to camelCase in JavaScript)
console.log(myCsAddon.Addon.hello('World'));
// Output: Hello from C#, World!

console.log(myCsAddon.Addon.add(5, 3));
// Output: 8

console.log(myCsAddon.Addon.getCurrentTime());
// Output: (current time)

Here's what the output looks like:

PS D:\work\w> node .\t.js
Hello from C#, World!
8
2025-10-22 17:36:15

@JesseCol
Copy link
Contributor Author

Oh, this does NOT use WinAppSDK yet, I'll try that next.

@JesseCol JesseCol self-assigned this Oct 23, 2025
@JesseCol JesseCol linked an issue Oct 23, 2025 that may be closed by this pull request
@JesseCol
Copy link
Contributor Author

Oh, this does NOT use WinAppSDK yet, I'll try that next.

Fixed now.

@azchohfi
Copy link
Collaborator

We need to make sure the generated .node file is actually self-contained.

@JesseCol
Copy link
Contributor Author

We need to make sure the generated .node file is actually self-contained.

I tested out the sample on a VM that doesn't have .net installed and I see it works fine. Also, I tested in the debugger to make sure it doesn't load any CLR/dotnet DLLs.

@JesseCol JesseCol changed the title Add create-cs-addon command that creates a C# add-on Add support for creating a C# addon to create-addon command Oct 28, 2025
Copy link
Contributor

@chiaramooney chiaramooney left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool! Once this gets merged, it would be great to add a page to Electron Gallery with a CS addon sample

@JesseCol
Copy link
Contributor Author

Cool! Once this gets merged, it would be great to add a page to Electron Gallery with a CS addon sample

Sure, sounds good!

Copy link
Member

@nmetulev nmetulev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Getting this error, make sure the cs-addon-utils.js is added to the package.json

Image

Also the template directory

Image

Could you also add a section in the generated Readme on how to call the api in JS? It took me more time that it should to figure out what script to import and how to call it.

@JesseCol
Copy link
Contributor Author

Hi @nmetulev thanks for testing!

Sorry I guess I'm still a node noob -- can you help me understand how you got that error? I've been running scripts\build-cli.ps1 to build the .tgz, but it seems like you're doing something different here?

Could you also add a section in the generated Readme on how to call the api in JS?

It does has that, it should look like the below. Does yours not have this?

=====

Using the Addon in JavaScript

After building, you can use the addon in your JavaScript code:

// Load the C# module
const csAddon = require('./csAddon/build/Release/csAddon');

// Call exported methods (note: C# method names are converted to camelCase in JavaScript)
console.log(csAddon.Addon.hello('World'));
// Output: Hello from C#, World!

console.log(csAddon.Addon.add(5, 3));
// Output: 8

console.log(csAddon.Addon.getCurrentTime());
// Output: (current time)

@nmetulev
Copy link
Member

I've been running scripts\build-cli.ps1 to build the .tgz, but it seems like you're doing something different here?

I'm doing the same, and then installing the generated tgz file in a new app to test it. To fix this, you need to add the folder and the js script you added to the package.json so they are included when we create the npm package:
image

@nmetulev
Copy link
Member

It does has that, it should look like the below. Does yours not have this?

Agh, I missed this, i had scrolled too far.

Though it is not working with const myCsAddon = require('./myCsAddon/build/Release/myCsAddon'); - I get this:
image

I had to reference it like so
image

@JesseCol
Copy link
Contributor Author

I've been running scripts\build-cli.ps1 to build the .tgz, but it seems like you're doing something different here?

I'm doing the same, and then installing the generated tgz file in a new app to test it.

That's what I'm doing to, I'm doing this in my new app:

D:\temp\t2>npm i --save-dev d:\winsdk-2\src\winsdk-npm

Are you doing something else? (I'm sure your suggestion is correct, I just want to make sure I know how to repro to make sure it's fixed)

@nmetulev
Copy link
Member

I've been running scripts\build-cli.ps1 to build the .tgz, but it seems like you're doing something different here?

I'm doing the same, and then installing the generated tgz file in a new app to test it.

That's what I'm doing to, I'm doing this in my new app:

D:\temp\t2>npm i --save-dev d:\winsdk-2\src\winsdk-npm

Are you doing something else? (I'm sure your suggestion is correct, I just want to make sure I know how to repro to make sure it's fixed)

Agh, no, I'm installing the generated package, not the folder. Do this npm i --save-dev d:\winsdk-2\artifacts\microsoft-winsdk-0.1.0-prerelease.xx.tgz

@JesseCol
Copy link
Contributor Author

Though it is not working with const myCsAddon = require('./myCsAddon/build/Release/myCsAddon'); - I get this:

@nmetulev great catch, thanks! Should be fixed now to point at the .node file.

Interesting, I think the location you found is pulling in the IL .dll file, not the AOT'd .node file. I'd love to know if it works for you when pointing to the .node file.

@nmetulev
Copy link
Member

@JesseCol, could you look at the conflict here?

@JesseCol
Copy link
Contributor Author

Thanks @nmetulev , looks like it needs reapproval (when you have a sec):

Waiting on 1 reapproval from someone other than the last pusher. Review from nmetulev is stale because it was submitted before the most recent code changes.

@nmetulev nmetulev merged commit 4c45653 into main Oct 31, 2025
7 checks passed
@nmetulev nmetulev deleted the jessecol/dotnet-addon-2 branch October 31, 2025 22:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[CLI] CLI has an option to add a new C# project to an existing node app

5 participants