Optionally launch form in VB.Net console application - vb.net

So I've set my application to a console type application and pointed it to a module containing just Sub Main, i.e.
Module mdlConsole
Sub Main(ByVal cmdArgs() As String)
If cmdArgs.Length = 0 Then
Dim frm As New frmMain
frm.Show()
End If
End Sub
End Module
Ideally if no arguments are supplied then the program would simply launch the primary form. The goal is to make this program (optionally) script-able from the command line. If arguments are supplied then the application form is not loaded and processes its features based off the command line arguments supplied.
As it is now, the program runs, briefly launches the form (frmMain) and then closes. What am I doing wrong or missing?
If you're not keen on giving me the answer, I'd be happy to be pointed in the right direction also. I don't expect anyone to just supply answers. I need to learn also.
Thanks!

For Winforms, you need to 'run' the App object, passing a form to use:
Sub Main(ByVal cmdArgs() As String)
If cmdArgs.Length = 0 Then
Dim frm As New frmMain
Application.Run(frm)
Else
' cmd line version
End If
End Sub

I see in your comment that you'd like to remove the console window that appears when running the form version of the program with the solution currently proposed. I cannot comment due to lack of reputation, so I will make this a full-fledged answer.
Consider approaching this from an inverse perspective: if you write the program as a forms application, opening it by default will bring up the form. But in the Form1_Load event, check the command line arguments; if they are greater than 0, simply run your (abbreviated) code logic here. At the end of the code, simply run Application.Exit(), like so:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
If My.Application.CommandLineArgs.Count > 0 Then
' Execute (abbreviated) code logic
' When finished, exit the program
Application.Exit()
End If
End Sub
This can also make your code cleaner and more practical if you're relying on a user-interface, because you can still access the values of form elements that the user would otherwise be modifying - but without the form showing on the screen (unless you prompt it to with a MsgBox or such).
This also works very nicely for Scheduled Tasks, as the user can run them manually with a user-interface, while the program executes without being visible via a scheduled task.

Kind of a follow-on to Chad's solution above I used the steps defined in How to have an invisible start up form? to avoid showing my form.
In short, create an Overrides subroutine that gets launched before Form1_Load:
This worked for me:
Protected Overrides Sub SetVisibleCore(ByVal value As Boolean)
If Not Me.IsHandleCreated Then
Me.CreateHandle()
value = False
MyBase.SetVisibleCore(value)
Else
Exit Sub
End If
If My.Application.CommandLineArgs.Count > 0 Then
MsgBox("Argument Sensed!")
' Execute (abbreviated) code logic
' When finished, exit the program
Me.Close()
Application.Exit()
Else
MyBase.SetVisibleCore(True)
End If
End Sub

Related

How to cause a running VB program to start from scratch again

How can I restart a running VB program from within?
I have written a VB program that solves SUDOKU puzzles.
When it completes the solution, it asks if the user wants to run again with another puzzle.
I can not:
-determine the first line of code that the program executes. The main() is empty. All code is on the tab for Form1. I have tried breakpoints, but still can't determine the starting point.
-figure out how to cause the program to jump back to the starting point in the code.
Can you help me?
I've tried placing breakpoints in the code at places that might be close to the starting point, but so far that hasn't worked. When the program starts, Form1 is displayed, and it is waiting to see if a check box gets activated, or if text is entered anywhere in many text boxes.
You should do what Alejandro said in his comment: "reset the data state to the starting point".
But if you must, you can restart a WinForms application with Shell(Application.ExecutablePath)
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If MessageBox.Show("Start from scratch?", "Confirm Restart", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = DialogResult.Yes Then restart()
End Sub
Private Sub restart()
Shell(Application.ExecutablePath, AppWinStyle.NormalFocus, False)
End
End Sub

How to create a custom event in VB.NET that checks for when the console finishes reading a line?

I am working on a VB.NET project for class, and I need to create an event that runs a sub whenever the console is finished reading a line. How do you code custom events in VB.NET? Or, is there a better way of doing what I'm trying to do without creating an event?
I don't think an event is required in this case.
As the next line won't execute until the current line is finished, your program will sit on Console.ReadLine() until the user has entered whatever needs to be entered. The next line in your code would then be mysub(), where mysub is the sub you need to run.
Sub Main()
Console.ReadLine()
mysub()
End Sub
Sub mysub()
Console.WriteLine("The user has pressed enter.")
Console.ReadLine() 'keeps console open until the user is ready to exit
End Sub

Execute a subroutine before exiting the application

I am designing a client-server application, where the client requests various data and the server retrieves it from the local SQL server.
I need to execute a function when the application exits in order to tell associated services that the server is offline, but I am unable to figure out exactly how to do this.
This related question seems to have the answer:
handle the AppDomain.ProcessExit event, which is raised when the application's parent process exits.
however when using the below code the onExit subroutine does not get executed on application closure, probably because I am using the wrong approach to this problem or that Environment.Exit isn't executed when the application exits:
Dim myConn As SqlConnection
Dim cmd As New SqlCommand
Sub Main()
AddHandler AppDomain.CurrentDomain.ProcessExit, AddressOf onExit
End Sub
Public Sub onExit(sender As Object, e As EventArgs)
'Unrelated code removed here.
End Sub
To clarify, I need it to execute onExit when the user closes the application; I am not looking to close the application via a console command.
I've also thought that perhaps I could add a Handle to onExit but I have no idea what to use here.
Is it possible to reliably execute a subroutine or function when the user attempts to close the application via the standard Windows Explorer user interface?
This is a console application, I know this can be very easily done in Windows Forms and thought it would be easy in console. Obviously not.
You need to import the SetConsoleCtrlHandler like in this sample:
Module Module1
Public Declare Function SetConsoleCtrlHandler Lib "kernel32" (Handler As ConsoleCtrlDelegate, Add As Boolean) As Boolean
Public Delegate Sub ConsoleCtrlDelegate()
Sub Main()
SetConsoleCtrlHandler(New ConsoleCtrlDelegate(AddressOf OnExit), True)
Console.WriteLine("Please try to close down...")
Console.ReadLine()
End Sub
Sub OnExit()
MsgBox("Help I'm being closed!")
End Sub
End Module

Catch a value from form1 to form2 in vb [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
In VB, I create 2 forms in 1 project. In form1, I put 3 buttons with different value. In form2, I only put 1 textbox with no value.
My question is, how if I press one of the button in form1, the form2 is automatically opened and the value from the button that I press automatically added to the form2 textbox?
Add following code into your button handler. You can double click button and add the code into event handler which is automatically created:
'Here we are creating actual object and passing string into it constructor method
Dim instanceOfForm2 = new Form2("String value from Form1!")
instanceOfForm2.Show() ' Showing form
In Form2 we need to tweak our constructor to accept one parameter:
Public Sub New(someValue as String)
InitializeComponents() 'This is always first row in form constructor
TextBox1.Text = someValue 'And put that text into textbox...
End Sub
In VB6 you can do all the stuff that lardymonkey has in place, but you don't have to. The most concise way to do what you want is this. First, make your three command buttons in Form1 into a control array. To do this, give them all the same name (I'll use "cmdMyButtons" in my example), and set their index properties to 0, 1, and 2. Then do this in Form1's code window:
Option Explicit
Dim ButtonText(2) As String
Public Sub Form_Load()
ButtonText(0) = "First Button Text"
ButtonText(1) = "Second Button Text"
ButtonText(2) = "Third Button Text"
End Sub
Public Sub cmdMyButtons_Click(Index As Integer)
With Form2
.txtMyTextBox.Text = ButtonText(Index)
.Show vbModal
End With
End Sub
Now, I like lardymonkey's idea of showing modally, so I put it in here as well. However, several things in his code sample aren't intrinsically necessary to do what you want, and create overhead, so I pulled them out:
You don't need to make a property; you can just set the text
directly as I have here.
You don't need to create a form variable; you can just reference the form directly as I have here.
You don't have to load the form explicitly; the form gets
automatically loaded as soon as you set the variable (by the way,
the Show method also automatically loads the form, too--you only use
Load when you want to have the form loaded into memory before you do
anything to it).
If you close the modal form it will be
automatically unloaded. However, unloading a form doesn't set any
object variables referencing it to nothing. Therefore, frmDetail
will not be Nothing when you check it, you will unload a form that
isn't loaded. While this doesn't throw an error (the statement is ignored), I wouldn't do it anyway. So, you don't
need any of the "make sure the form is destroyed" code.
And now, for a short lecture on the whole business of always explicitly destroying object variables:
There is a longstanding argument about whether you need to explicitly set all your local object variables to Nothing before exiting a subroutine in VB6. I don't agree with this at all; VB takes care of this automatically when the variables go out of scope. As far as I can see, the reason that people believe that they have to do this is that the scope finalizer doesn't collect garbage in any particular order, and sometimes two interacting COM objects need to be destroyed in a particular order due to poor coupling architecture. In such a case, you do indeed need to clear the objects in the correct order to work around intermittent bugs, so the myth developed that VB's garbage collection is buggy and needs to be circumvented by always manually destroying object variables.
Frankly, the idea that a programmer is going to always do this and never forget is naive. So I persist in disagreeing with it; the developers of VB6 put a lot more thought and effort into developing the scope finalizer than any programmer is going to put into circumventing it.
Without knowing the specific version of the software you are using we cant answer, we can answer it if you provide the correct version
In .net it's a simple as creating the form then passing the value over.
Friend objForm2 as New Form2
Private Sub button1_Click(ByVal sender As System.Object, ByVal e as System.EventArgs) Handles button1.Click
objForm2 = new Form2()
TextBox1.Text = value
End Sub
This would be a way of doing it in VB6. I've left the error handling up to you.
I've made the assumption that the name of the text box is txtOutput on form2.
In Form2 add the following:
Option Explicit
Public Property Let OutputText(ByVal strOut As String)
txtOutput.Text = strOut
End Property
In Form1 add the following:
Option Explicit
Private Sub Command1_Click()
DisplayForm "1"
End Sub
Private Sub Command2_Click()
DisplayForm "2"
End Sub
Private Sub Command3_Click()
DisplayForm "3"
End Sub
Private Sub DisplayForm(ByVal strValue As String)
'Declare the variables
Dim frmDetail As Form2
'Create the form
Set frmDetail = New Form2
'Load the form and display it modal
Load frmDetail
frmDetail.OutputText = strValue
frmDetail.Show vbModal, Me
'Make sure the form is destoryed
If Not frmDetail Is Nothing Then
Unload frmDetail
Set frmDetail = Nothing
End If
End Sub
Make sure you comment the code and if you need some error handling then add it. If you need help with the VB6 functions you can find it here MSDN VB6 Reference

VB.Net App Stuck in Loop

I would just like the program to end itself.
Application.Exit just keeps rolling me back in a loop.
EDITED to Include Code::
Module Module 1
Sub Main()
Sub1()
Sub2()
End Sub
Sub1()
EndSub
Sub2()
End Sub
End Module
EDIT: It seems to be looping back here to Sub ChooseDomain2.. I am including Sub 1 as well.
Sub ChooseDomain1()
Dim DomainName As Object
'Get List of all users on Domain using WinNT
DomainName = InputBox(messageOK, Title, defaultValue)
de.Path = "WinNT://****".Replace("****", DomainName)
If DomainName Is "" Then ChooseDomain2() Else StoreUserData1()
End Sub
Sub ChooseDomain2()
MsgBox("Welcome to the Domain Searcher. Click OK to Auto Search for Domain")
Dim MsgBoxResult As Object = ActiveDirectory.Domain.GetCurrentDomain.Name
MsgBoxResult = InputBox(messageCan, Title, MsgBoxResult)
de.Path = "WinNT://*****".Replace("*****", MsgBoxResult)
StoreUserData1()
End Sub
When it hits end Module it Just starts back from Square one.
Modules don’t execute at all – so it never “hits end module” and never starts “from square one”. Modules merely group methods that can be executed, and Main is a special method that serves as the start of your application.
That said, your code is guaranteed (!) not to execute repeatedly. Also, there is no Application.Exit anywhere in your code so it’s hard to see what you are actually executing. Not the code you showed, anyway.
Note that VB potentially executes code that you didn’t write (code can be auto-generated by the compiler, in particular the application framework) but this doesn’t seem to be happening in your case, and shouldn’t loop in any case. But again, this is impossible to say from the information you have given.
Application.Exit is not required as the console app will quit after it finishes executing the last line in Sub Main. As previously mentioned it is likely you have Sub1 calling Sub2 (or something similar), so set a breakpoint on the start of each sub to find which one is continually being called. Then you can do a search in your code to find where this sub is being called from.