Form.Show()不适用于1台特定计算机

时间:2018-07-12 13:36:49

标签: c# windows-10 excel-2016 office-2016

我正在用C#开发一个Excel插件。 该插件包含带有一些按钮的面板,用于打开悬停表单。

我已收到通知,该功能不适用于我公司的一台计算机。它使用Excel Office 2016为最新版本。
这是发生了什么:

Form issue

灰色框应该是Windows窗体,但是由于某些原因它无法加载。用户单击一个按钮将其打开,它只是保持灰色,没有控件,没有事件,没有任何响应。

现在,这是打开表单的代码:

private void _Form_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{   
    // ActiveForm() returns basically a UserForm with some methods to fit my specific needs
    ActiveForm().ShowMyForm(_columnButton); // --> ClickEvent
}

public void ShowMyForm(object parent = null)
{
    ActiveForm().StartPosition = FormStartPosition.CenterScreen;

    if (parent != null)
        ComputeLocation(parent);

    IntPtr handle = new IntPtr(Excel.Hwnd);
    ActiveForm().Show(new WindowWrapper(handle)); // --> Shows a grey box
}

public class WindowWrapper : IWin32Window
{
    private IntPtr _hwnd;
    public WindowWrapper(IntPtr handle)
    {
        _hwnd = handle;
    }

    public IntPtr Handle
    {
        get { return _hwnd; }
    }
}

我提供此代码只是为了以防万一,但我不确定它是否有问题。

完全相同的代码在任何其他机器上都可以正常工作,并且我的插件的任何版本都出现了问题。
我已经用几个(稳定的)版本检查过它,即使是beta版本,问题仍然存在。

但是,它在外接程序重新安装到计算机上的先前版本之后出现。它不应与任何外部事物混淆,但我认为指出这一点很重要。
我正在使用Wix 3.11生成的msi安装程序进行安装。

我没有修改代码,但是这是我尝试过的。我希望这不是荒谬的,我对此没有经验:
-卸载并重新安装插件,
-修复Office 2016,然后在不更改任何内容的情况下进行卸载/重新安装,
-将.NET版本从4.6更新到4.7.2(该插件需要4.6)
-更新了计算机上的图形卡驱动程序

此外,我尝试检查日志以查看是否生成了任何类型的错误:
-我的插件在日志中没有显示错误
-我已经建立了Visual Studio项目,并在调试模式下启动了插件,并且具有断点和所有->没有任何类型的错误
-我检查了Windows日志事件,没有发现任何相关信息。由于我没有阅读经验,所以我可能会错过一些东西。

我终于找到了一个“做某事”的链接:
How to revert to an earlier version of office 2016

我将Office版本恢复为16.0.9330.2118,并且表单按预期开始工作了大约30分钟。然后,我被告知问题再次出现,即使计算机上没有任何更新。它只是“再次出错”。我将Office更新到最新版本,并且直到第二天早上才重新开始工作。

如您所见,不会产生任何错误,但是将Office版本替换为其他版本“会有所作为”。看起来与某些Office库存在某种冲突,但是我不知道该怎么办或如何处理。
即使我已经注意到一些看起来像我的问题的主题,但它们都与代码和表单管理有关。我真的相信,这与代码无关,即使我不能肯定地证明这一点。

有人可以帮助我吗?甚至对如何处理此问题的一些想法都将不胜感激,因为我真的不满意。

编辑

所以我有点想知道发生了什么,但不是全部。
我做了@HansPassant告诉我的事情,并逐步在同事的计算机上运行了VS调试器,并使其一次又一次地运行。 看来是导致此问题的原因是ComputeLocation方法(请参阅原始内容)。
基本上ComputeLocation是这样工作的(我简化了一点):

private void ComputeLocation(object parent)
{
    Control parentControl = (Control) parent;
    Point location = parentControl .PointToScreen(new Point(0,0));

    //Process location's coordinates here

    location = parentControl.PointToClient(location);

    ActiveForm().StartPosition = FormStartPosition.Manual;
    ActiveForm().Location = location;
}

我终于注意到使用PointToClient时会发生此问题。表单会更改其位置,但内容不会更改。
删除对PointToClient的调用后,我得到了预期的行为。

我想指出的是,这段代码实际上是错误的(与我在原始部分所说的相反),因为ActiveForm()是topMost Form,并且没有父级。在这种情况下使用PointToClient是一个错误,因为它的位置始终以屏幕坐标表示,尽管这不是导致我在这里出现问题的原因:在这种情况下,PointToClient总是返回与屏幕坐标几乎相同的位置。

我最终永久删除了对PointToClient的呼叫,从而解决了问题。表单的内容再次跟随其容器。

我仍然不知道PointToClient为何会导致这种行为。
几天后,另一位同事遇到了完全相同的问题,而他的计算机上没有任何更新。该插件从在Excel工作簿上正常运行到在下一个工作簿上显示灰色框。

由于我能够解决此问题,所以我不知道是否应该将此问题标记为已解决,但是不完全了解是什么原因造成的。

1 个答案:

答案 0 :(得分:0)

我相信我已经找到导致此问题的原因。 该问题“传播”到我公司的另外2台计算机上,即使我不知道真正的原因,我也可以通过更正进行修复。
随着时间的推移,又出现了一个问题:插件窗体中不再显示ToolStrips控件。

最终,我的一位同事不得不更新他的Windows版本,这彻底消除了所有问题。
我检查了一下,所有3台计算机都在Windows 10 1709版上运行。
我找到了有关此版本问题的链接,但我不完全确定这正是导致错误行为的原因:
https://support.microsoft.com/en-us/help/4340917/windows-10-update-kb4340917

其他计算机已快速更新为Windows 10 April 2018升级,并且该加载项的每个版本上的所有功能都再次正常运行。