Skip to content

Commit 7ec28f3

Browse files
committed
Try to avoid RCW exception at shutdown
This wraps the calls to set and get the enabled state, the visibility and the tag of a CommanBarButton in a check whether it has already been released an logs any attempt the access these methods after the release as a warning. This should lead to a clean exit. However, it only fixes the symptoms of apparently too late CanExecute checks. Identifying these is made difficult by the fact that setting the enabled state is dispatched to the UI thread, which cuts off the stack trace.
1 parent 877d0f6 commit 7ec28f3

File tree

3 files changed

+72
-13
lines changed

3 files changed

+72
-13
lines changed

Rubberduck.Core/UI/Command/MenuItems/ParentMenus/ParentMenuItemBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,8 @@ public async Task EvaluateCanExecuteAsync(RubberduckParserState state, Cancellat
154154
}
155155
catch (Exception exception)
156156
{
157-
value.IsEnabled = false;
158157
Logger.Error(exception, "Could not evaluate availability of commmand menu item {0}.", value.Tag ?? "{Unknown}");
158+
value.IsEnabled = false;
159159
}
160160
});
161161
break;

Rubberduck.VBEEditor/SafeComWrappers/SafeComWrapper.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ private void Release(bool final = false)
9292
}
9393
}
9494

95-
private bool HasBeenReleased => _rcwReferenceCount <= 0;
95+
protected bool HasBeenReleased => _rcwReferenceCount <= 0;
9696

9797
public bool IsWrappingNullReference => Target == null;
9898
object INullObjectWrapper.Target => Target;

Rubberduck.VBEditor.VBA/SafeComWrappers/Office/CommandBarButton.cs

Lines changed: 70 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@ public sealed class CommandBarButton : SafeEventedComWrapper<MSO.CommandBarButto
1515

1616
public const bool AddCommandBarControlsTemporarily = false;
1717

18-
public CommandBarButton(MSO.CommandBarButton target, bool rewrapping = false)
18+
public CommandBarButton(MSO.CommandBarButton target, bool rewrapping = false)
1919
: base(target, rewrapping)
2020
{
2121
_control = new CommandBarControl(target, true);
2222
}
23-
23+
2424
private MSO.CommandBarButton Button => Target;
25-
25+
2626
public bool IsBuiltInFace
2727
{
2828
get => !IsWrappingNullReference && Button.BuiltInFace;
@@ -35,7 +35,7 @@ public bool IsBuiltInFace
3535
}
3636
}
3737

38-
public int FaceId
38+
public int FaceId
3939
{
4040
get => IsWrappingNullReference ? 0 : Button.FaceId;
4141
set
@@ -183,13 +183,31 @@ public string Caption
183183
public string DescriptionText
184184
{
185185
get => _control.DescriptionText;
186-
set => _control.DescriptionText=value;
186+
set => _control.DescriptionText = value;
187187
}
188188

189189
public bool IsEnabled
190190
{
191-
get => _control.IsEnabled;
192-
set=> _control.IsEnabled = value;
191+
get
192+
{
193+
if (HasBeenReleased)
194+
{
195+
_logger.Warn($"Getting IsEnabled of already release CommandBarButton.");
196+
return false;
197+
}
198+
else
199+
{
200+
return _control.IsEnabled;
201+
}
202+
}
203+
set
204+
{
205+
if (!HasBeenReleased) {
206+
_control.IsEnabled = value;
207+
} else {
208+
_logger.Warn($"Setting IsEnabled on already release CommandBarButton.");
209+
}
210+
}
193211
}
194212

195213
public int Height
@@ -226,8 +244,28 @@ public int Priority
226244

227245
public string Tag
228246
{
229-
get => _control.Tag;
230-
set => _control.Tag = value;
247+
get
248+
{
249+
if (HasBeenReleased)
250+
{
251+
_logger.Warn($"Getting Tag of already release CommandBarButton.");
252+
return null;
253+
} else
254+
{
255+
return _control.Tag;
256+
}
257+
}
258+
set
259+
{
260+
if (!HasBeenReleased)
261+
{
262+
_control.Tag = value;
263+
}
264+
else
265+
{
266+
_logger.Warn($"Setting Tag on already release CommandBarButton.");
267+
}
268+
}
231269
}
232270

233271
public string TooltipText
@@ -242,8 +280,29 @@ public string TooltipText
242280

243281
public bool IsVisible
244282
{
245-
get => _control.IsVisible;
246-
set => _control.IsVisible = value;
283+
get
284+
{
285+
if (HasBeenReleased)
286+
{
287+
_logger.Warn($"Getting IsVisible of already release CommandBarButton.");
288+
return false;
289+
}
290+
else
291+
{
292+
return _control.IsVisible;
293+
}
294+
}
295+
set
296+
{
297+
if (!HasBeenReleased)
298+
{
299+
_control.IsVisible = value;
300+
}
301+
else
302+
{
303+
_logger.Warn($"Setting IsVisible on already release CommandBarButton.");
304+
}
305+
}
247306
}
248307

249308
public int Width

0 commit comments

Comments
 (0)