Skip to content

Commit

Permalink
Was able to reproduce issue #2846 consistently by having the dbcontex…
Browse files Browse the repository at this point in the history
…t open / edited (not saved) and invoking reverse engineer. System dialog would open which corrupted the existing process flow. Removed code in StatusBarHelper that I added early in development that didn't allow system dialog to place nicely. Also refactored flow from page 3 to page 4 for a more consistent user experience. Tested by opening all dialogs and taking steps noted above to reproduce - had expected results with no issues.
  • Loading branch information
William Kratochvil committed Feb 15, 2025
1 parent 850c968 commit 3dbd356
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 78 deletions.
14 changes: 7 additions & 7 deletions src/GUI/EFCorePowerTools/EFCorePowerToolsPackage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,13 @@ protected override async Task InitializeAsync(CancellationToken cancellationToke

if (oleMenuCommandService != null)
{
////oleMenuCommandService.AddCommand(new OleMenuCommand(
//// OnProjectContextMenuInvokeHandler,
//// null,
//// OnProjectMenuBeforeQueryStatus,
//// new CommandID(
//// GuidList.GuidDbContextPackageCmdSet,
//// (int)PkgCmdIDList.cmdidWizardPoc)));
oleMenuCommandService.AddCommand(new OleMenuCommand(
OnProjectContextMenuInvokeHandler,
null,
OnProjectMenuBeforeQueryStatus,
new CommandID(
GuidList.GuidDbContextPackageCmdSet,
(int)PkgCmdIDList.cmdidWizardPoc)));

oleMenuCommandService.AddCommand(new OleMenuCommand(
OnProjectContextMenuInvokeHandler,
Expand Down
4 changes: 2 additions & 2 deletions src/GUI/EFCorePowerTools/EFCorePowerToolsPackage.vsct
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
</Menus>

<Buttons>
<!--<Button guid="guidDbContextPackageCmdSet" id="cmdidWizardPoc" priority="0x0100" type="Button">
<Button guid="guidDbContextPackageCmdSet" id="cmdidWizardPoc" priority="0x0100" type="Button">
<Parent guid="guidDbContextPackageCmdSet" id="cmdidEdmProjectMenuItemsGroup" />
<Icon guid="ImageCatalogGuid" id="DatabaseConfigurationFile" />
<CommandFlag>IconIsMoniker</CommandFlag>
Expand All @@ -93,7 +93,7 @@
<Strings>
<ButtonText>Reverse Engineer Wizard (preview)</ButtonText>
</Strings>
</Button>-->
</Button>

<Button guid="guidDbContextPackageCmdSet" id="cmdidReverseEngineerCodeFirst" priority="0x0101" type="Button">
<Parent guid="guidDbContextPackageCmdSet" id="cmdidEdmProjectMenuItemsGroup" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,9 +273,6 @@ public void ShowStatus(
// run in a dispatcher here to force the UI to be updated before render cycle
#pragma warning disable VSTHRD001 // Avoid legacy thread switching APIs
Dispatcher.CurrentDispatcher.Invoke(() => ShowStatusInternal(message, timeoutMs, imageSource, spin, flashIcon: flashIcon));

// BillKrat: Allow the page to refresh so we don't have to look at blank page while the data loads
Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new Action(delegate { }));
#pragma warning restore VSTHRD001 // Avoid legacy thread switching APIs
}
else
Expand Down
59 changes: 1 addition & 58 deletions src/GUI/EFCorePowerTools/Wizard/Wiz3_EfCoreModelDialog.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using System;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Windows;
using EFCorePowerTools.Common.Models;
using EFCorePowerTools.Contracts.ViewModels;
Expand All @@ -14,7 +12,6 @@
using EFCorePowerTools.Messages;
using EFCorePowerTools.ViewModels;
using Microsoft.VisualStudio.Shell;
using RevEng.Common;

namespace EFCorePowerTools.Wizard
{
Expand Down Expand Up @@ -114,14 +111,6 @@ private void GenerateFiles_Click(object sender, RoutedEventArgs e)
};
}

var project = wea.Project;
var optionsPath = wea.OptionsPath;
var options = wea.Options;
var userOptions = wea.UserOptions;
var namingOptionsAndPath = wea.NamingOptionsAndPath;
var onlyGenerate = wea.OnlyGenerate;
var forceEdit = wea.ForceEdit;

if (IsPageDirty)
{
var isSuccessful2 = false;
Expand All @@ -144,54 +133,8 @@ private void GenerateFiles_Click(object sender, RoutedEventArgs e)
});
}

wizardViewModel.GenerateStatus = string.Empty;
wizardViewModel.Bll.GetModelOptionsPostDialog(options, project.Name, wea, wizardViewModel.Model);
cancelButton.IsEnabled = false; // Once processed we can't cancel - only finish
NextButton.IsEnabled = true;
var errorMessage = string.Empty;

this.applyPresets(wizardViewModel.Model);

var isSuccessful = false;
ThreadHelper.JoinableTaskFactory.Run(async () =>
{
isSuccessful = await InvokeWithErrorHandlingAsync(async () =>
{
await wizardViewModel.Bll.SaveOptionsAsync(project, optionsPath, options, userOptions, new Tuple<List<Schema>, string>(options.CustomReplacers, namingOptionsAndPath.Item2));

await RevEngWizardHandler.InstallNuGetPackagesAsync(project, onlyGenerate, options, forceEdit, wea);

var neededPackages = await wea.Project.GetNeededPackagesAsync(wea.Options);
var missingProviderPackage = neededPackages.Find(p => p.DatabaseTypes.Contains(options.DatabaseType) && p.IsMainProviderPackage && !p.Installed)?.PackageId;
if (options.InstallNuGetPackage || options.SelectedToBeGenerated == 2)
{
missingProviderPackage = null;
}

wea.ReverseEngineerStatus = await wizardViewModel.Bll.GenerateFilesAsync(project, options, missingProviderPackage, onlyGenerate, neededPackages, true);

var postRunFile = Path.Combine(Path.GetDirectoryName(optionsPath), "efpt.postrun.cmd");
if (File.Exists(postRunFile))
{
Process.Start($"\"{postRunFile}\"");
}

return true;
});

NextButton.IsEnabled = isSuccessful;
});

if (string.IsNullOrEmpty(errorMessage))
{
Statusbar.Status.ShowStatus();
wizardViewModel.GenerateStatus = wea.ReverseEngineerStatus;
}
else
{
wizardViewModel.GenerateStatus = $"❌ {errorMessage}";
}

Telemetry.TrackEvent("PowerTools.ReverseEngineer");
}

Expand Down
70 changes: 65 additions & 5 deletions src/GUI/EFCorePowerTools/Wizard/Wiz4_StatusDialog.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
using System.Windows;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using EFCorePowerTools.Contracts.Wizard;
using EFCorePowerTools.Extensions;
using EFCorePowerTools.Handlers.ReverseEngineer;
using EFCorePowerTools.Locales;
using EFCorePowerTools.Messages;
using EFCorePowerTools.ViewModels;
using Microsoft.VisualStudio.Shell;
using RevEng.Common;

namespace EFCorePowerTools.Wizard
{
Expand All @@ -19,8 +27,7 @@ public Wiz4_StatusDialog(WizardDataViewModel viewModel, IWizardView wizardView)
Loaded += WizardPage4_Loaded;

InitializeComponent();

Loaded += (s, e) => OnPageVisible(s, null);
InitializeMessengerWithStatusbar(Statusbar, ReverseEngineerLocale.StatusbarGeneratingFiles);
}

private void WizardPage4_Loaded(object sender, RoutedEventArgs e)
Expand All @@ -32,6 +39,8 @@ private void WizardPage4_Loaded(object sender, RoutedEventArgs e)
protected override void OnPageVisible(object sender, StatusbarEventArgs e)
#pragma warning restore SA1202 // Elements should be ordered by access
{
var wea = wizardViewModel.WizardEventArgs;

IsPageLoaded = wizardViewModel.IsPage4Initialized;

if (wizardViewModel.ErrorMessage != null)
Expand All @@ -45,18 +54,69 @@ protected override void OnPageVisible(object sender, StatusbarEventArgs e)

if (!IsPageLoaded)
{
var project = wea.Project;
var optionsPath = wea.OptionsPath;
var options = wea.Options;
var userOptions = wea.UserOptions;
var namingOptionsAndPath = wea.NamingOptionsAndPath;
var onlyGenerate = wea.OnlyGenerate;
var forceEdit = wea.ForceEdit;

// When generating we'll initialize the page to known state
wizardViewModel.GenerateStatus = string.Empty;
Statusbar.Status.ShowStatus(ReverseEngineerLocale.StatusbarGeneratingFiles);
PreviousButton.IsEnabled = false;
FinishButton.IsEnabled = false;

wizardViewModel.GenerateStatus = string.Empty;
wizardViewModel.Bll.GetModelOptionsPostDialog(options, project.Name, wea, wizardViewModel.Model);
var errorMessage = string.Empty;

var isSuccessful = false;
ThreadHelper.JoinableTaskFactory.Run(async () =>
{
isSuccessful = await InvokeWithErrorHandlingAsync(async () =>
{
await wizardViewModel.Bll.SaveOptionsAsync(project, optionsPath, options, userOptions, new Tuple<List<Schema>, string>(options.CustomReplacers, namingOptionsAndPath.Item2));

await RevEngWizardHandler.InstallNuGetPackagesAsync(project, onlyGenerate, options, forceEdit, wea);

var neededPackages = await wea.Project.GetNeededPackagesAsync(wea.Options);
var missingProviderPackage = neededPackages.Find(p => p.DatabaseTypes.Contains(options.DatabaseType) && p.IsMainProviderPackage && !p.Installed)?.PackageId;
if (options.InstallNuGetPackage || options.SelectedToBeGenerated == 2)
{
missingProviderPackage = null;
}

wea.ReverseEngineerStatus = await wizardViewModel.Bll.GenerateFilesAsync(project, options, missingProviderPackage, onlyGenerate, neededPackages, true);

var postRunFile = Path.Combine(Path.GetDirectoryName(optionsPath), "efpt.postrun.cmd");
if (File.Exists(postRunFile))
{
Process.Start($"\"{postRunFile}\"");
}

return true;
});
});

if (string.IsNullOrEmpty(errorMessage))
{
Statusbar.Status.ShowStatus();
wizardViewModel.GenerateStatus = wea.ReverseEngineerStatus;
}
else
{
wizardViewModel.GenerateStatus = $"❌ {errorMessage}";
}
}
}

private void TextChangedEventHandler(object sender, System.Windows.Controls.TextChangedEventArgs e)
{
var wea = wizardViewModel.WizardEventArgs;

var textBox = sender as TextBox;
if (textBox != null && !string.IsNullOrEmpty(textBox.Text) && PreviousButton != null && FinishButton != null)
if (textBox != null && !string.IsNullOrEmpty(textBox.Text) && PreviousButton != null && FinishButton != null && !string.IsNullOrEmpty(wea.ReverseEngineerStatus))
{
// If here then we have status update - enabled buttons
Statusbar.Status.ShowStatus(); // Will reset status bar
Expand Down
9 changes: 8 additions & 1 deletion src/GUI/EFCorePowerTools/Wizard/WizardDialogBox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,14 @@ private void WizardLauncher_WizardReturn(object sender, WizardReturnEventArgs e)
{
if (DialogResult == null)
{
DialogResult = e.Result == WizardResult.Finished;
try
{
DialogResult = e.Result == WizardResult.Finished;
}
catch
{
this.Close();
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
Expand Down Expand Up @@ -115,7 +115,7 @@ public async Task ReverseEngineerCodeFirstLaunchWizardAsync(WizardEventArgs wiza
// data using existing business logic; to simplify wizard refactor this handler
// serves as the BLL (and DAL)
var wizard = new WizardDialogBox(this, wizardArgs, wizardViewModel);
wizard.ShowDialog();
wizard.Show();
await Task.Yield();
}
catch (AggregateException ae)
Expand Down

0 comments on commit 3dbd356

Please sign in to comment.