internal async Task BuildBootstrapProjectAsync(ILogger logger, CancellationToken cancellationToken) { string outputText; string errorMessage = null; try { ToolConsole.WriteLineIf(ToolConsole.Verbosity >= Verbosity.Verbose, Resource.RestoringNuGetPackagesMsg); var restoreResult = await this.MSBuildProj.RestoreAsync(logger, cancellationToken).ConfigureAwait(false); MarkupTelemetryHelper.TelemetryPostOperation(restoreResult.ExitCode == 0, "Restore bootstrapper"); if (restoreResult.ExitCode != 0) { ToolConsole.WriteWarning(restoreResult.OutputText); } ToolConsole.WriteLineIf(ToolConsole.Verbosity >= Verbosity.Verbose, Resource.BuildingProjectMsg); var buildResult = await this.MSBuildProj.BuildAsync(logger, cancellationToken).ConfigureAwait(false); MarkupTelemetryHelper.TelemetryPostOperation(buildResult.ExitCode == 0, "Build bootstrapper"); } catch (ProcessRunner.ProcessException exception) { throw new BootstrapException(string.Format(CultureInfo.CurrentCulture, "{0}{1}{2}", exception.Message, Environment.NewLine, Resource.BootstrapErrorDisableReferences)); } }
public static void TelemetryPostOperation(bool succeess, string str) { if (ToolConsole.IsMarkupEnabled && !String.IsNullOrWhiteSpace(str)) { ToolConsole.WriteLine(str, (succeess ? LogTag.TraceSuccess : LogTag.TraceFailure), ToolConsole.Space); } }
internal static void WriteHelp() { if (ToolConsole.Verbosity > Verbosity.Silent && ToolConsole.ToolModeLevel != OperationalContext.Infrastructure) { ToolConsole.WriteLine(HelpGenerator.GenerateHelpText(), LogTag.Important); } }
private async Task GenerateProjectAsync(bool keepBootstrapperDir, ILogger logger, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var projectFullPath = Path.Combine(this.Options.BootstrapPath.FullName, nameof(SvcutilBootstrapper), SvcutilBootstrapper.ProjectName); if (keepBootstrapperDir) { // creating the directory prevents the bootstrapper project from deleting it as it doesn't own it, files will not be deleted either. Directory.CreateDirectory(Path.GetDirectoryName(projectFullPath)); } // If the target framework was provided, it was validated already when processing params. // Bootstrapping is enabled only for netcoreapp or netstandard TFM, let's check. bool isSupportedTFM = TargetFrameworkHelper.IsSupportedFramework(this.Options.TargetFramework.FullName, out var frameworkInfo); Debug.Assert(frameworkInfo.IsDnx, "The bootstrapper has been enabled for a non-DNX platform!"); ToolConsole.WriteLineIf(ToolConsole.Verbosity >= Verbosity.Verbose, Resource.CreatingProjectMsg); using (await SafeLogger.WriteStartOperationAsync(logger, $"Creating project file: \"{projectFullPath}\"").ConfigureAwait(false)) { var svcutilPkgRef = ProjectDependency.FromAssembly(Path.Combine(Path.GetDirectoryName(Tool.FullPath), Tool.AssemblyName + ".dll")); this.MSBuildProj = await MSBuildProj.DotNetNewAsync(projectFullPath, logger, cancellationToken).ConfigureAwait(false); this.MSBuildProj.AddDependency(svcutilPkgRef); // NOTE: If post v2.0 NetStandard ships a different version from NetCore the table below needs to be updated! var targetFramework = frameworkInfo.FullName; if (isSupportedTFM && frameworkInfo.IsKnownDnx) { if (frameworkInfo.Name == FrameworkInfo.Netstandard) { targetFramework = FrameworkInfo.Netcoreapp + TargetFrameworkHelper.NetStandardToNetCoreVersionMap[frameworkInfo.Version]; } this.MSBuildProj.TargetFramework = targetFramework; } // else // The TFM is unknown: either, it was not provided or it is a version not yet known to the tool, // we will use the default TF from the generated project. } foreach (ProjectDependency dependency in this.Options.References) { this.MSBuildProj.AddDependency(dependency); } if (!string.IsNullOrEmpty(this.Options.RuntimeIdentifier)) { this.MSBuildProj.RuntimeIdentifier = this.Options.RuntimeIdentifier; } // Don't treat warnings as errors so the bootstrapper will succeed as often as possible. this.MSBuildProj.ClearWarningsAsErrors(); await this.MSBuildProj.SaveAsync(logger, cancellationToken).ConfigureAwait(false); }
public static void TelemetryPostFault(Exception ex) { if (ToolConsole.IsMarkupEnabled) { var str = Utils.GetExceptionMessage(ex, includeStackTrace: true); ToolConsole.WriteLine(str, LogTag.TraceException, ToolConsole.Space); } }
public bool AfterImportMetadata(ServiceDescriptor serviceDescriptor) { try { // Convert errors to warnings to workaround the issue that many validation errors from XSD compiler // can be ignored. for (int idx = _wsdlImporter.Errors.Count - 1; idx >= _nonWsdlImportErrors; idx--) { var error = _wsdlImporter.Errors[idx]; if (!error.IsWarning) { ToolConsole.ExitCode = ToolExitCode.ValidationErrorTurnedWarning; var warning = new MetadataConversionError(error.Message, isWarning: true); _wsdlImporter.Errors[idx] = warning; } } MarkupTelemetryHelper.SendBindingData(serviceDescriptor.Bindings); Collection <ServiceEndpoint> endpoints = new Collection <ServiceEndpoint>(serviceDescriptor.Endpoints.ToList()); Collection <Binding> bindings = new Collection <Binding>(serviceDescriptor.Bindings.ToList()); Collection <ContractDescription> contracts = new Collection <ContractDescription>(serviceDescriptor.Contracts.ToList()); _codegenExtension.WsdlImported(_wsdlImporter, endpoints, bindings, contracts); } catch (Exception e) { ToolConsole.WriteError(e); } ToolConsole.WriteConversionErrors(_wsdlImporter.Errors); ImportServiceContracts(serviceDescriptor); ToolConsole.WriteConversionErrors(_contractGenerator.Errors); var contractsResolved = true; if (_validateMetadataImport) { _validateMetadataImport = false; contractsResolved = ContractsResolved(serviceDescriptor, this.CodeCompileUnit); if (!contractsResolved) { var importer1 = ServiceDescriptor.DefaultUseMessageFormat ? typeof(DataContractSerializerMessageContractImporter) : typeof(XmlSerializerMessageContractImporter); var importer2 = ServiceDescriptor.DefaultUseMessageFormat ? typeof(XmlSerializerMessageContractImporter) : typeof(DataContractSerializerMessageContractImporter); ToolConsole.WriteWarning(string.Format(CultureInfo.CurrentCulture, SR.WrnCouldNotGenerateContractOperationsFormat, importer1, importer2)); } } // on false, ServiceDescriptor will attempt to use a different contract serializer. return(contractsResolved); }
internal static void WriteHeaderIf(bool condition) { if (condition && ToolConsole.Verbosity > Verbosity.Minimal && ToolConsole.ToolModeLevel != OperationalContext.Infrastructure) { ToolConsole.WriteLine(string.Format(SR.LogoFormat, Tool.ToolName, Tool.PackageVersion, SR.Microsoft_Copyright_CommandLine_Logo), LogTag.Important); if (AppInsightsTelemetryClient.IsUserOptedIn) { ToolConsole.WriteLine(SR.TelemetryEnabled, LogTag.Information); } } }
static public Type[] LoadTypes(Assembly assembly, Verbosity verbosity) { Type[] types; try { types = assembly.GetTypes(); } catch (ReflectionTypeLoadException rtle) { string warning; types = Array.FindAll <Type>(rtle.Types, delegate(Type t) { return(t != null); }); if (verbosity > Verbosity.Normal) { foreach (var ex in rtle.LoaderExceptions) { warning = ex.Message; if (!s_loadTypesWarnings.Contains(warning)) { s_loadTypesWarnings.Add(warning); ToolConsole.WriteWarning(warning); } } if (types.Length == 0) { warning = string.Format(SR.ErrCouldNotLoadTypesFromAssemblyAtFormat, assembly.Location); if (!s_loadTypesWarnings.Contains(warning)) { s_loadTypesWarnings.Add(warning); ToolConsole.WriteWarning(warning); } } else { warning = string.Format(SR.WrnCouldNotLoadTypesFromReferenceAssemblyAtFormat, assembly.Location); if (!s_loadTypesWarnings.Contains(warning)) { s_loadTypesWarnings.Add(warning); ToolConsole.WriteWarning(warning); } } } } return(types); }
// While enabling logging markup option, the tool will append specific prefix string to each console output // This feature is designed for console redirection to get better UI experience also telemetry data collection private static void TelemetryAddProperty(string propName, string propValue) { if (!String.IsNullOrWhiteSpace(propName)) { if (propValue == null) { propValue = "<null>"; } else if (propValue.Trim() == string.Empty) { propValue = "<empty>"; } ToolConsole.WriteLine(propName + LogTag.TraceProperty + propValue, LogTag.TraceProperty, ToolConsole.Space); } }
internal bool ImportServiceContracts(ServiceDescriptor serviceDescriptor) { bool result = false; try { _codegenExtension.ClientGenerating(_contractGenerator); } catch (Exception e) { ToolConsole.WriteError(e); } HttpBindingTracker httpBindingTracker = FindImportExtension <HttpBindingTracker>(); foreach (ContractDescription contractDescription in serviceDescriptor.Contracts) { if (!httpBindingTracker.IsHttpBindingContract(contractDescription) || serviceDescriptor.Endpoints.Any(endpoint => endpoint.Contract == contractDescription)) { _contractGenerator.GenerateServiceContractType(contractDescription); } } try { _codegenExtension.ClientGenerated(_contractGenerator); if (_codegenExtension.ErrorDetected) { ToolConsole.ExitCode = ToolExitCode.ValidationError; } result = !_codegenExtension.ErrorDetected; } catch (NotSupportedException) { throw; } catch (Exception e) { ToolConsole.WriteError(e); } return(result); }
internal async Task <ProcessRunner.ProcessResult> BoostrapSvcutilAsync(bool keepBootstrapperDir, ILogger logger, CancellationToken cancellationToken) { bool redirectOutput = false; if (this.Options.ToolContext == OperationalContext.Infrastructure) { redirectOutput = true; } ProcessRunner.ProcessResult result = null; using (await SafeLogger.WriteStartOperationAsync(logger, "Bootstrapping svcutil ...").ConfigureAwait(false)) { // guard against bootstrapping recursion. if (this.Options.NoBootstrapping != true) { Debug.Fail($"The NoBootstrapping property is not set, this would cause infinite bootstrapping recursion!"); return(null); } if (this.Options.Project != null && StringComparer.OrdinalIgnoreCase.Compare(this.Options.Project.FileName, SvcutilBootstrapper.ProjectName) == 0) { Debug.Fail("Bootstrapping is enabled for the bootstrapper! This would cause an infinite bootstrapping recursion!"); return(null); } // When in Infrastructure mode (WCF CS) it is assumed the initial progress message is to be presented by the calling tool. ToolConsole.WriteLineIf(ToolConsole.ToolModeLevel != OperationalContext.Infrastructure, Resource.BootstrappingApplicationMsg); await GenerateProjectAsync(keepBootstrapperDir, logger, cancellationToken).ConfigureAwait(false); await GenerateProgramFileAsync(logger, cancellationToken).ConfigureAwait(false); var paramsFilePath = await GenerateParamsFileAsync(logger, cancellationToken).ConfigureAwait(false); await BuildBootstrapProjectAsync(logger, cancellationToken).ConfigureAwait(false); ToolConsole.WriteLineIf(ToolConsole.Verbosity >= Verbosity.Verbose, Resource.InvokingProjectMsg); result = await ProcessRunner.RunAsync("dotnet", $"run \"{paramsFilePath}\"", this.MSBuildProj.DirectoryPath, redirectOutput, logger, cancellationToken).ConfigureAwait(false); MarkupTelemetryHelper.TelemetryPostOperation(result.ExitCode == 0, "Invoke svcutil bootstrapper"); } return(result); }
static public Assembly LoadAssembly(string path) { string DotDll = ".dll"; string DotExe = ".exe"; if (path.EndsWith(DotDll, StringComparison.OrdinalIgnoreCase) || path.EndsWith(DotExe, StringComparison.OrdinalIgnoreCase)) { path = path.Remove(path.Length - DotDll.Length, DotDll.Length); } try { return(Assembly.Load(new AssemblyName(path))); } catch (Exception ex) { ToolConsole.WriteWarning(string.Format(SR.ErrUnableToLoadReferenceFormat, path, ex.Message)); return(null); } }
public void BeforeImportMetadata(ServiceDescriptor serviceDescriptor) { _nonWsdlImportErrors = _wsdlImporter.Errors.Count; _wsdlImporter.WsdlImportExtensions.Add(new BindingImportTracker()); _wsdlImporter.WsdlImportExtensions.Add(new HttpBindingTracker()); InitializationHelper.RemoveUnneededSerializers(_options, serviceDescriptor, _wsdlImporter.WsdlImportExtensions); InitializationHelper.ConfigureSerializers(_options, _codeCompileUnit, _wsdlImporter); try { _codegenExtension.WsdlImporting(_wsdlImporter); } catch (Exception e) { ToolConsole.WriteError(e); } }
internal static void WriteConversionErrors(Collection <MetadataConversionError> errors) { if (ToolConsole.Verbosity == Verbosity.Silent) { // filter out warnings if there are no errors. bool isError = false; foreach (var err in errors) { if (!err.IsWarning) { isError = true; break; } } if (!isError) { for (int idx = errors.Count - 1; idx >= 0; idx--) { if (errors[idx].IsWarning) { errors.RemoveAt(idx); } } } } if (errors.Count > 0) { foreach (MetadataConversionError conversionError in errors) { if (!string.IsNullOrWhiteSpace(conversionError.Message)) { ToolConsole.WriteConversionError(conversionError); } } } }
private void LogMessage(string message, LogTag logTag, bool logToUI = false) { if (this.EnableTracing || logToUI) { message = message?.Trim(); if (!string.IsNullOrEmpty(message)) { if (logTag == LogTag.Error) { ToolConsole.WriteError(message, isTrace: !logToUI); } else if (logTag == LogTag.Warning) { ToolConsole.WriteWarning(message, isTrace: !logToUI); } else { ToolConsole.WriteLine(message, logToUI ? LogTag.Information : LogTag.LogMessage); } } } }
internal static async Task <int> MainAsync(string[] args, ILogger logger, CancellationToken cancellationToken) { int result = -1; CommandProcessorOptions options = null; WaitForDebugger(); try { options = await CommandProcessorOptions.ParseArgumentsAsync(args, logger, cancellationToken); ValidateUICulture(options); if (options.NoTelemetry == true) { AppInsightsTelemetryClient.IsUserOptedIn = false; } ToolConsole.Init(options); ToolConsole.WriteHeaderIf(options.NoLogo != true); ThrowOnValidationErrors(options); if (options.Help == true) { ToolConsole.WriteHelp(); result = (int)ToolExitCode.Success; } else { // Show early warnings var earlyWarnings = options.Warnings; foreach (string warning in earlyWarnings.Distinct()) { ToolConsole.WriteWarning(warning); } var operationMessage = (options.IsUpdateOperation ? "Update" : "Add") + " web service reference operation started!"; using (var safeLogger = await SafeLogger.WriteStartOperationAsync(options.Logger, operationMessage).ConfigureAwait(false)) { await options.ResolveAsync(cancellationToken).ConfigureAwait(false); ThrowOnValidationErrors(options); options.ProviderId = Tool.ToolName; options.Version = Tool.PackageVersion; foreach (string warning in options.Warnings.Distinct().Except(earlyWarnings)) { ToolConsole.WriteWarning(warning); } if (options.RequiresBoostrapping) { using (var bootstrapper = new SvcutilBootstrapper(options.CloneAs <SvcutilOptions>())) { await options.SetupBootstrappingDirectoryAsync(options.Logger, cancellationToken).ConfigureAwait(false); var bootstrapResult = await bootstrapper.BoostrapSvcutilAsync(options.KeepBootstrapDir, options.Logger, cancellationToken).ConfigureAwait(false); ToolConsole.WriteLine(bootstrapResult.OutputText); result = bootstrapResult.ExitCode; } } else { result = (int) await RunAsync(options, cancellationToken).ConfigureAwait(false); } if (IsSuccess(result)) { if (!File.Exists(options.OutputFile.FullName)) { await safeLogger.WriteMessageAsync("The process completed successfully but no proxy file was found!", logToUI : false); throw new ToolArgumentException(SR.ErrUnexpectedError); } else { await GenerateParamsFileAsync(options, options.Logger, cancellationToken); if (CanAddProjectReferences(options) && !await AddProjectReferencesAsync(options.Project, options, cancellationToken).ConfigureAwait(false)) { result = (int)ToolExitCode.InputError; } } // clean up only on success to allow to troubleshoot any problems on failure. options?.Cleanup(); } } } } catch (Exception e) { result = await ProcessExceptionAsync(e, options); } finally { try { // Don't log telemetry if we're running from bootstrapper or connected service. if (options?.ToolContext <= OperationalContext.Global) { var properties = new Dictionary <string, string>() { { "IsUpdate", (options?.IsUpdateOperation).ToString() }, { "TargetFramework", options?.TargetFramework?.FullName }, { "Parameters", options?.ToTelemetryString() }, { "ExitCode", result.ToString() }, { "RequiresBootstrapping", options?.RequiresBoostrapping.ToString() }, }; var telemetryClient = await AppInsightsTelemetryClient.GetInstanceAsync(cancellationToken).ConfigureAwait(false); telemetryClient.TrackEvent("ToolRun", properties); } } catch { } } return(result); }
private static async Task <int> ProcessExceptionAsync(Exception ex, CommandProcessorOptions options) { int retVal = (int)ToolExitCode.Unknown; Debug.Assert(ex != null, "exception should not be null!"); if (ex != null) { try { s_processingException = true; var agex = ex as AggregateException; if (agex != null) { foreach (var ax in agex.InnerExceptions) { retVal = await ProcessExceptionAsync(ax, options); } } else if (ex is BootstrapException bootstrapEx) { ToolConsole.WriteToolError(ex); retVal = bootstrapEx.ExitCode; } else if (ex is ProcessRunner.ProcessException rpe) { ToolConsole.WriteError(rpe, null); retVal = rpe.ExitCode; } else if (ex is ToolArgumentException ae) { ToolConsole.WriteToolError(ae); retVal = (int)ae.ExitCode; } else if (ex is ToolRuntimeException rt) { ToolConsole.WriteToolError(rt); retVal = (int)rt.ExitCode; } else if (ex is DcNS.InvalidDataContractException dce) { ToolConsole.WriteError(dce); retVal = (int)ToolExitCode.RuntimeError; } else if (Utils.IsUnexpected(ex)) { ToolConsole.WriteError(SR.ErrUnexpectedError); retVal = (int)ToolExitCode.RuntimeError; } else // (Exception e) { ToolConsole.WriteError(ex); retVal = (int)ToolExitCode.Unknown; } // don't log aggregate exceptions as the internal exceptions are already logged. if (agex == null) { string exMsg = null; if (options?.Logger != null) { exMsg = Utils.GetExceptionMessage(ex, true); await options.Logger.WriteErrorAsync(exMsg, logToUI : false).ConfigureAwait(false); } // Don't log telemetry if we're running from bootstrapper or connected service. // if options = null, it must be that a parsing exception occurred. if (options == null || options.ToolContext <= OperationalContext.Global) { exMsg = exMsg ?? Utils.GetExceptionMessage(ex, true); var telemetryClient = await AppInsightsTelemetryClient.GetInstanceAsync(CancellationToken.None).ConfigureAwait(false); telemetryClient.TrackError("Exception", exMsg); } } } catch { } } return(retVal); }
internal static async Task <ToolExitCode> RunAsync(CommandProcessorOptions options, CancellationToken cancellationToken) { ImportModule importModule = null; var credsProvicer = new CmdCredentialsProvider(); ServiceDescriptor serviceDescriptor = options.Inputs.Count == 1 ? new ServiceDescriptor(options.Inputs[0].ToString(), credsProvicer, credsProvicer, credsProvicer) : new ServiceDescriptor(options.Inputs.Select(i => i.ToString()).ToList(), credsProvicer, credsProvicer, credsProvicer); // When in Infrastructure mode (WCF CS) it is assumed the metadata docs have been downloaded and passed in as wsdl files. if (options.ToolContext != OperationalContext.Infrastructure) { if (serviceDescriptor.MetadataUrl != null) { ToolConsole.WriteLine(string.Format(SR.RetreivingMetadataMsgFormat, serviceDescriptor.MetadataUrl.AbsoluteUri)); } else { var displayUri = serviceDescriptor.MetadataFiles.Count() == 1 ? serviceDescriptor.MetadataFiles.First().LocalPath : SR.WsdlOrSchemaFilesMsg; ToolConsole.WriteLine(string.Format(SR.ReadingMetadataMessageFormat, displayUri)); } } using (await SafeLogger.WriteStartOperationAsync(options.Logger, "Importing metadata ...").ConfigureAwait(false)) { try { await serviceDescriptor.ImportMetadataAsync( (wi) => importModule = new ImportModule(options, serviceDescriptor, wi), (sd) => importModule.BeforeImportMetadata(sd), (sd) => importModule.AfterImportMetadata(sd), cancellationToken).ConfigureAwait(false); } catch (Exception ex) { if (Utils.IsFatalOrUnexpected(ex)) { throw; } var exception = new ToolInputException(Utils.GetExceptionMessage(ex), ex); if (serviceDescriptor.MetadataUrl != null) { exception = new ToolMexException(exception, serviceDescriptor.MetadataUrl); } throw exception; } } using (await SafeLogger.WriteStartOperationAsync(options.Logger, "Processing Code DOM ...").ConfigureAwait(false)) { ToolConsole.WriteLine(SR.GeneratingFiles); CodeSerializer codeSerializer = new CodeSerializer(options, serviceDescriptor.MetadataDocuments); var filePath = codeSerializer.Save(importModule.CodeCompileUnit); // When in Infrastructure mode (WCF CS) it is assumed the output file path have been provided so no need to display it. ToolConsole.WriteLineIf(options.ToolContext != OperationalContext.Infrastructure, filePath, LogTag.Important); } return(ToolConsole.ExitCode); }
public static async Task <AppInsightsTelemetryClient> GetInstanceAsync(CancellationToken cancellationToken) { if (s_instance == null) { try { if (!bool.TryParse(Environment.GetEnvironmentVariable(testModeVariable), out bool testMode)) { testMode = false; } lock (s_lockObj) { if (s_instance == null) { if (!IsUserOptedIn) { // If the user hasn't opted in return now with a null telemetry client to ensure we don't create any telemetry context. return(new AppInsightsTelemetryClient(null)); } TelemetryConfiguration config; try { config = TelemetryConfiguration.Active; } catch (InvalidOperationException) { config = new TelemetryConfiguration(); } config.TelemetryChannel.DeveloperMode = testMode; s_instance = new AppInsightsTelemetryClient(new TelemetryClient(config)); } } var telemetryClient = s_instance._telemetryClient; telemetryClient.InstrumentationKey = instrumentationKey; // Populate context with properties that are common and should be logged for all events. var context = telemetryClient.Context; context.Device.OperatingSystem = GetOperatingSystemString(); #if !NETCORE10 // Set the user id to a stable hash of the user's current username. Users with the same username // or those with hash collisions will show up as the same id. So the user id won't be perfectly unique. // However, it will give us some idea of how many different users are using the tool. context.User.Id = GetStableHashCode(Environment.UserName).ToString(); #endif // DebugLogger tracks telemetry when adding exceptions. We pass null for the logger to avoid the possibility of an endless cyclic call if something goes wrong in GetSdkVersionAsync. var sdkVersion = await ProjectPropertyResolver.GetSdkVersionAsync(System.IO.Directory.GetCurrentDirectory(), null /* logger */, cancellationToken).ConfigureAwait(false); context.Properties["SvcUtil.Version"] = Tool.PackageVersion; context.Properties["Dotnet.Version"] = string.IsNullOrEmpty(sdkVersion) ? "unknown" : sdkVersion; context.Properties["TestMode"] = testMode.ToString(); } catch (Exception ex) { #if DEBUG ToolConsole.WriteWarning(ex.Message); #endif s_isUserOptedIn = false; } } return(s_instance); }