I'm trying to convert WinForms app into a class library - long story short the production environment I'm working in will allow our users to make changes to DLLs but not EXEs, so I'm trying to shove an entire existing app into a DLL and then just create and show an instance of the startup object/form from a second WinForms app with the goal of creating some kind of auto-update system.
I've changed the output type of the project to Class Library, added the launcher app, etc, but attempting to build the old app as a class library throws hundreds of errors, almost all of which are Reference to a non-shared member requires an object reference.
Upon inspection, these errors are appearing everywhere in the code that the startup object/form or any of its properties or methods are referenced. Since a great many things in a WinForms application naturally reference the main form... this is problematic.
Stuff like:
If DbConn = n.DbConn_.Prod Then
miParent = mainform.MiProdReq
throws the aforementioned error upon the attempt to access mainform.MiProdReq
Am I missing some simple/obvious step here?
You are referring to the default instance of the mainform
type in that code. Default instances are provided by something automagically generated when building Windows Forms Application projects. Class Library projects have no such thing as default instances, so any code that tries to use them will appear to be trying to access instance members as though they were Shared
.
You need to put an instance somewhere and change your code to refer to that instead. If you use a global variable, which is not ideal itself but the simplest option for where you're at, then you can just do a Find & Replace In Files to find the references you need to change.
Note that default instances are something that most experienced developers would suggest avoiding anyway. They don't exist in C# and I've never heard complaints about that, so it's hardly onerous. They were added to VB as a convenience for beginners and migrating VB6 developers who weren't used to proper OOP.
EDIT:
I haven't tested it but you may be able to use Application.OpenForms(0)
to get a reference to the startup form anywhere in your library. You could, perhaps, add a module like this:
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
and then your code may even just work as it is.