diff --git a/packaging/windows/clisdk/bundle.wxs b/packaging/windows/clisdk/bundle.wxs index d1de0ef58..4f379ca3e 100644 --- a/packaging/windows/clisdk/bundle.wxs +++ b/packaging/windows/clisdk/bundle.wxs @@ -37,6 +37,7 @@ + diff --git a/packaging/windows/clisdk/dotnet.wxs b/packaging/windows/clisdk/dotnet.wxs index 976bf5a55..315b801e5 100644 --- a/packaging/windows/clisdk/dotnet.wxs +++ b/packaging/windows/clisdk/dotnet.wxs @@ -30,12 +30,20 @@ - - + + - - + + diff --git a/src/dotnet/BuiltInCommandsCatalog.cs b/src/dotnet/BuiltInCommandsCatalog.cs index 68bfdb1ab..25c69fdbd 100644 --- a/src/dotnet/BuiltInCommandsCatalog.cs +++ b/src/dotnet/BuiltInCommandsCatalog.cs @@ -143,6 +143,10 @@ namespace Microsoft.DotNet.Cli ["parse"] = new BuiltInCommandMetadata { Command = ParseCommand.Run + }, + ["internal-reportinstallsuccess"] = new BuiltInCommandMetadata + { + Command = InternalReportinstallsuccess.Run } }; } diff --git a/src/dotnet/Parser.cs b/src/dotnet/Parser.cs index a377cbd3e..5f5bdd6c8 100644 --- a/src/dotnet/Parser.cs +++ b/src/dotnet/Parser.cs @@ -54,6 +54,7 @@ namespace Microsoft.DotNet.Cli Create.Command("msbuild", ""), Create.Command("vstest", ""), CompleteCommandParser.Complete(), + InternalReportinstallsuccessCommandParser.InternalReportinstallsuccess(), CommonOptions.HelpOption(), Create.Option("--info", ""), Create.Option("-d", ""), diff --git a/src/dotnet/Telemetry.cs b/src/dotnet/Telemetry.cs index baa0d7015..457e6f7af 100644 --- a/src/dotnet/Telemetry.cs +++ b/src/dotnet/Telemetry.cs @@ -76,6 +76,15 @@ namespace Microsoft.DotNet.Cli ); } + public void ThreadBlockingTrackEvent(string eventName, IDictionary properties, IDictionary measurements) + { + if (!Enabled) + { + return; + } + TrackEventTask(eventName, properties, measurements); + } + private void InitializeTelemetry() { try diff --git a/src/dotnet/commands/dotnet-internal-reportinstallsuccess/InternalReportinstallsuccessCommand.cs b/src/dotnet/commands/dotnet-internal-reportinstallsuccess/InternalReportinstallsuccessCommand.cs new file mode 100644 index 000000000..f3ac8702f --- /dev/null +++ b/src/dotnet/commands/dotnet-internal-reportinstallsuccess/InternalReportinstallsuccessCommand.cs @@ -0,0 +1,56 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Linq; +using System.IO; +using System.Collections.Generic; +using Microsoft.DotNet.Configurer; + +namespace Microsoft.DotNet.Cli +{ + public class InternalReportinstallsuccess + { + internal const string TelemetrySessionIdEnvironmentVariableName = "DOTNET_CLI_TELEMETRY_SESSIONID"; + + public static int Run(string[] args) + { + var telemetry = new ThreadBlockingTelemetry(); + ProcessInputAndSendTelemetry(args, telemetry); + + return 0; + } + + public static void ProcessInputAndSendTelemetry(string[] args, ITelemetry telemetry) + { + var parser = Parser.Instance; + var result = parser.ParseFrom("dotnet internal-reportinstallsuccess", args); + + var internalReportinstallsuccess = result["dotnet"]["internal-reportinstallsuccess"]; + + var exeName = Path.GetFileName(internalReportinstallsuccess.Arguments.Single()); + telemetry.TrackEvent( + "reportinstallsuccess", + new Dictionary { { "exeName", exeName } }, + new Dictionary()); + } + + internal class ThreadBlockingTelemetry : ITelemetry + { + private Telemetry telemetry; + + internal ThreadBlockingTelemetry() + { + var sessionId = + Environment.GetEnvironmentVariable(TelemetrySessionIdEnvironmentVariableName); + telemetry = new Telemetry(new FirstTimeUseNoticeSentinel(new CliFallbackFolderPathCalculator()), sessionId); + } + public bool Enabled => telemetry.Enabled; + + public void TrackEvent(string eventName, IDictionary properties, IDictionary measurements) + { + telemetry.ThreadBlockingTrackEvent(eventName, properties, measurements); + } + } + } +} \ No newline at end of file diff --git a/src/dotnet/commands/dotnet-internal-reportinstallsuccess/InternalReportinstallsuccessCommandParser.cs b/src/dotnet/commands/dotnet-internal-reportinstallsuccess/InternalReportinstallsuccessCommandParser.cs new file mode 100644 index 000000000..1c83a86b3 --- /dev/null +++ b/src/dotnet/commands/dotnet-internal-reportinstallsuccess/InternalReportinstallsuccessCommandParser.cs @@ -0,0 +1,16 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Linq; +using Microsoft.DotNet.Cli.CommandLine; + +namespace Microsoft.DotNet.Cli +{ + internal static class InternalReportinstallsuccessCommandParser + { + public static Command InternalReportinstallsuccess() => + Create.Command( + "internal-reportinstallsuccess", "internal only", + Accept.ExactlyOneArgument()); + } +} \ No newline at end of file diff --git a/test/dotnet.Tests/TelemetryCommandTest.cs b/test/dotnet.Tests/TelemetryCommandTest.cs index cb4a943c2..5fd8a9689 100644 --- a/test/dotnet.Tests/TelemetryCommandTest.cs +++ b/test/dotnet.Tests/TelemetryCommandTest.cs @@ -17,14 +17,15 @@ namespace Microsoft.DotNet.Tests public bool Enabled { get; set; } public string EventName { get; set; } + public IDictionary Properties { get; set; } public void TrackEvent(string eventName, IDictionary properties, IDictionary measurements) { EventName = eventName; + Properties = properties; } } - public class TelemetryCommandTests : TestBase { [Fact] @@ -35,5 +36,23 @@ namespace Microsoft.DotNet.Tests Microsoft.DotNet.Cli.Program.ProcessArgs(args, mockTelemetry); Assert.Equal(mockTelemetry.EventName, args[0]); } + + [Fact] + public void InternalreportinstallsuccessCommandCollectExeNameWithEventname() + { + MockTelemetry mockTelemetry = new MockTelemetry(); + string[] args = { "c:\\mypath\\dotnet-sdk-latest-win-x64.exe" }; + + InternalReportinstallsuccess.ProcessInputAndSendTelemetry(args, mockTelemetry); + + mockTelemetry.EventName.Should().Be("reportinstallsuccess"); + mockTelemetry.Properties["exeName"].Should().Be("dotnet-sdk-latest-win-x64.exe"); + } + + [Fact] + public void InternalreportinstallsuccessCommandIsRegistedInBuiltIn() + { + BuiltInCommandsCatalog.Commands.Should().ContainKey("internal-reportinstallsuccess"); + } } }