从隐藏的控制台应用程序显示窗体 [英] Show Form from hidden console application

查看:323
本文介绍了从隐藏的控制台应用程序显示窗体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有运行控制台应用程序中的主要应用。控制台应用程序通常始于隐藏( ProcessWindowStyle.Hidden ),但是出于测试目的,我可以用所示的窗口中运行它。



在控制台应用程序,我可以有加载并执行插件。其中一个插件试图打开一个WinForm对话框。如果控制台应用程序是可见它工作正常,但它不工作了,如果控制台是隐藏的。



我曾尝试:

  Application.EnableVisualStyles(); 
Application.SetCompatibleTextRenderingDefault(假);
Application.Run(新表());

和我也试过在一个新的线程是一样的。

 线程t =新System.Threading.Thread(开始); 
t.Start();
t.Join();



其中,开始()包含了以前的事情。此外,我试过的ShowDialog()

  Application.EnableVisualStyles(); 
Application.SetCompatibleTextRenderingDefault(假);
变种F =新表();
f.ShowDialog();



的方法都没有表现出窗口。



在WinDbg中,本机调用堆栈总是包含 NtUserWaitMessage()

  0:000> ķ
ChildEBP RetAddr
0038dd58 7b0d8e08 USER32!NtUserWaitMessage +为0x15

和托管调用栈总是包含 WaitMessage() FPushMessageLoop() RunMessageLoop()

  0:000> !clrstack 
OS线程ID:0x47c4(0)
ESP EIP
0045e560 76bff5be [InlinedCallFrame:0045e560] System.Windows.Forms.UnsafeNativeMethods.WaitMessage()
0045e55c 7b0d8e08系统。 Windows.Forms.Application + ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(的Int32,的Int32,Int32)将
0045e5f8 7b0d88f7 System.Windows.Forms.Application + ThreadContext.RunMessageLoopInner(的Int32,System.Windows。 Forms.ApplicationContext)
0045e64c 7b0d8741 System.Windows.Forms.Application + ThreadContext.RunMessageLoop(的Int32,System.Windows.Forms.ApplicationContext)
0045e67c 7b5ee597 System.Windows.Forms.Application.RunDialog(系统。 Windows.Forms.Form)
0045e690 7b622d98 System.Windows.Forms.Form.ShowDialog(System.Windows.Forms.IWin32Window)
0045e71c 7b622faf System.Windows.Forms.Form.ShowDialog()

如何可以显示一个WinForms从隐藏控制台窗口形成的?



SSCCE:



编译这是一个Windows窗体应用程序:

 公共部分Form1类:表格
{
公共Form1中()
{
的InitializeComponent();
}

私人无效的button1_Click(对象发件人,EventArgs五)
{
变种的StartInfo =新的ProcessStartInfo(Console.exe);
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
的Process.Start(StartInfo的);
}
}



编译此作为控制台应用程序:



 类节目
{
静态无效的主要(字串[] args)
{
应用.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(假);
变种的MainForm =新表();
//启用下一行,使之出现
// mainForm.Visible = TRUE;
Application.Run(MainForm的);
}
}


解决方案

使用 Winspector间谍我发现窗外是实际可用的,但它不具备 WS_VISIBLE 的风格。运用这种风格的形成由之可见,它是在Windows任务栏中显示。



解决方案是显示它之前,使窗体可见的,所以下面的方法加工的

  Application.EnableVisualStyles(); 
Application.SetCompatibleTextRenderingDefault(假);
变种F =新表()
f.Visible = TRUE;
Application.Run(F);

由于在我来说,我希望得到的返回值,我应该叫的ShowDialog()。但是,调用的ShowDialog()已经可见的窗体上是不允许的,所以我粘到 Application.Run(F)和检索结果自己:

  VAR答案= configForm.DialogResult; 


I have a main application which runs a console application. The console application is usually started hidden (ProcessWindowStyle.Hidden), but for testing purposes I can run it with the window shown.

Within the console application I can have plugins loaded and executed. One of the plugins tries to open a WinForm dialog. It works fine if the console application is visible, but it doesn't work any more if the console is hidden.

I have tried:

Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form());

and I also tried the same in a new thread.

Thread t = new System.Threading.Thread(start);
t.Start();
t.Join();

where start() contains the things before. In addition I tried ShowDialog()

Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var f = new Form();
f.ShowDialog();

None of the methods showed the window.

In WinDbg, the native callstack always includes NtUserWaitMessage():

0:000> k
ChildEBP RetAddr  
0038dd58 7b0d8e08 USER32!NtUserWaitMessage+0x15

And the managed callstack always includes WaitMessage(), FPushMessageLoop() and RunMessageLoop():

0:000> !clrstack
OS Thread Id: 0x47c4 (0)
ESP       EIP     
0045e560 76bff5be [InlinedCallFrame: 0045e560] System.Windows.Forms.UnsafeNativeMethods.WaitMessage()
0045e55c 7b0d8e08 System.Windows.Forms.Application+ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32, Int32, Int32)
0045e5f8 7b0d88f7 System.Windows.Forms.Application+ThreadContext.RunMessageLoopInner(Int32, System.Windows.Forms.ApplicationContext)
0045e64c 7b0d8741 System.Windows.Forms.Application+ThreadContext.RunMessageLoop(Int32, System.Windows.Forms.ApplicationContext)
0045e67c 7b5ee597 System.Windows.Forms.Application.RunDialog(System.Windows.Forms.Form)
0045e690 7b622d98 System.Windows.Forms.Form.ShowDialog(System.Windows.Forms.IWin32Window)
0045e71c 7b622faf System.Windows.Forms.Form.ShowDialog()

How can I show a WinForms form from a hidden console window?

SSCCE:

Compile this as a Windows Form application:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        var startInfo = new ProcessStartInfo("Console.exe");
        startInfo.WindowStyle = ProcessWindowStyle.Hidden;
        Process.Start(startInfo);
    }
}

Compile this as the console application:

class Program
{
    static void Main(string[] args)
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        var mainForm = new Form();
        // Enable next line to make it show
        // mainForm.Visible = true;
        Application.Run(mainForm);
    }
}

解决方案

Using Winspector Spy I found out that the window is actually available, but it doesn't have the WS_VISIBLE style. Applying that style to the form made it visible and it was shown in the Windows task bar.

The solution was to make the Form visible before showing it, so the following worked:

Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var f = new Form()
f.Visible = true;
Application.Run(f);

Because in my case I wanted to get the return value, I should call ShowDialog(). However, calling ShowDialog() on an already visible form is not allowed, so I sticked to Application.Run(f) and retrieved the result myself:

var answer = configForm.DialogResult;

这篇关于从隐藏的控制台应用程序显示窗体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆