【问题标题】:Prevent Windows Forms application from closing when the Console is closed [duplicate]关闭控制台时防止 Windows 窗体应用程序关闭 [重复]
【发布时间】:2014-02-25 13:48:18
【问题描述】:

我有一个标准的 Windows 窗体应用程序,我需要一个解决方案来在 Windows 窗体应用程序设置中打开控制台。我想出了这个解决方案:

Public Class Win32

    <DllImport("kernel32.dll")>
    Public Shared Function AllocConsole() As Boolean
    End Function

    <DllImport("kernel32.dll")>
    Public Shared Function FreeConsole() As Boolean
    End Function

' ...

Win32.AllocConsole()
Console.WriteLine("Test")

使用上面的 P/Invoke 函数,我可以打开一个控制台,而我的应用程序不是“控制台应用程序”。

我现在遇到的问题是,当我关闭控制台窗口时,它会退出我的程序并关闭所有窗体和窗口。有没有办法阻止用户关闭控制台窗口,或者阻止程序在控制台窗口关闭时退出? (我可以使用Win32.FreeConsole() 以编程方式关闭控制台。)

【问题讨论】:

  • 我试图澄清你的问题。如果我记错了,您可以打开revision history 并回滚到以前的版本。
  • 我已经尝试过这个答案,但它对我不起作用!
  • 问题和可能的答案在该问题/答案中得到了非常深入的介绍。查看其他答案以获得可能的解决方案。
  • 在这些答案中没有什么可以“尝试”的。他们都说同样的话:你不能阻止这一点。如果您负担不起,请不要创建控制台。
  • @HansPassant 我想说错了,你可以停下来,我做到了,而且效果很好!

标签: vb.net console


【解决方案1】:

我想你可能会觉得这很有趣,试一试;对我有用!另一个注意事项:用户无法点击关闭按钮,因为它已被禁用,唯一退出的方法是您如何设置它...

 Imports System.Collections.Generic
 Imports System.Windows.Forms
 Imports System.Runtime.InteropServices
 Imports System.Diagnostics
 Imports Microsoft.Win32

 Public Class Form1

 <DllImport("kernel32.dll", SetLastError:=True)> _
Private Shared Function AllocConsole() As Boolean
End Function

<DllImport("kernel32.dll", SetLastError:=True)> _
Private Shared Function FreeConsole() As Boolean
End Function

Private Declare Function DeleteMenu Lib "user32" (ByVal hMenu As Integer, _
 ByVal uPosition As Integer, ByVal uFlags As Integer) As Boolean
Private Declare Function GetForegroundWindow Lib "user32" () As Integer
Private Declare Function GetSystemMenu Lib "user32" (ByVal hWnd As Integer, _
   ByVal bRevert As Boolean) As Integer
Private Declare Function GetWindow Lib "user32" (ByVal hWnd As Integer, _
   ByVal uCmd As Integer) As Integer
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
   (ByVal hWnd As Integer, ByVal lpString As String, ByVal nMaxCount As Integer) As Integer


Private Sub btnStartConsole_Click(sender As Object, e As EventArgs) Handles btnStartConsole.Click
    StartConsole()
End Sub

Private Sub StartConsole()
    AllocConsole()
    Console.Title = "TEST"
    ' Obtain a handle to the console application window by passing the title of your application.
    Dim hWnd As Integer = ObtainWindowHandle("TEST") 'Can change this, but must match the name you give it!'

    ' Obtain a handle to the console application system menu.
    Dim hMenu As Integer = GetSystemMenu(hWnd, False)

    ' Delete the Close menu item from the console application system menu.
    ' This will automatically disable the Close button on the console application title bar.
    DeleteMenu(hMenu, 6, 1024)

    Console.WriteLine("We have a console! Enter something!")
    ' Read value.
    Dim s As String = Console.ReadLine()
    ' Write the value.
    Console.WriteLine("You typed " + s)
    Console.WriteLine("Press any key! ...")
    Console.ReadLine()

    FreeConsole()
End Sub

Private Function ObtainWindowHandle(ByVal lpstrCaption As String) As Integer

    ' To store the handle to a window.
    Dim hWnd As Integer
    ' Maximum number of characters in the GetWindowText method.
    Dim nMaxCount As Integer
    ' Actual number of characters copied in the GetWindowText method.
    Dim nCopiedLength As Integer
    ' To store the text of the title bar of the window.
    Dim lpString As String

    nMaxCount = 255
    ' Obtain a handle to the first window.
    hWnd = GetForegroundWindow

    ' Loop through the various windows until you encounter the console application window, _
    ' or there are no more windows.
    While hWnd <> 0

        ' Fill lpString with spaces.
        lpString = Space(nMaxCount)
        ' Get the text of the title bar of the window in lpString.
        nCopiedLength = GetWindowText(hWnd, lpString, nMaxCount)

        ' Verify that lpString is neither empty, nor NULL.
        If Len(Trim(lpString)) <> 0 And Asc(Trim(lpString)) <> 0 Then
            ' Verify that the title of the retrieved window is the same as the title of the console application window.
            If CType(InStr(Microsoft.VisualBasic.Left(lpString, nCopiedLength), lpstrCaption), Boolean) Then
                ' Return hWnd to the Main method.
                Return hWnd
            End If
        End If

        ' Get the next window.
        hWnd = GetWindow(hWnd, 2)

    End While

    ' If no corresponding windows are found, return 0.
    Return 0

End Function
End Class

【讨论】:

  • 这也是经过尝试和测试的!让我知道你的效果如何!
  • 他主要担心的是如果有人通过单击关闭按钮关闭控制台,它杀死应用程序。
  • @MarkHall 好了,现在没问题了,我之前做过这个,必须通过并找到它。它禁用菜单关闭,但仍然可以使用最大化和最小化功能......试试看......
  • @Mr CoDeXeR 是的,您的代码是问题的解决方案,但从技术上讲,它并不是问题的真正答案,因为您停止显示关闭按钮,但没有说明如何在关闭按钮被按下,但您的回答不允许按下关闭按钮
  • 好的,让我提醒您您的问题....“我现在遇到的问题是,当我关闭控制台窗口时,它会退出我的程序并关闭所有窗体和窗口。有吗?一种防止用户关闭控制台窗口或在控制台窗口关闭时阻止程序退出的方法?”这就是您的要求,我为您提供了解决方案。如果你不停止关闭按钮,那么他们可以退出!
猜你喜欢
  • 2013-11-24
  • 2010-12-30
  • 1970-01-01
  • 2015-01-28
  • 1970-01-01
  • 1970-01-01
  • 2013-08-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多