使用DNU / DNX和project.json

时间:2016-01-19 10:00:07

标签: c# macos mono visual-studio-code dnx

问题(这是OSX的全部内容。):

  1. 通过yo aspnetdnu restorednu builddnx run< - all is peachy
  2. 创建一个新的C#控制台应用程序
  3. 向项目添加依赖项(例如Newtonsoft.JSON,Akka),dnu restorednu builddnx run< - all is peachy
  4. 查看此网站,看看它应该如何运作。 https://code.visualstudio.com/Docs/editor/debugging#_mono-debugging(哦,通过谷歌搜索和试错将其余部分拼凑起来)
  5. 在Program.cs中添加using Newtonsoft.JSON,然后......实际使用它。
  6. 尝试编译/调试
  7. meh ...
  8. 让我们调查:

    mcs -debug Program.cs无法编译Program.cs,因为它无法找到位于dnu restore某处的~/.dnx/packages/...安装的依赖项。有点理智。所以使用mcs编译是不是要走的路?

    其他人说"使用xbuild或其他"。但我不想制作.csproj档案。我想使用project.json和DNU / DNX。 (我还没有尝试过)

    那你能做什么?尝试使用tasks.json摆弄dnu build

    这是我得到的。

    {
        "version": "0.1.0",
        "command": "dnu",
        "options": {
            "cwd": "/Users/meh/Development/code/HelloWorld"
        },
        "showOutput": "silent",
        "tasks": [
            {
                "taskName": "build",
                "isBuildCommand": true,
                "problemMatcher": "$msCompile"
            }
        ]
    }
    

    它不是很漂亮,但实际上它完成了工作。

    现在,我无法开始工作的部分是调试部分。

    所以dnu build在某个目录中创建输出,如/Users/meh/Development/code/HelloWorld/bin/Debug/dnx451/HelloWorld.dll

    如果你试图让它像这个launch.json一样工作,它适用于没有依赖项生成的简单Program.cs文件,你什么也得不到。 我通过控制台尝试了解它为什么不起作用。所以为什么?因为mono无法找到必要的依赖关系。为什么?因为他们不在目录中。

    {
        "version": "0.2.0",
        "configurations": [
            {
                "name": "Launch",
                "type": "mono",
                "request": "launch",
                "program": "/Users/meh/Development/code/HelloWorld/bin/Debug/dnx451/HelloWorld.dll",
                "args": [],
                "cwd": ".",
                "runtimeExecutable": null,
                "env": {}
            },
            {
                "name": "Attach",
                "type": "mono",
                "request": "attach",
                "address": "localhost",
                "port": 5858
            }
        ]
    }
    

    如果您使用dnx run或您配置的任何内容来运行已编译的程序,它当然可以正常工作。

    所以环顾dnx --help我看到了一个不错的dnx --debug选项。如果你在控制台上运行它,你会得到这个不错的输出:

    Blah:HelloWorld meh$ dnx --debug run
    Process Id: 19228
    Waiting for the debugger to attach...
    

    事情是......我不知道调试器正在等待什么端口。事实上,mono-sgenps告诉我PID属于)实际上并不是在监听任何端口。我试图通过lsof查看。

    我担心dnx --debug实际上并没有真正发挥作用,因为我已经在github问题上看到随机评论,并提到了一些内容。

    那就是它。那是我有多远。

    因此。还有人进一步了吗?还有人试过吗?我是试图通过DNX / DNU制作控制台应用程序并使用VSCode进行编程和调试的白痴吗?我刚做错了吗?

    任何接受者?

    修改1 : 您必须将此添加到project.json以获取已编译的DLL文件中的入口点,以便单元能够运行该程序。

    "compilationOptions": {
        "emitEntryPoint": true
    },
    

    编辑2 : 我试过的其他事情......

    1。查看dnx run实际执行的操作。

    它做了什么?

    45588 s000  U+     0:02.11 mono /Users/meh/.dnx/runtimes/dnx-mono.1.0.0-rc1-update1/bin/Microsoft.Dnx.Host.Mono.dll run
    

    它从项目目录中调用了一个名为Microsoft.Dnx.Host.Mono.dll的东西,用于调用所有东西。

    遗憾的是,没有真正的方法将该命令放入launch.json条目以使其成为a)从正确的目录开始并且b)从命令中省略.DLL文件名。

    这是launch.json中最好的争吵。

    cd '/Users/meh/Development/code/HelloWorld/bin/Debug/dnx451';  'mono' '--debug' '--debugger-agent=transport=dt_socket,server=y,address=127.0.0.1:61396' '/Users/meh/.dnx/runtimes/dnx-mono.1.0.0-rc1-update1/bin/Microsoft.Dnx.Host.Mono.dll' 'HelloWorld.dll' 'run'
    

    很明显,它是Microsoft.Dnx.Host.Mono.dll运行的错误目录,您无法省略HelloWorld.dll参数。

    另一件事是。即使你可以让VSCode生成正确的命令行,它也不起作用。打开终端并执行这样的命令可以进入调试模式:

    cd '/Users/meh/Development/code/HelloWorld/';  'mono' '--debug' '--debugger-agent=transport=dt_socket,server=y,address=127.0.0.1:61396' '/Users/meh/.dnx/runtimes/dnx-mono.1.0.0-rc1-update1/bin/Microsoft.Dnx.Host.Mono.dll' 'run'
    

    然后通过launch.json中的attach配置从VSCode连接到调试器,如上所示(当然端口需要匹配),运行程序,但调试器无法获取挂钩猜猜是因为你没有真正调试HelloWorld.dll。或dnx build不输出调试符号。可能是最后一个。

    2。告诉单声道依赖项的细节。

    所以我在man mono周围挖了一下,发现你可以通过$MONO_PATH告诉单声道在哪里寻找图书馆。

    但是制作脚本并拍打~/.dnx/packages中找到的所有路径并不好,因为在那里包含了所有库dnu restored。他们的每个版本。

    那么如何只为你的project.json引用提供库?好吧,我在dnu附近挖了一下,发现dnu publish。这会在output内生成包含许多内容的bin目录。其中一个是名为packages的文件夹,其中包含所有项目依赖项。

    Yeay?不!

    因为dnu publish没有做的是创建一个已编译的.DLL文件。相反,它创建了一个shell脚本,似乎可以动态编译你的东西。但是无所谓。我们只是想要DLL。

    那我们有什么。我们有一个dnu build来获取一个不错的.DLL文件。我们有dnu publish收集我们的依赖项。

    现在你可以使用一点shell魔术以$MONO_PATH友好的方式为我们收集路径。

    ls -d $PWD/bin/output/approot/packages/*/*/lib/net45 | tr '\n' ':'
    

    问题再次出现在launch.json。它有一个名为env : {}的不错的属性,但VSCode在生成启动调试器的实际命令时,会将您放入的所有内容放在单引号中。哪个被解释为文字字符串。因此,您实际上无法将上面的小命令放入其中。 悲伤的长号

    顺便说一下。如果你再次打开一个终端,并将上述脚本的输出导出到$MONO_PATH然后手动运行mono命令,那么你可以再次尝试将VSCode调试器连接到它,命令运行但调试器无法挂钩。我认为它既不是调试符号也不是其他东西。

     Flash:HelloWorld meh$ export MONO_PATH=$(ls -d $PWD/bin/output/approot/packages/*/*/lib/net45 | tr '\n' ':')
     Flash:HelloWorld meh$ echo $MONO_PATH 
     /Users/meh/Development/code/HelloWorld/bin/output/approot/packages/Akka/1.0.5/lib/net45:/Users/meh/Development/code/HelloWorld/bin/output/approot/packages/Microsoft.CSharp/4.0.1-beta-23516/lib/net45:/Users/meh/Development/code/HelloWorld/bin/output/approot/packages/Newtonsoft.Json/8.0.1-beta3/lib/net45:/Users/meh/Development/code/HelloWorld/bin/output/approot/packages/System.Collections/4.0.11-beta-23516/lib/net45:/Users/meh/Development/code/HelloWorld/bin/output/approot/packages/System.Linq/4.0.1-beta-23516/lib/net45:/Users/meh/Development/code/HelloWorld/bin/output/approot/packages/System.Threading/4.0.11-beta-23516/lib/net45:
     Flash:HelloWorld meh$ cd '/Users/meh/Development/code/HelloWorld/bin/Debug/dnx451';  'mono' '--debug' '--debugger-agent=transport=dt_socket,server=y,address=127.0.0.1:61396' 'HelloWorld.dll'
     Meh
     Hello World
     {
       "blah": "blub"
     }
     From ConsoleActor: blah blub
     From ConsoleActor: blubberblub
    
     Flash:dnx451 meh$ 
    

    现在的结论。我完全没有想法。如果没有像@richardsonmarkj建议的那样使用gulp或其他构建工具,我很快就会发现它不会发生。

2 个答案:

答案 0 :(得分:0)

我也一直试图了解这种情况。我走过你的台阶,最后到了另一个地方。我没有看到依赖问题。当我尝试从VSCode调试时,我在终端窗口中得到了这个 -

cd '/Users/markr/Projects/ConsoleApplication/bin/Debug/dnxcore50';  'mono' '--debug' '--debugger-agent=transport=dt_socket,server=y,address=127.0.0.1:58907' 'ConsoleApplication.dll'
Assembly '/Users/markr/Projects/ConsoleApplication/bin/Debug/dnxcore50/ConsoleApplication.dll' doesn't have an entry point.

区别在于将Newtonsoft.JSON添加到我的依赖项 -

之后
 "dependencies": {
  "Newtonsoft.Json": "8.0.2"
},

在我的project.json文件中,我做了dnu restore

编辑:"compilationOptions": { "emitEntryPoint": true },添加到我的project.json文件中确实修复了我的入口点问题。

这是我的代码: -

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;

namespace ConsoleApplication
{
public class Program
{
    public static void Main(string[] args)
    {
        Console.WriteLine("Hello World");

        JArray array = new JArray();
        array.Add("Manual text");
        array.Add(new DateTime(2000, 5, 23));

        JObject o = new JObject();
        o["MyArray"] = array;

        string json = o.ToString();
        Console.WriteLine(json);

        Console.Read();
    }
}
}

我认为调试器遇到了与mcs -debug相同的问题。通过mono ConsoleApplication.dll从命令行运行该应用程序给出了

Unhandled Exception:
System.IO.FileNotFoundException: Could not load file or assembly 'Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies.
File name: 'Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed'
[ERROR] FATAL UNHANDLED EXCEPTION: System.IO.FileNotFoundException: Could not load file or assembly 'Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies.
File name: 'Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed'

将Newtonsoft.Json.dll文件复制到目录中可以解决问题并且应用程序将运行。此时,调试器似乎也像我在下面的评论中提到的那样工作。

我认为我们需要一个构建步骤来收集依赖项并将它们放在输出目录中。

编辑:我已经验证了这一点。我将Newtonsoft.Json.dll拉入根目录并将tasks.json更改为 -

{
    "version": "0.1.0",
    "command": "mcs",
    "options": {
        "cwd": "/Users/markr/Projects/ConsoleApplication"
    },
    "args": [
        "*.cs",
        "-debug",
        "-r:Newtonsoft.Json.dll"
    ],
    "showOutput": "always",
    "tasks": [
        {
            "taskName": "build",
            "suppressTaskName": true,
            "isBuildCommand": true,
            "problemMatcher": "$msCompile"
        }
    ]
}

当指向新的Program.exe时,调试按预期工作。这有效地消除了dnu / dnx,这意味着项目管理将变得乏味。因此,您需要找到一种方法来将非框架依赖项收集到输出/运行时cwd中,以便Mono vm可以找到它们。看起来像Nant或Gulp可能有用的东西。

答案 1 :(得分:0)

DNX已被弃用,所以现在这个问题没有实际意义。

将此link留在此处,显示使用vscode进行实验性.net核心调试。