判断主程序是Windows应用程序还是控制台应用程序

来源:水如烟 - CSDNBlog
  我们知道,桌面应用程序一般有两种类型,一是Windows应用程序,二是控制台应用程序。
  如何判断调用自己所在Dll的主程序是Windows还是控制台应用程序呢?

  解决这个问题,基点是ApplicationBase,ConsoleApplicationBase和WindowsFormsApplicationBase,
攻击的地方,当然是Application了。

我也曾想到能否从Thread.CurrentContext,Thread.CurrentThread,AppDomain.CurrentDomain来切入,不过没有去看。现在想“当然”的Application,有点武断,况且,Application源于System.Windows.Forms空间,用它来判断ConsoleApplicationBase,总觉得有些刺。

据自己的测试,主程序的有三种体现方式,如下:

Public Enum ApplicationType
 WindowsForms '这是Form启动的Windows应用程序
 ConsoleForms '这是Main启动且含代码Application.Run(New Form)的控制台应用程序
 Console '这是Main启动无窗体的控制台应用程序,就算是Form.ShowDialog也列于此项
End Enum
MyApplicationBase.vb

Imports Microsoft.VisualBasic.ApplicationServices

Namespace LzmTW.uSystem.uForms

 Public Class MyApplicationBase

 'System.Windows.Forms.Application+ThreadContext
 Private Shared gThreadContextType As uReflection.TypeHelper

 'Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase+WinFormsAppContext
 Private Shared gWinFormsAppContextType As uReflection.TypeHelper
 Private gAppContext As Object = Nothing 'ApplicationContext or WinFormsAppContext
 Private gWindowsFormsApplicationBase As WindowsFormsApplicationBase = Nothing
 Private gCurrentType As ApplicationType

 Shared Sub New()
 gThreadContextType = New uReflection.TypeHelper(GetType(Application), "ThreadContext", True)
 gWinFormsAppContextType = New uReflection.TypeHelper(GetType(WindowsFormsApplicationBase), "WinFormsAppContext", True)
 End Sub
 Sub New()
 GetApplicationContext()

 GetWindowsFormsApplicationBase()

 gCurrentType = GetApplcationType()
 End Sub

 Private Sub GetApplicationContext()
 Dim mCurrentThreadContext As Object
 mCurrentThreadContext = gThreadContextType.MethodInvoke("FromCurrent")
 gThreadContextType.SetCurrentObj(mCurrentThreadContext)
 gAppContext = gThreadContextType.GetMemberValue("ApplicationContext")
 End Sub
 Private Sub GetWindowsFormsApplicationBase()
 If Not gWinFormsAppContextType.CurrentType.IsInstanceOfType(gAppContext) Then Return
 gWinFormsAppContextType.SetCurrentObj(gAppContext)
 gWindowsFormsApplicationBase = CType(gWinFormsAppContextType.GetMemberValue("m_App"), WindowsFormsApplicationBase)
 End Sub

 Private Function GetApplcationType() As ApplicationType
 If gAppContext Is Nothing Then
 Return ApplicationType.Console
 End If
 If gWindowsFormsApplicationBase Is Nothing Then
  Return ApplicationType.ConsoleForms
 End If

 Return ApplicationType.WindowsForms
  End Function

 Public ReadOnly Property ApplicationContext() As ApplicationContext
 Get
 Return CType(gAppContext, ApplicationContext)
 End Get
 End Property

 Public ReadOnly Property WindowsFormsApplicationBase() As WindowsFormsApplicationBase
 Get
 Return gWindowsFormsApplicationBase
 End Get
  End Property
 Public ReadOnly Property CurrentType() As ApplicationType
 Get
 Return gCurrentType
 End Get
 End Property
 Public Enum ApplicationType
WindowsForms
ConsoleForms
Console
End Enum

End Class
End Namespace
控制台的一个测试:

Public Class Program
Shared Sub Main()
Console.WriteLine((New LzmTW.uSystem.uForms.MyApplicationBase).CurrentType.ToString)
Application.Run(New Form1)
Console.WriteLine((New LzmTW.uSystem.uForms.MyApplicationBase).CurrentType.ToString)
Console.Read()
End Sub
End Class
而Form1中有一个按钮也来测试

Private Sub ButtonTest_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonTest.Click
Console.WriteLine((New LzmTW.uSystem.uForms.MyApplicationBase).CurrentType.ToString)
End Sub
那么,显示的结果,先是Console,后是ConsoleForms,最后是Console。

MyApplicationBase有没有用?

这当然看自己的需求。
举例来说,如果有一个类需要输出信息,如是控制台应用程序,就输出到控制台,如是WinForm程序,就以Form的形式显示,
这个时候,就需要MyApplicationBase来判定的了。

另,如果是WinForm应用程序,MyApplicationBase.WindowsFormsApplicationBase其实就是My.Application,
这里有大量的信息供自己使用。

个人感觉,这个类可能还是蛮有用的。 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值