rubicon-oss / LicenseHeaderManager

Manage license headers for your source code files in Visual Studio
179 stars 41 forks source link

Fix NullReferenceException in LoadCurrentRegistryValues_3_0_3 #168

Closed gmt2001 closed 2 years ago

gmt2001 commented 2 years ago

I just installed the new 5.0.0 version of License Header Manager into VS2022. I have previously used LHM in VS2019, however, I had completely uninstalled VS2019 before installing VS2022.

It appears that GetRegistryKey() returned null in LoadCurrentRegistryValues_3_0_3() and therefore the logger call on the next line tries to dereference null.Name, and the processing logic underneath would end up doing similar.

The root cause of all this appears to be that OptionsStoreMode.RegistryStore_3_0_3 is assumed until OptionsStoreMode.JsonStore is explicitly set, and thus MigrateOptions() is triggered on the non-existent 3.0.3 registry store.

I checked my AppData\Roaming\Microsoft\VisualStudio version folders and had no artifacts from previous versions of LHM. I also checked my HKEY_CURRENT_USER\SOFTWARE\Microsoft\VisualStudio\ version registry keys and had no artifacts from previous versions of LHM.

My project does have a .licenseheader file since I was using LHM with the project back when I was working on it in VS2019.

Here is the stacktrace from the ActivityLog.xml (I decoded the HTML entities for readability).

  <entry>
    <record>2158</record>
    <time>2022/03/12 12:36:31.351</time>
    <type>Error</type>
    <source>VisualStudio</source>
    <description>SetSite failed for package [LicenseHeadersPackage]Source: 'LicenseHeaderManager' Description: Object reference not set to an instance of an object.
System.NullReferenceException: Object reference not set to an instance of an object.
at LicenseHeaderManager.Options.DialogPages.BaseOptionPage`1.LoadCurrentRegistryValues_3_0_3(BaseOptionModel`1 dialogPage) in C:\Build\1776828f99d31c99\LicenseHeaderManager.Shared\Options\DialogPages\BaseOptionPage.cs:line 182
at LicenseHeaderManager.Options.DialogPages.OptionsPage.MigrateStorageLocation_4_0_0() in C:\Build\1776828f99d31c99\LicenseHeaderManager.Shared\Options\DialogPages\OptionsPage.cs:line 47
at LicenseHeaderManager.Options.UpdateStep.ExecuteActions() in C:\Build\1776828f99d31c99\LicenseHeaderManager.Shared\Options\UpdateStep.cs:line 53
at LicenseHeaderManager.Options.DialogPages.BaseOptionPage`1.Update(UpdateStep updateStep) in C:\Build\1776828f99d31c99\LicenseHeaderManager.Shared\Options\DialogPages\BaseOptionPage.cs:line 129
at LicenseHeaderManager.Options.DialogPages.BaseOptionPage`1.MigrateOptions() in C:\Build\1776828f99d31c99\LicenseHeaderManager.Shared\Options\DialogPages\BaseOptionPage.cs:line 94
at LicenseHeaderManager.LicenseHeadersPackage.<MigrateOptionsAsync>d__66.MoveNext() in C:\Build\1776828f99d31c99\LicenseHeaderManager.Shared\LicenseHeadersPackage.cs:line 464
--- 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 LicenseHeaderManager.LicenseHeadersPackage.<InitializeAsync>d__53.MoveNext() in C:\Build\1776828f99d31c99\LicenseHeaderManager.Shared\LicenseHeadersPackage.cs:line 266
--- 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.VisualStudio.Shell.AsyncPackage.<>c__DisplayClass20_0.<<Microsoft-VisualStudio-Shell-Interop-IAsyncLoadablePackageInitialize-Initialize>b__1>d.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.VisualStudio.Threading.JoinableTask.<JoinAsync>d__76.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.VisualStudio.Services.VsTask.RethrowException(AggregateException e)
at Microsoft.VisualStudio.Services.VsTask.InternalGetResult(Boolean ignoreUIThreadCheck)</description>
    <guid>{4C570677-8476-4D33-BD0C-DA36C89287C8}</guid>
    <hr>80004003 - E_POINTER</hr>
    <errorinfo></errorinfo>
  </entry>

The proposed fix which I have submitted in this PR is to wrap everything underneath the GetRegistryKey() call in a if != null check, except for the final line that sets OptionsStoreMode.JsonStore.

gmt2001 commented 2 years ago

I have additionally discovered that while this extension is enabled, I am unable to edit files at all in VS2022 while this Exception exists. If I attempt to type anything or hit paste, nothing occurs. Disabling LHM enables me to edit my files again

MichaelKetting commented 2 years ago

@gmt2001 Thanks for the report!