DEVKIT1017 - phuocle/Dynamics-Crm-DevKit GitHub Wiki
This analyzer detects usage of Console.Write, Console.WriteLine, and other Console methods in plugin and workflow activity code. Console output has no effect in the Dataverse sandbox environment because the console stream is redirected to null.
Console output in plugins and workflows:
- Has No Effect: Console is not available in the Dataverse sandbox - output is discarded
- Wastes Resources: String formatting and method calls execute but produce nothing
- Creates False Confidence: Developers may think their debug output is being logged
- Better Alternatives Exist: ITracingService provides actual logging
The analyzer flags usage of these Console methods within IPlugin or CodeActivity classes:
Console.Write()Console.WriteLine()Console.ErrorConsole.OutConsole.SetOut()Console.SetError()Console.Beep()Console.Clear()Console.ResetColor()Console.SetCursorPosition()
public class MyPlugin : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
var context = (IPluginExecutionContext)serviceProvider
.GetService(typeof(IPluginExecutionContext));
// ❌ Console output has no effect in sandbox
Console.WriteLine("Plugin started");
Console.WriteLine($"Message: {context.MessageName}");
// ... plugin logic
Console.WriteLine("Plugin completed");
}
}public class MyPlugin : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
// ✅ Get tracing service for actual logging
var tracingService = (ITracingService)serviceProvider
.GetService(typeof(ITracingService));
var context = (IPluginExecutionContext)serviceProvider
.GetService(typeof(IPluginExecutionContext));
tracingService.Trace("Plugin started");
tracingService.Trace($"Message: {context.MessageName}");
// ... plugin logic
tracingService.Trace("Plugin completed");
}
}- Remove Console calls: Delete all Console.Write/WriteLine statements
- Add ITracingService: Get the tracing service from the service provider
-
Replace with Trace: Use
tracingService.Trace()instead of Console
public void Execute(IServiceProvider serviceProvider)
{
+ var tracingService = (ITracingService)serviceProvider
+ .GetService(typeof(ITracingService));
+
var context = (IPluginExecutionContext)serviceProvider
.GetService(typeof(IPluginExecutionContext));
- Console.WriteLine($"Processing: {context.MessageName}");
+ tracingService.Trace($"Processing: {context.MessageName}");
}Unlike Console output, ITracingService trace logs are captured by the platform:
- Go to Settings → Plug-in Trace Log
- Filter by plugin assembly or message
- Review the
MessageBlockfield for trace output
Note: Tracing must be enabled in the environment (Plug-in Trace Log Setting).
If you have a specific reason to use Console (e.g., code shared with non-plugin projects):
#pragma warning disable DEVKIT1017
Console.WriteLine("Debug output");
#pragma warning restore DEVKIT1017Or in .editorconfig:
[*.cs]
dotnet_diagnostic.DEVKIT1017.severity = none- DEVKIT1012 - Consider using ITracingService in plug-ins
| Property | Value |
|---|---|
| Rule ID | DEVKIT1017 |
| Category | DynamicsCrm.DevKit |
| Severity | Warning |
| Enabled by default | Yes |