简体   繁体   English

如何在 VS 代码中检查 Debug.Writeline() 输出?

[英]How to check Debug.Writeline() output in VS code?

I want to know the exact way to check the output of Debug.Writeline() in VS Code using C# extension.我想知道在 VS Code 中使用 C# 扩展检查 Debug.Writeline() 输出的确切方法。

I was using .net core 2.2 as a framework to run a sample test from this website https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/keyvault/Azure.Security.KeyVault.Keys/samples/Sample1_HelloWorld.cs .我使用 .net core 2.2 作为框架从这个网站https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/keyvault/Azure.Security.KeyVault运行示例测试。键/样本/Sample1_HelloWorld.cs

The test passed but I couldn't see any output from the Debug.Writeline() in the terminal.测试通过了,但我在终端中看不到 Debug.Writeline() 的任何输出。 So I googled and found that common solution is to include the following code in my .cs file:所以我用谷歌搜索,发现常见的解决方案是在我的 .cs 文件中包含以下代码:

/* Create a listener that outputs to the console screen, and 
   add it to the debug listeners. */
   TextWriterTraceListener myWriter = new TextWriterTraceListener(System.Console.Out);
   Debug.Listeners.Add(myWriter);

However, after I put the code into the file, it can't find the property 'listeners' under the class 'Debug'.但是,在我将代码放入文件后,它在“Debug”类下找不到属性“listeners”。 So I googled again and realised that it is because this property is only included in .Net Framework 4.8.所以我再次用谷歌搜索并意识到这是因为这个属性只包含在 .Net Framework 4.8 中。 Therefore, I downloaded .Net Framework v4.8 and changed 'TargetFramework as follows:因此,我下载了 .Net Framework v4.8 并将“TargetFramework”更改为如下:

<TargetFramework>net48</TargetFramework>

After the modifications, I ran the test again:修改后,我再次运行测试:

dotnet test 

But the result is still like this:但是结果还是这样:

Microsoft (R) Test Execution Command Line Tool Version 16.2.0-preview-20190606-02
Copyright (c) Microsoft Corporation.  All rights reserved.

Starting test execution, please wait...


Test Run Successful.
Total tests: 1
     Passed: 1

This is my .csproj file:这是我的 .csproj 文件:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net48</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Azure.Identity" Version="1.0.0-preview.3"/>
    <PackageReference Include="Azure.Security.KeyVault.Keys" Version="4.0.0-preview.2"/>
    <PackageReference Include="NUnit" Version="3.12.0"/>
    <PackageReference Include="NUnit3TestAdapter" Version="3.14.0"/>
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.3.0-preview-20190808-03"/>
  </ItemGroup>
</Project>

This is the sample test I ran without modification:这是我未经修改运行的示例测试:

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for
// license information.

using Azure.Identity;
using NUnit.Framework;
using System;
using System.Diagnostics;
using System.Security.Cryptography;
using System.Threading;

namespace Azure.Security.KeyVault.Keys.Samples
{
    /// <summary>
    /// Sample demonstrates how to set, get, update and delete a key using the synchronous methods of the KeyClient.
    /// </summary>
    [Category("Live")]
    public partial class HelloWorld
    {
        [Test]
        public void HelloWorldSync()
        {
            // Environment variable with the Key Vault endpoint.
            string keyVaultUrl = Environment.GetEnvironmentVariable("AZURE_KEYVAULT_URL");

            // Instantiate a key client that will be used to call the service. Notice that the client is using default Azure
            // credentials. To make default credentials work, ensure that environment variables 'AZURE_CLIENT_ID',
            // 'AZURE_CLIENT_KEY' and 'AZURE_TENANT_ID' are set with the service principal credentials.
            var client = new KeyClient(new Uri(keyVaultUrl), new DefaultAzureCredential());

            // Let's create a RSA key valid for 1 year. If the key
            // already exists in the Key Vault, then a new version of the key is created.
            string rsaKeyName = $"CloudRsaKey-{Guid.NewGuid()}";
            var rsaKey = new RsaKeyCreateOptions(rsaKeyName, hsm: false, keySize: 2048)
            {
                Expires = DateTimeOffset.Now.AddYears(1)
            };

            client.CreateRsaKey(rsaKey);

            // Let's Get the Cloud RSA Key from the Key Vault.
            Key cloudRsaKey = client.GetKey(rsaKeyName);
            Debug.WriteLine($"Key is returned with name {cloudRsaKey.Name} and type {cloudRsaKey.KeyMaterial.KeyType}");

            // After one year, the Cloud RSA Key is still required, we need to update the expiry time of the key.
            // The update method can be used to update the expiry attribute of the key.
            cloudRsaKey.Expires.Value.AddYears(1);
            KeyBase updatedKey = client.UpdateKey(cloudRsaKey, cloudRsaKey.KeyMaterial.KeyOps);
            Debug.WriteLine($"Key's updated expiry time is {updatedKey.Expires}");

            // We need the Cloud RSA key with bigger key size, so you want to update the key in Key Vault to ensure
            // it has the required size.
            // Calling CreateRsaKey on an existing key creates a new version of the key in the Key Vault 
            // with the new specified size.
            var newRsaKey = new RsaKeyCreateOptions(rsaKeyName, hsm: false, keySize: 4096)
            {
                Expires = DateTimeOffset.Now.AddYears(1)
            };

            client.CreateRsaKey(newRsaKey);

            // The Cloud RSA Key is no longer needed, need to delete it from the Key Vault.
            client.DeleteKey(rsaKeyName);

            // To ensure key is deleted on server side.
            Assert.IsTrue(WaitForDeletedKey(client, rsaKeyName));

            // If the keyvault is soft-delete enabled, then for permanent deletion, deleted key needs to be purged.
            client.PurgeDeletedKey(rsaKeyName);

        }

        private bool WaitForDeletedKey(KeyClient client, string keyName)
        {
            int maxIterations = 20;
            for (int i = 0; i < maxIterations; i++)
            {
                try
                {
                    client.GetDeletedKey(keyName);
                    return true;
                }
                catch
                {
                    Thread.Sleep(5000);
                }
            }
            return false;
        }
    }
}

This is the test after modification:这是修改后的测试:

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for
// license information.

using Azure.Identity;
using NUnit.Framework;
using System;
using System.Diagnostics;
using System.Security.Cryptography;
using System.Threading;

namespace Azure.Security.KeyVault.Keys.Samples
{
    /// <summary>
    /// Sample demonstrates how to set, get, update and delete a key using the synchronous methods of the KeyClient.
    /// </summary>
    [Category("Live")]
    public partial class HelloWorld
    {
        [Test]
        public static void Main()
        {    
            /* Create a listener that outputs to the console screen, and 
             add it to the debug listeners. */
           TextWriterTraceListener myWriter = new TextWriterTraceListener(System.Console.Out);
           Debug.Listeners.Add(myWriter);

            // Environment variable with the Key Vault endpoint.
            string keyVaultUrl = Environment.GetEnvironmentVariable("AZURE_KEYVAULT_URL");

            // Instantiate a key client that will be used to call the service. Notice that the client is using default Azure
            // credentials. To make default credentials work, ensure that environment variables 'AZURE_CLIENT_ID',
            // 'AZURE_CLIENT_KEY' and 'AZURE_TENANT_ID' are set with the service principal credentials.
            var client = new KeyClient(new Uri(keyVaultUrl), new DefaultAzureCredential());

            // Let's create a RSA key valid for 1 year. If the key
            // already exists in the Key Vault, then a new version of the key is created.
            string rsaKeyName = $"CloudRsaKey-{Guid.NewGuid()}";
            var rsaKey = new RsaKeyCreateOptions(rsaKeyName, hsm: false, keySize: 2048)
            {
                Expires = DateTimeOffset.Now.AddYears(1)
            };

            client.CreateRsaKey(rsaKey);
            // Let's Get the Cloud RSA Key from the Key Vault.
            Key cloudRsaKey = client.GetKey(rsaKeyName);
            Debug.WriteLine($"Key is returned with name {cloudRsaKey.Name} and type {cloudRsaKey.KeyMaterial.KeyType}");

            // After one year, the Cloud RSA Key is still required, we need to update the expiry time of the key.
            // The update method can be used to update the expiry attribute of the key.
            cloudRsaKey.Expires.Value.AddYears(1);
            KeyBase updatedKey = client.UpdateKey(cloudRsaKey, cloudRsaKey.KeyMaterial.KeyOps);
            Debug.WriteLine($"Key's updated expiry time is {updatedKey.Expires}");

            // We need the Cloud RSA key with bigger key size, so you want to update the key in Key Vault to ensure
            // it has the required size.
            // Calling CreateRsaKey on an existing key creates a new version of the key in the Key Vault 
            // with the new specified size.
            var newRsaKey = new RsaKeyCreateOptions(rsaKeyName, hsm: false, keySize: 4096)
            {
                Expires = DateTimeOffset.Now.AddYears(1)
            };

            client.CreateRsaKey(newRsaKey);

            // The Cloud RSA Key is no longer needed, need to delete it from the Key Vault.
            client.DeleteKey(rsaKeyName);

            // To ensure key is deleted on server side.
            // Assert.IsTrue(WaitForDeletedKey(client, rsaKeyName));

            // If the keyvault is soft-delete enabled, then for permanent deletion, deleted key needs to be purged.
            // client.PurgeDeletedKey(rsaKeyName);

        }

        private bool WaitForDeletedKey(KeyClient client, string keyName)
        {
            int maxIterations = 20;
            for (int i = 0; i < maxIterations; i++)
            {
                try
                {
                    client.GetDeletedKey(keyName);
                    return true;
                }
                catch
                {
                    Thread.Sleep(5000);
                }
            }
            return false;
        }
    }
}

In the end I tried to type the following in the terminal:最后,我尝试在终端中键入以下内容:

dotnet run

I finally got what I expected from the terminal in a format like this:我终于以这样的格式从终端得到了我所期望的:

Key is returned with name CloudRsaKey-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and type xxx
Key's updated expiry time is x/xx/20xx x:xx:xx AM +00:00

But I want to know if it is the only way to see the output from Debug.Witeline().但我想知道它是否是查看 Debug.Witeline() 输出的唯一方法。 Since I did not type the dotnet test command in the terminal, I don't think I was actually running the test.由于我没有在终端中输入dotnet test命令,我认为我实际上并没有在运行测试。 I am quite confused.我很困惑。

First off, you'll have to set an environment variable that will enable debugging tests hosted on the dotnet test process to use the configuration for attaching a debugger in VS Code.首先,您必须设置一个环境变量,该变量将启用托管在 dotnet 测试进程上的调试测试,以使用在 VS Code 中附加调试器的配置。 On Windows with Powershell, this is done as: $env:VSTEST_HOST_DEBUG=1在带有 Powershell 的 Windows 上,这是这样完成的: $env:VSTEST_HOST_DEBUG=1

Running dotnet test without this setting would simply pass.在没有此设置的情况下运行dotnet test只会通过。 And even breakpoints would be ignored if not executed in Debug mode.如果不在调试模式下执行,甚至断点也会被忽略。

Once you attach a debugger to the test process, your breakpoints will be caught and you'll be able to step through code as usual, now seeing the output of all the Debug.WriteLine() statements in the Debug Console of VS Code.一旦您将调试器附加到测试过程,您的断点将被捕获,您将能够像往常一样单步执行代码,现在可以在 VS Code 的调试控制台中看到所有 Debug.WriteLine() 语句的输出。

Check this article for a quick walk through.查看这篇文章以快速浏览。

Here is a short demo:这是一个简短的演示:

在 VS Code 中调试

Hope this helps!希望这可以帮助!

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

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