简体   繁体   English

Mono MSC C# 编译器如何添加程序集引用

[英]Mono MSC C# compiler how to add assembly references

So im trying to run a .NET C# script in mono, but i get errors of missing assemblies...所以我试图在 mono 中运行 .NET C# 脚本,但我收到缺少程序集的错误...

C:\Users\user\Documents\GitHub\callCsharp-fromCPP\CMonoTest\Mp3ToSpeech.cs(1,14): error CS0234: The type or namespace name `Speech' does not exist in the namespace `System'. Are you missing an assembly reference?
C:\Users\user\Documents\GitHub\callCsharp-fromCPP\CMonoTest\Mp3ToSpeech.cs(6,7): error CS0246: The type or namespace name `NAudio' could not be found. Are you missing an assembly reference?
C:\Users\user\Documents\GitHub\callCsharp-fromCPP\CMonoTest\SeleniumWebdriver.cs(1,7): error CS0246: The type or namespace name `OpenQA' could not be found. Are you missing an assembly reference?
...

here is my current C++ code这是我当前的 C++ 代码

#include <windows.h>
#include <mono/jit/jit.h>
#include <mono/metadata/assembly.h>
#include <mono/metadata/debug-helpers.h>
#include <cstdlib>
#include <string>
#include <iostream>
#include <sstream>
#include <direct.h>
#include <filesystem>


#pragma comment(lib, "mono-2.0-boehm.lib") // replaced from mono-2.0.lib
#pragma comment(lib, "mono-2.0-sgen.lib") // It is new with GC code library GC from Gnu Compilication
#pragma comment(lib , "MonoPosixHelper.lib")

std::string get_working_path()
{
    char temp[260]; // max windows path length
    return (_getcwd(temp, sizeof(temp)) ? std::string(temp) : std::string(""));
}

int main(int argc, char* argv[])
{
#pragma region Load and compile the script
    std::string Mp3Path = std::filesystem::path(get_working_path()).parent_path().string() + R"(\CMonoTest\ChromeDriverInstaller.cs  )";
    std::string ProgramPath = std::filesystem::path(get_working_path()).parent_path().string() + R"(\CMonoTest\Program.cs  )";
    std::string ChromeInstPath = std::filesystem::path(get_working_path()).parent_path().string() + R"(\CMonoTest\Mp3ToSpeech.cs  )";
    std::string SeleniumWebPath = std::filesystem::path(get_working_path()).parent_path().string() + R"(\CMonoTest\SeleniumWebdriver.cs  )";
    //C:\Users\user\.nuget\packages\dotnetseleniumextras.waithelpers\3.11.0\lib\net45\SeleniumExtras.WaitHelpers.dll
    //C:\Users\user\.nuget\packages\naudio\2.1.0\lib\net6.0\NAudio.dll
    //C:\Users\user\.nuget\packages\selenium.support\4.4.0\lib\net5.0\WebDriver.Support.dll
    //C:\Users\user\.nuget\packages\selenium.webdriver\4.4.0\lib\net5.0\WebDriver.dll
    //C:\Users\user\.nuget\packages\system.speech\6.0.0\lib\net6.0\System.Speech.dll
    std::string references = R"(-r:C:\Users\user\.nuget\packages\dotnetseleniumextras.waithelpers\3.11.0\lib\net45\SeleniumExtras.WaitHelpers.dll
    -r:C:\Users\user\.nuget\packages\naudio\2.1.0\lib\net6.0\NAudio.dll -r:/C:\Users\user\.nuget\packages\selenium.support\4.4.0\lib\net5.0\WebDriver.Support.dll
    -r:C:\Users\user\.nuget\packages\selenium.webdriver\4.4.0\lib\net5.0\WebDriver.dll -r:C:\Users\user\.nuget\packages\system.speech\6.0.0\lib\net6.0\System.Speech.dll)";
    std::string command = "mcs " + ProgramPath + ChromeInstPath + SeleniumWebPath + Mp3Path + references + R"( -target:library)";
    
    //Compile the script
    std::string Command = std::string(R"(cd C:\Program Files (x86)\Mono\bin && )") + command;
    system(Command.c_str());
#pragma endregion

#pragma region Init mono runtime
    mono_set_dirs("C:\\Program Files (x86)\\Mono\\lib",
        "C:\\Program Files (x86)\\Mono\\etc");

    //Init a domain
    MonoDomain* domain;
    domain = mono_jit_init("MonoScriptTry");
    if (!domain)
    {
        std::cout << "mono_jit_init failed" << std::endl;
        system("pause");
        return 1;
    }

    //Open a assembly in the domain
    MonoAssembly* assembly;
    std::string assemblyPath = std::filesystem::path(get_working_path()).parent_path().string() + R"(\CMonoTest\Program.dll)";
    assembly = mono_domain_assembly_open(domain, assemblyPath.c_str());
    if (!assembly)
    {
        std::cout << "mono_domain_assembly_open failed" << std::endl;
        system("pause");
        return 1;
    }

    //Get a image from the assembly
    MonoImage* image;
    image = mono_assembly_get_image(assembly);
    if (!image)
    {
        std::cout << "mono_assembly_get_image failed" << std::endl;
        system("pause");
        return 1;
    }
#pragma endregion

#pragma region Run a static method
    {
        //Build a method description object
        MonoMethodDesc* TypeMethodDesc;
        const char* TypeMethodDescStr = "Program:StartWebRegister()";
        TypeMethodDesc = mono_method_desc_new(TypeMethodDescStr, NULL);
        if (!TypeMethodDesc)
        {
            std::cout << "mono_method_desc_new failed" << std::endl;
            system("pause");
            return 1;
        }

        //Search the method in the image
        MonoMethod* method;
        method = mono_method_desc_search_in_image(TypeMethodDesc, image);
        if (!method)
        {
            std::cout << "mono_method_desc_search_in_image failed" << std::endl;
            system("pause");
            return 1;
        }

        //run the method
        std::cout << "Running the static method: " << TypeMethodDescStr << std::endl;
        mono_runtime_invoke(method, nullptr, nullptr, nullptr);
    }
#pragma endregion


#pragma endregion

    system("pause");
    return 0;
}

Im trying to reference assemblies using -r: , using full path where they are located, but it doesnt work and i still get errors.我试图使用 -r: 引用程序集,使用它们所在的完整路径,但它不起作用,我仍然得到错误。

  1. I Tried using msbuild, to build.csproj with instead of msc (see my other question Embedding mono in C++, Could not load file or assembly 'System.Runtime' or one of its dependencies ) but it cant call the static method I Tried using msbuild, to build.csproj with instead of msc (see my other question Embedding mono in C++, Could not load file or assembly 'System.Runtime' or one of its dependencies ) but it cant call the static method

So my question is how can i reference the assemblies.所以我的问题是如何引用程序集。 Is there a easy way to do that in mono if you are using nuget?如果您使用的是 nuget,在 mono 中是否有一种简单的方法可以做到这一点? I saw on the docs that you can call packages using -pkg: if they have a.pc file (which none of.nuget have)我在文档上看到你可以使用 -pkg 调用包:如果它们有一个 .pc 文件(没有一个.nuget 有)

For those who have also problems with this, my problem was that对于那些也有这个问题的人,我的问题是

std::string references = R"(-r:C:\Users\user\.nuget\packages\dotnetseleniumextras.waithelpers\3.11.0\lib\net45\SeleniumExtras.WaitHelpers.dll
    -r:C:\Users\user\.nuget\packages\naudio\2.1.0\lib\net6.0\NAudio.dll -r:C:\Users\user\.nuget\packages\selenium.support\4.4.0\lib\net5.0\WebDriver.Support.dll
    -r:C:\Users\user\.nuget\packages\selenium.webdriver\4.4.0\lib\net5.0\WebDriver.dll -r:C:\Users\user\.nuget\packages\system.speech\6.0.0\lib\net6.0\System.Speech.dll)";

wasnt respecting this format不尊重这种格式

msc -r:"reference\to\assembly.dll"

it should be in quotes even if the path doesnt have any spaces.即使路径没有任何空格,它也应该用引号引起来。
This is a problem only when you want to use full path, as当您想使用完整路径时,这才是问题,因为

msc -r:System.Assembly.dll 

works fine!工作正常!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM