CounterStrikeSharp icon indicating copy to clipboard operation
CounterStrikeSharp copied to clipboard

"Could not load plugin" when using AspNetCore / WebApplication.CreateBuilder

Open wiesendaniel opened this issue 1 year ago • 12 comments

Thanks for creating this awesome framework. Has been a lot of fun to play around with so far.

I wanted to test adding some HTTP endpoint to a plugin, which did not work as expected. My expectations might be off tho as I'm rather new to dotnet/c#.

Issue

Plugin can not be loaded if Microsoft.AspNetCore.Builder / WebApplication.CreateBuilder() is used. Plugin builds without any issue. The logs don't contain any information on why the plugin could not be loaded.

Logs

[INFO] (cssharp:PluginContext) Loading plugin SomePlugin
Could not load plugin "[redacted]game\csgo\addons\counterstrikesharp\plugins/disabled/SomePlugin/SomePlugin.dll")

Code

using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Core.Attributes;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Builder;

namespace SomePlugin;

[MinimumApiVersion(144)]
public class SomePlugin: BasePlugin {
    public override string ModuleName => "SomePlugin";
    public override string ModuleVersion => "0.0.1";
    public override string ModuleAuthor => "Someone";
    public override string ModuleDescription => "A simple plugin";

    public override void Load(bool hotReload) {
        Logger.LogInformation("Starting SomePlugin...");
        // next line prevents the plugin from loading. "Starting SomePlugin..." is not logged.
        var builder = WebApplication.CreateBuilder();     
    }
}

Added to my .csproj file

  <ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>

wiesendaniel avatar Jan 17 '24 02:01 wiesendaniel

I've just realized that hot reloading the plugin might have been a bad idea. I found that the load command silences the exception. Added it and created a PullRequest.

The error still seems odd to me. Microsoft.AspNetCore seems to be packaged with the dotnet distribution. Any ideas?

[INFO] (cssharp:PluginContext) Loading plugin SomePlugin
Could not load plugin "[redacted]game\csgo\addons\counterstrikesharp\plugins/disabled/SomePlugin/SomePlugin.dll")
[EROR] (cssharp:Core) Could not load plugin "[redacted]game\csgo\addons\counterstrikesharp\plugins/disabled/SomePlugin/SomePlugin.dll"
System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.AspNetCore, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. The system cannot find the file specified.
File name: 'Microsoft.AspNetCore, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'
   at SomePlugin.SomePlugin.Load(Boolean hotReload)
   at CounterStrikeSharp.API.Core.Plugin.PluginContext.Load(Boolean hotReload)
   at CounterStrikeSharp.API.Core.Plugin.Host.PluginManager.LoadPlugin(String path)
   at CounterStrikeSharp.API.Core.Application.OnCSSPluginCommand(CCSPlayerController caller, CommandInfo info)

wiesendaniel avatar Jan 17 '24 21:01 wiesendaniel

Try with dotnet add package Microsoft.AspNetCore --version 2.2.0

alexevladgabriel avatar Jan 17 '24 21:01 alexevladgabriel

Try with dotnet add package Microsoft.AspNetCore --version 2.2.0

Tried it and Microsoft.AspNetCore was added as PackageReference. Sadly it did not change the outcome. It seems to look for Version=7.0.0.0 which does not exist.

wiesendaniel avatar Jan 17 '24 22:01 wiesendaniel

I've copied over all files from addons\counterstrikesharp\dotnet\shared\Microsoft.AspNetCore.App\7.0.11 to my plugins folder. It started loading just fine. I wasn't able to configure the project to include these DLLs when running dotnet publish. I suppose it's always expected to be part of the dotnet distribution. (Still a dotnet noob tho doing guesswork over here)

Aren't those libraries supposed to be loaded? Am I missing something here?

EDIT: Found a difference in packaging dotnet for windows and linux. Tested on on both. Does not work with either unless dlls are copied next to the plugin.

wiesendaniel avatar Jan 19 '24 01:01 wiesendaniel

Try using self-contained runtime or single file publish

https://learn.microsoft.com/en-us/dotnet/core/deploying/#publish-self-contained

https://learn.microsoft.com/en-us/dotnet/core/deploying/single-file/overview?tabs=cli

The problem is that the manifest of the shared runtime does not include ASP.NET, so we have to do it ourselves

stevefan1999-personal avatar Jan 20 '24 17:01 stevefan1999-personal

you can also merge the dlls into a single assembly aswell with third party programs

KillStr3aK avatar Jan 23 '24 19:01 KillStr3aK

Try using self-contained runtime or single file publish

https://learn.microsoft.com/en-us/dotnet/core/deploying/#publish-self-contained

https://learn.microsoft.com/en-us/dotnet/core/deploying/single-file/overview?tabs=cli

The problem is that the manifest of the shared runtime does not include ASP.NET, so we have to do it ourselves

I tried to implement this according to the documentation with out success. As far as i understand it only works for <Project Sdk="Microsoft.NET.Sdk.Web"> and not <Project Sdk="Microsoft.NET.Sdk">. Also needs a <RuntimeIdentifier>. Is Microsoft.AspNetCore OS dependent and thus usually shipped with the distribution? (Just a thought)

you can also merge the dlls into a single assembly aswell with third party programs

Do you have any further details on how to do this. I think i went through everything there is twice but there is a solid chance I'm missing something.

wiesendaniel avatar Jan 24 '24 01:01 wiesendaniel

I'm not sure I understand the purpose to have aspnet core endpoints in a plugin. Are you trying to send commands to a server? May I suggest running an aspnet core app elsewhere with a signalR hub, and have your plugin register to that hub as a client?

frederikstonge avatar Jan 24 '24 01:01 frederikstonge

Thanks for the suggestion. Very much appreciated. I will definitely read up on it. As said, very little and old knowledge on dotnet and its ecosystem on my end.

I want to build a little WebApp to interact with the server. Fun little project to be motivated to learn something new I guess. For me it is all about keeping it as simple as possible. If I'm able to avoid running something on another server I would rather do it that way.

Also I don't want to misuse this projects issue tracker as my personal help desk ;) For now I'm good doing some DLL copy workarounds here and there.

For the sake of this projects interests, rather than my personal ones I'd like to steer this discussion in a more general direction.

I'd rather just have the following questions answered:

Is this DLL not loading expected behavior?

If so, should this be changed?

And if it is not supposed to work and never should: Why are those files being shipped in the release distribution of this framework?

wiesendaniel avatar Jan 24 '24 02:01 wiesendaniel

I want to build a little WebApp to interact with the server.

I'd suggest nodejs & socketio for the web part and use sockets to receive packets from the webserver

your error comes from the fact that you are trying to load the dependency while it is not found, probably you got 7.0.0 from nuget but 7.0.11 is shipped with cssharp by default but they are different assemblies

so either set the reference manually, or get the correct version of the assembly

KillStr3aK avatar Jan 24 '24 02:01 KillStr3aK

Indeed i got a version newer than 7.0.11. Changed it to the correct version (i hope, it's a bit confusing) and it still did not work.

dotnet --info
.NET SDK:
 Version:   7.0.401
 Commit:    eb26aacfec

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.22621
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\7.0.401\

Host:
  Version:      8.0.1
  Architecture: x64
  Commit:       bf5e279d92

.NET SDKs installed:
  7.0.401 [C:\Program Files\dotnet\sdk]
  8.0.101 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 7.0.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 8.0.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.25 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 7.0.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 7.0.11 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 8.0.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 6.0.25 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 7.0.5 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 7.0.11 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 8.0.1 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Other architectures found:
  x86   [C:\Program Files (x86)\dotnet]
    registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]

Environment variables:
  Not set

wiesendaniel avatar Jan 26 '24 15:01 wiesendaniel

This is probably not something that is officially supported inside of CS#, so you might have to find your own way forward on this; though I am interested to hear the outcome.

While you can use package references etc. to use whatever libraries you'd like, any of the core .NET Sdks that are referenced using <Project Sdk> are not tested.

roflmuffin avatar Feb 22 '24 01:02 roflmuffin