TemplateStudio
TemplateStudio copied to clipboard
NullRefException when creating project at the drive root with "Solution and project in same directory" checked
Describe the bug
System.NullReferenceException: Object reference not set to an instance of an object. at Microsoft.Templates.Core.Gen.GenController.ValidateUserSelection(UserSelection userSelection, Boolean isNewProject) at Microsoft.Templates.Core.Gen.NewProjectGenController.<UnsafeGenerateProjectAsync>d__4.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult() at Microsoft.Templates.UI.Services.GenerationService.<GenerateProjectAsync>d__5.MoveNext()
To Reproduce
Create a project with Template Studio for WinUI (C#) at the root of the drive and select "Solution and project in same directory" in the VS new project dialog before triggering the Template Studio wizard. Complete the wizard and try to create the project. Observe the above exception.
Additional context
https://github.com/microsoft/TemplateStudio/blob/9af5bd47815c648f48d3253c4892a8420abf5c13/code/SharedFunctionality.Core/Gen/GenController.cs#L121 doesn't handle the case where Directory.GetParent returns null for the drive root.
Applies to the following platforms:
- [X] WinUI
- [X] WPF
- [X] UWP
About your setup
- Visual Studio Version: VS Community 2022 17.1.1
- Template Studio Wizard Version: 1.0
- Windows Build: Insider
@mrlacey is there a reason for the nested Directory.GetParent
calls here. I don't see nested calls anywhere else in the project. Might just need to remove the outer call.
@mrlacey is there a reason for the nested
Directory.GetParent
calls here. I don't see nested calls anywhere else in the project. Might just need to remove the outer call.
I'm not sure I did that deliberately and don't remember touching that code. Short answer: I don't know. Longer answer: I suspect it's trying to get the name from the solution directory and so stepping up from the project one.
This only reproes if the VS checkbox for "solution and project in same directory" is checked.
If I remove the nested GetParent call, the project creation fails later at:
https://github.com/microsoft/TemplateStudio/blob/ae61901436e79818adbae678912a01a316b96803/code/SharedFunctionality.Core/PostActions/PostActionFactory.cs#L101
It's trying to enumerate all folders at the root and throwing an exception trying to access system folders that it can't access like c:/$RecycleBin.
genInfo.GenerationPath is set below and is dependent on wts.outputToParent in template.json. If that tag is set to true, then when the template is processed, this resolves to C:/, which then triggers access issues in the above call enumerating files.
https://github.com/microsoft/TemplateStudio/blob/ae61901436e79818adbae678912a01a316b96803/code/SharedFunctionality.Core/Gen/GenInfo.cs#L44-L50
I'm not sure the proper way to fix this. @mrlacey could you take a look?
The repro is create a project at the root of the drive and select "Solution and project in same directory" in the VS new project dialog before triggering the wizard.
I've just tested with the VS2019 version of the extension, and the issue reproduces there too. In that we've gone 5 years without anyone encountering this issue can we lower the priority on this and move it to the backlog?
If that's the case, then we can move it out of the initial VS 2022 milestone yes. We can revisit later.
I had a very similar issue but a different exception. It doesnt happen when I use the tip of the repo.
System.Exception: Error executing 'Microsoft.Templates.Core.PostActions.Catalog.Merge.MergePostAction'. Related template: ts.WinUI.Proj.Default. ---> System.IO.FileNotFoundException: There is no merge target for file 'C:\dev\TemplateStudio\code\TemplateStudioForUWP\Templates\Ft\3DLauncher\App_postaction.xaml.cs'. Related Template: 'ts.WinUI.Proj.Default'. at Microsoft.Templates.Core.PostActions.Catalog.Merge.MergePostAction.HandleFileNotFound(String originalFilePath, String suffix) at Microsoft.Templates.Core.PostActions.PostAction.Execute() --- End of inner exception stack trace --- at Microsoft.Templates.Core.PostActions.PostAction.Execute() at Microsoft.Templates.Core.Gen.GenController.ExecutePostActions(GenInfo genInfo, ITemplateCreationResult generationResult) at Microsoft.Templates.Core.Gen.GenController.<GenerateItemsAsync>d__4.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Templates.Core.Gen.NewProjectGenController.<UnsafeGenerateProjectAsync>d__4.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Templates.UI.Services.GenerationService.<GenerateProjectAsync>d__5.MoveNext()