首页 文章

使用DNU / DNX和project.json在VSCode中调试C#控制台应用程序

提问于
浏览
0

问题(这是OSX顺便说一句 . ):

  • 通过 yo aspnetdnu restorednu builddnx run < - 所有是peachy创建一个新的C#控制台应用程序

  • 将依赖项(例如Newtonsoft.JSON,Akka)添加到项目中, dnu restorednu builddnx run < - 所有都是桃子

  • 查看此网站,了解它应该如何运作 . https://code.visualstudio.com/Docs/editor/debugging#_mono-debugging(哦,通过谷歌搜索和试错,拼凑其余部分)

  • 在Program.cs中添加 using Newtonsoft.JSON 并实际使用它 .

  • 尝试编译/调试

  • meh ......

让我们调查:

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

如果你试图让它像_1840475中那样工作,它适用于没有依赖项生成的简单 Program.cs 文件,你什么也得不到 . 我通过控制台试了一下,看看它为什么不起作用 . 所以为什么?因为 mono 可以't find the necessary dependencies. Why? Because they'不在所述目录中 .

{
    "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进行编程和调试的白痴吗?我刚做错了吗?

任何接受者?

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

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

Edit 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连接到调试器,如上所示(当然端口需要匹配),运行程序但调试器可以't get a hook in. Guess that',因为你没有真正调试 HelloWorld.dll . 或 dnx build 不输出调试符号 . 可能是最后一个 .

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

所以我在 man mono 周围挖了一下,发现你可以通过 $MONO_PATH 告诉单声道查找库 .

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

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

Yeay?没有!

因为 dnu publish 没有做的是创建一个编译的.DLL文件 . 相反,它会创建一个似乎打开的shell脚本苍蝇编译你的东西 . 但是无所谓 . 我们只是想要DLL .

那么我们有什么 . 我们有一个 dnu build 给我们一个很好的.DLL文件 . 我们有 dnu publish 收集我们的依赖项 .

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

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

问题再次出现在 launch.json . 它有一个很好的属性叫做 env : {} 但是VSCode,在生成启动调试器的实际命令时,把你放在那里的所有东西放在单引号中 . 哪个被解释为文字字符串 . 所以你实际上不能把像上面的小命令这样的东西放进去 . sad trombone

顺便说一句 . 如果你再次打开一个终端,并将上述脚本的输出导出到 $MONO_PATH 然后手动运行 mono 命令,就像在另一个尝试中你可以再次尝试将VSCode调试器附加到它,该命令运行但是调试器可以't hook into it. Again i think it'既不是调试符号,也不是其他东西 .

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$

结论现在 . 我完全没有想法 . 除了使用gulp或其他构建工具,如@richardsonmarkj建议,我不会很快看到它发生 .

2 回答

  • 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

    EDIT:"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文件复制到目录中可以解决问题并且应用程序将运行 . 此时,调试器似乎也像我在下面的评论中提到的那样工作 .

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

    EDIT: 我已经证实了这一点 . 我将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可能有用的东西 .

  • 0

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

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

相关问题