将 WinForms 应用程序转换为 Class 库时,对启动对象的引用失败

References to startup object fail when converting WinForms app to Class Library

我正在尝试将 WinForms 应用程序转换为 class 库 - 长话短说,我工作的生产环境将允许我们的用户更改 DLL 而不是 EXE,所以我试图将整个现有应用程序推入 DLL,然后仅创建并显示来自第二个 WinForms 应用程序的启动实例 object/form,目的是创建某种自动更新系统。

我已将项目的输出类型更改为 Class 库,添加了启动器应用程序等,但尝试将旧应用程序构建为 class 库会引发数百个错误,几乎都是Reference to a non-shared member requires an object reference.

经检查,这些错误出现在引用启动 object/form 或其任何属性或方法的代码中。由于 WinForms 应用程序中的很多东西自然会引用主窗体...这是有问题的。

诸如此类的内容:

If DbConn = n.DbConn_.Prod Then
    miParent = mainform.MiProdReq

在尝试访问 mainform.MiProdReq

时抛出上述错误

我是不是漏掉了一些 simple/obvious 步骤?

您指的是该代码中 mainform 类型的默认实例。默认实例由构建 Windows 表单应用程序项目时自动生成的内容提供。 Class 库项目没有默认实例这样的东西,因此任何尝试使用它们的代码似乎都在尝试访问实例成员,就好像它们是 Shared.

您需要在某处放置一个实例并更改您的代码以引用它。如果您使用全局变量,它本身并不理想,但却是您所处位置的最简单选择,那么您只需执行“在文件中查找和替换”即可找到您需要更改的引用。

请注意,大多数有经验的开发人员无论如何都会建议避免使用默认实例。它们在 C# 中不存在,而且我从未听到过对此的抱怨,所以它并不繁重。它们被添加到 VB 是为了方便初学者和迁移 VB6 不习惯正确 OOP 的开发人员。

编辑:

我还没有测试过,但您可以使用 Application.OpenForms(0) 在您的库中的任何位置获取对启动表单的引用。您也许可以像这样添加一个模块:

Module Module1

    Private _mainform As Form1

    Public ReadOnly Property mainform As mainform
        Get
            If _mainform Is Nothing Then
                _mainform = DirectCast(Application.OpenForms(0), mainform)
            End If

            Return _mainform
        End Get
    End Property

End Module

然后您的代码甚至可以按原样工作。