private async Task <bool> ChooseDataBaseConnectionAsync(ReverseEngineerOptions options)
        {
            var databaseList = vsDataHelper.GetDataConnections(_package);
            var dacpacList   = await EnvDTEExtensions.GetDacpacFilesInActiveSolutionAsync();

            var psd = _package.GetView <IPickServerDatabaseDialog>();

            if (databaseList != null && databaseList.Any())
            {
                psd.PublishConnections(databaseList.Select(m => new DatabaseConnectionModel
                {
                    ConnectionName   = m.Value.ConnectionName,
                    ConnectionString = m.Value.ConnectionString,
                    DatabaseType     = m.Value.DatabaseType,
                    DataConnection   = m.Value.DataConnection,
                }));
            }

            if (dacpacList != null && dacpacList.Any())
            {
                psd.PublishDefinitions(dacpacList.Select(m => new DatabaseDefinitionModel
                {
                    FilePath = m
                }));
            }

            if (options.FilterSchemas && options.Schemas != null && options.Schemas.Any())
            {
                psd.PublishSchemas(options.Schemas);
            }

            psd.PublishCodeGenerationMode(options.CodeGenerationMode);

            if (!string.IsNullOrEmpty(options.UiHint))
            {
                psd.PublishUiHint(options.UiHint);
            }

            var pickDataSourceResult = psd.ShowAndAwaitUserResponse(true);

            if (!pickDataSourceResult.ClosedByOK)
            {
                return(false);
            }

            options.CodeGenerationMode = pickDataSourceResult.Payload.CodeGenerationMode;
            options.FilterSchemas      = pickDataSourceResult.Payload.FilterSchemas;
            options.Schemas            = options.FilterSchemas ? pickDataSourceResult.Payload.Schemas?.ToList() : null;
            options.UiHint             = pickDataSourceResult.Payload.UiHint;
            options.Dacpac             = pickDataSourceResult.Payload.Definition?.FilePath;

            if (pickDataSourceResult.Payload.Connection != null)
            {
                options.ConnectionString = pickDataSourceResult.Payload.Connection.ConnectionString;
                options.DatabaseType     = pickDataSourceResult.Payload.Connection.DatabaseType;
            }

            return(true);
        }
        private async Task <bool> ChooseDataBaseConnectionByUiHintAsync(ReverseEngineerOptions options)
        {
            await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

            var databaseList = vsDataHelper.GetDataConnections(_package);

            if (databaseList != null && databaseList.Any())
            {
                var dataBaseInfo = databaseList.Values.FirstOrDefault(m => m.ConnectionName == options.UiHint);
                if (dataBaseInfo != null)
                {
                    options.ConnectionString = dataBaseInfo.ConnectionString;
                    options.DatabaseType     = dataBaseInfo.DatabaseType;
                    return(true);
                }
            }

            var dacpacList = await EnvDTEExtensions.GetDacpacFilesInActiveSolutionAsync();

            if (dacpacList != null && dacpacList.Any())
            {
                if (!string.IsNullOrEmpty(options.UiHint) &&
                    options.UiHint.EndsWith(".sqlproj", StringComparison.OrdinalIgnoreCase))
                {
                    var candidate = dacpacList
                                    .Where(m => !string.IsNullOrWhiteSpace(m) && m.EndsWith(".sqlproj"))
                                    .FirstOrDefault(m => m.Equals(options.UiHint, StringComparison.OrdinalIgnoreCase));

                    if (candidate != null)
                    {
                        options.Dacpac = candidate;
                        return(true);
                    }
                }
            }

            return(false);
        }
        private async Task <DatabaseConnectionModel> GetDatabaseInfoAsync(ReverseEngineerOptions options)
        {
            await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

            var dbInfo = new DatabaseConnectionModel();

            if (!string.IsNullOrEmpty(options.ConnectionString))
            {
                dbInfo.ConnectionString = options.ConnectionString;
                dbInfo.DatabaseType     = options.DatabaseType;
            }

            if (!string.IsNullOrEmpty(options.Dacpac))
            {
                dbInfo.DatabaseType      = DatabaseType.SQLServerDacpac;
                dbInfo.ConnectionString  = $"Data Source=(local);Initial Catalog={Path.GetFileNameWithoutExtension(options.Dacpac)};Integrated Security=true;";
                options.ConnectionString = dbInfo.ConnectionString;
                options.DatabaseType     = dbInfo.DatabaseType;

                options.Dacpac = await EnvDTEExtensions.BuildSqlProjAsync(options.Dacpac);

                if (string.IsNullOrEmpty(options.Dacpac))
                {
                    VSHelper.ShowMessage(ReverseEngineerLocale.UnableToBuildSelectedDatabaseProject);
                    return(null);
                }
            }

            if (dbInfo.DatabaseType == DatabaseType.Undefined)
            {
                VSHelper.ShowError($"{ReverseEngineerLocale.UnsupportedProvider}");
                return(null);
            }

            return(dbInfo);
        }
        private async Task <string> GetOutputInternalAsync(string outputPath, string projectPath, GenerationType generationType, string contextName, string migrationIdentifier, string nameSpace)
        {
            await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

            var launchPath = await DropNetCoreFilesAsync();

            var startupOutputPath = await EnvDTEExtensions.GetStartupProjectOutputPathAsync() ?? outputPath;

            outputPath = FixExtension(outputPath);

            startupOutputPath = FixExtension(startupOutputPath);

            var startInfo = new ProcessStartInfo
            {
                FileName               = Path.Combine(Path.GetDirectoryName(launchPath) ?? throw new InvalidOperationException(), "efpt.exe"),
                Arguments              = "\"" + outputPath + "\"",
                UseShellExecute        = false,
                RedirectStandardOutput = true,
                RedirectStandardError  = true,
                CreateNoWindow         = true,
                StandardOutputEncoding = Encoding.UTF8,
            };

            var outputs = " \"" + outputPath + "\" \"" + startupOutputPath + "\" ";

            startInfo.Arguments = outputs;

            switch (generationType)
            {
            case GenerationType.Dgml:
                break;

            case GenerationType.Ddl:
                startInfo.Arguments = "ddl" + outputs;
                break;

            case GenerationType.DebugView:
                break;

            case GenerationType.MigrationStatus:
                startInfo.Arguments = "migrationstatus" + outputs;
                break;

            case GenerationType.MigrationApply:
                startInfo.Arguments = "migrate" + outputs + contextName;
                break;

            case GenerationType.MigrationAdd:
                startInfo.Arguments = "addmigration" + outputs + "\"" + projectPath + "\" " + contextName + " " + migrationIdentifier + " " + nameSpace;
                break;

            case GenerationType.MigrationScript:
                startInfo.Arguments = "scriptmigration" + outputs + contextName;
                break;

            case GenerationType.DbContextList:
                startInfo.Arguments = "contextlist" + outputs;
                break;

            case GenerationType.DbContextCompare:
                startInfo.Arguments = "schemacompare" + outputs + "\"" + migrationIdentifier + "\" " + contextName;
                break;

            default:
                break;
            }

            var fileRoot = Path.Combine(Path.GetDirectoryName(outputPath), Path.GetFileNameWithoutExtension(outputPath));
            var efptPath = Path.Combine(launchPath, "efpt.dll");

            var depsFile      = fileRoot + ".deps.json";
            var runtimeConfig = fileRoot + ".runtimeconfig.json";

            var projectAssetsFile = await _project.GetAttributeAsync("ProjectAssetsFile");

            var runtimeFrameworkVersion = await _project.GetAttributeAsync("RuntimeFrameworkVersion");

            var dotNetParams = $"exec --depsfile \"{depsFile}\" ";

            if (projectAssetsFile != null && File.Exists(projectAssetsFile))
            {
                var lockFile = LockFileUtilities.GetLockFile(projectAssetsFile, NuGet.Common.NullLogger.Instance);

                if (lockFile != null)
                {
                    foreach (var packageFolder in lockFile.PackageFolders)
                    {
                        var path = packageFolder.Path.TrimEnd('\\');
                        dotNetParams += $"--additionalprobingpath \"{path}\" ";
                    }
                }
            }

            if (File.Exists(runtimeConfig))
            {
                dotNetParams += $"--runtimeconfig \"{runtimeConfig}\" ";
            }
            else if (!string.IsNullOrEmpty(runtimeFrameworkVersion))
            {
                dotNetParams += $"--fx-version {runtimeFrameworkVersion} ";
            }

            dotNetParams += $"\"{efptPath}\" ";

            startInfo.WorkingDirectory = Path.GetDirectoryName(outputPath);
            startInfo.FileName         = "dotnet";
            startInfo.Arguments        = dotNetParams + " " + startInfo.Arguments;

            try
            {
                File.WriteAllText(Path.Combine(Path.GetTempPath(), "efptparams.txt"), startInfo.Arguments);
            }
            catch
            {
                // Ignore
            }

            var standardOutput = new StringBuilder();
            var error          = string.Empty;

            using (var process = System.Diagnostics.Process.Start(startInfo))
            {
                while (process != null && !process.HasExited)
                {
                    standardOutput.Append(await process.StandardOutput.ReadToEndAsync());
                }
                if (process != null)
                {
                    standardOutput.Append(await process.StandardOutput.ReadToEndAsync());
                }
                if (process != null)
                {
                    error = await process.StandardError.ReadToEndAsync();
                }
            }

            var result = standardOutput.ToString();

            if (string.IsNullOrEmpty(result) && !string.IsNullOrEmpty(error))
            {
                result = "Error:" + Environment.NewLine + error;
            }

            return(result);
        }