skip to Main Content

I am developing a system that uses Roslyn to do runtime compilation of C# code.

I am adding assemblies using this code, passing the fully qualified assembly file name to the method.

public bool AddAssembly(string assemblyDll)
{
     if (string.IsNullOrEmpty(assemblyDll)) return false;

     var file = Path.GetFullPath(assemblyDll);

     if (!File.Exists(file))
     {
         // check framework or dedicated runtime app folder
         var path = Path.GetDirectoryName(typeof(object).Assembly.Location);
         file = Path.Combine(path, assemblyDll);

         if (!File.Exists(file))
             return false;
     }

     if (References.Any(r => r.FilePath == file)) 
         return true;

     try
     {
         var reference = MetadataReference.CreateFromFile(file);
         References.Add(reference);
     }
     catch
     {
         return false;
     }

     return true;
}

All worked well until I wanted to build a Winforms form in the code.
Despite adding System.Windows.Forms.dll to the assembly references I still get the error

Type or namespace name "Forms" does not exist in the namespace ‘System.Windows’

Reading other articles on this error message the solutions all involve Visual Studio and editing the .csproj file to add

<UseWindowsForms>true</UseWindowsForms>

So, how do I get Roslyn to recognize that I want to use Winforms forms?

2

Answers


  1. Chosen as BEST ANSWER

    I solved my problem and thought it might be useful for someone else.

    To summarise. This was part of an R&D exercise we are doing.

    Summary of the spec was - Write a program to a read C# source code file, compile it and write the dll to a SQL database. Then write another program to retrieve the dll from SQL and run a method in the dll.

    To do this I was using Roslyn APIs (.Net Compiler Platform SDK) and .Net Core.

    To get this to work you have to reference any assembly that the code will need when Roslyn compiles it. That is what the code in the question was doing.

    In my case these were in

    C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.3

    All went well until I picked some code that generated a Winforms Form. Then I got the error above. Eventually I created a "Windows Forms App" project to see what VS 2022 referenced and found that it had another framework in its Dependencies

    Microsoft.WindowsDesktop.App.WindowsForms

    This refered to files in the following directory

    C:Program FilesdotnetpacksMicrosoft.WindowsDesktop.App.Ref8.0.3refnet8.0

    Once I referenced

    System.Windows.Forms.dll and System.Windows.Forms.Primitives.dll

    Roslyn compiled perfectly.


  2. … I load the assemblies before I compile the source code and once compiled I run the code. My problem is that I can’t get it to compile.

    The code you wrote to load the assembly can only run after it has been compiled. Therefore, it cannot load the assemblies which are needed for a successful compilation.

    You don’t need any code to load assemblies, unless you are implementing a kind of plug-in/add-in architecture. All you need is to add references to your project.

    The compiler will automatically copy the required assemblies into the output folder binDebugnet8.0-windows or binReleasenet8.0-windows and the Common Language Runtime (CLR) will automatically load the assemblies when you launch the application.

    When you create a project using the Windows Forms App (.NET Core) template, your *.csproj will look like this:

    <Project Sdk="Microsoft.NET.Sdk">
    
      <PropertyGroup>
        <OutputType>WinExe</OutputType>
        <TargetFramework>net8.0-windows</TargetFramework>
        <Nullable>enable</Nullable>
        <UseWindowsForms>true</UseWindowsForms>
        <ImplicitUsings>enable</ImplicitUsings>
      </PropertyGroup>
    
    </Project>
    

    And your references like this:

    enter image description here

    And you don’t have to do anything manually. On the other hand, if you started with another project type, you might have to change *.csproj and to add references manually.

    And again: Do not attempt to load these assemblies with C# code!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search