确定正在运行的应用程序类型 (.NET)

3

如何确定正在运行的应用程序是Windows Forms还是控制台应用程序?

4个回答

5
您无法可靠地做到这一点。例如,从Windows Forms应用程序项目模板开始启动一个新项目。单击“项目”+“属性”,将输出类型更改为“控制台应用程序”。按F5查看其外观。虽然每个合理的测试都会说它是一个控制台模式应用程序,但它实际上是一个WF应用程序。
反之亦然,仅有System.Windows.Forms.dll的存在并不意味着它是一个WF应用程序。例如,控制台应用程序可能使用它来显示MessageBox。
此外,它也可能两者都不是。您的代码可能由服务调用。
推迟这个问题,应用程序的作者从未遇到过告诉您代码应该做什么的问题。向您的类添加一个属性,以允许她这样做。

4

p/invoke:

[DllImport("shell32.dll")]
private static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags);

结构体:

[StructLayout(LayoutKind.Sequential)]
private struct SHFILEINFO
{
    public IntPtr hIcon;
    public IntPtr iIcon;
    public uint dwAttributes;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=260)]
    public string szDisplayName;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=80)]
    public string szTypeName;
}

方法:
private static bool IsWindowsApplication(string fileName)
{
    SHFILEINFO psfi = new SHFILEINFO();
    switch (((int) SHGetFileInfo(fileName, 0, ref psfi, (uint) Marshal.SizeOf(psfi), 0x2000)))
    {
        case 0:
            return false;

        case 0x4550:
            return false;

        case 0x5a4d:
            return false;
    }
    return true;
}

如果以上方法返回false,那么这是一个控制台应用程序。
-Oisin

如果同时打开了一个表单和控制台,那么函数会返回什么?它是否在语义上正确? - Aviad P.
这可能对于本地可执行文件是正确的,但对于.NET可执行文件则不是。 - Aviad P.
.NET可执行文件和本地Win32应用程序一样采用PE格式,因此对于.NET可执行文件也是如此。您可以从VS命令提示符中检查它:dumpbin/HEADERS myapp.exe将显示PE标题。查找显示子系统的行。值为2表示Windows GUI,值为3表示Windows CUI(控制台应用程序)(请参见http://msdn.microsoft.com/en-us/magazine/ms809762.aspx)。 - Dirk Vollmar
2
好的,但是对于一个可能同时打开控制台、窗体和WPF主机的.NET应用程序来说,那个标志有点微不足道...这就是我想说的。也许它可以回答原帖作者的问题,也许不能,这取决于他自己的判断。在我看来,所有事情都是平等的,那个标志对于一个.NET应用程序来说是微不足道的。 - Aviad P.
@Aviad:即使你可以伪造不同的行为,但.NET应用程序也只能是控制台或窗口应用程序之一。由于这个子系统类型决定内核如何加载应用程序,因此.NET应用程序无法改变低级别的操作系统行为。我建议你阅读Raymond Chen的这篇文章:http://blogs.msdn.com/oldnewthing/archive/2009/01/01/9259142.aspx。 - Dirk Vollmar
显示剩余4条评论

0

如果不需要以编程方式完成,您可以尝试使用类似ProcessExplorer的程序,并查看System.Winforms.dll是否已加载。我认为这并不是绝对可靠的方法,但这可能是一个好的开始。


0

一种选择可能是检查System.Windows.Forms.Application.OpenForms是否包含任何元素。

另一种选择可能是检查Console.TitleConsole.WindowTop是否会抛出异常(如果没有控制台窗口打开,则会抛出异常)。

编辑

但请注意,一个应用程序可能同时拥有控制台窗口和表单...那么它是什么类型的应用程序呢?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接