我尝试这样(部分测试代码):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace WindowsFormsApplication1
{
static class Program //
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
public class ConsoleShow
{
/// <summary>
/// 启动控制台
/// </summary>
/// <returns></returns>
[DllImport("kernel32.dll")]
public static extern bool AllocConsole();
/// <summary>
/// 释放控制台
/// </summary>
/// <returns></returns>
[DllImport("kernel32.dll")]
public static extern bool FreeConsole();
}
[STAThread]
static void Main(string[] args)
{
if (args.Length > 0)
{
//控制台方式
ConsoleShow.AllocConsole();
Console.WriteLine(args[0]);
}
else
{
//窗口方式
ConsoleShow.FreeConsole();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
}
通过下面两种方式编译,但实现效果都不太好:
(1)输出类型为“Windows应用程序”时:双击运行,正常显示窗口。但命令行带参数运行时,输出的内容在新的命令行窗口中且一闪而过,不合要求。能否使它显示在原来的命令行窗口中?
(2)输出类型为“控制台应用程序”时:命令行带参数运行,输出内容正常显示。但双击运行时,能显示窗口,但窗口前有命令行窗口一闪而过,不完美。能否实现不闪呢?
分不多,聊表心意。
可能上面说的不清。
我的要求是:(设测试程序为:test.exe)
1.控制台中输入:“test.exe 123”,直接在下一行输出“123”,不许另开窗口。
2.在资源管理器中双击此test.exe,此时直接打开此程序的窗口面,不能显示控制台窗口(闪一下的也不要)。
代码没问题,但是做的事情多余了。满足以下几点就可以了:
输出方式为控制台应用程序
有参数时,直接做该做的事情,不需要AllocConsole或FreeConsole,也就是保持原本的状态。
无参数时,调用FreeConsole释放掉控制台,再运行Form。
这个方式有个问题,也不够完美,就是在FreeConsole之前还是会有个黑色窗口一闪而过的。就是你的第二个方案。但是相比方案一而言,应该是好很多的。
要用AllocConsole把流写入前面的控制台,有看到过解决方案,但是极其复杂且有兼容性问题,不建议做过多研究。
追问多余的代码只为方便测试,对比输出方式为“控制台应用程序”和“Windows应用程序”时的不同。目前困扰我的就是一闪而过的窗口,请问大虾有没有方法解决,听说在代码加载时修改注册类型可以做到,但是不知如何做。
本回答被网友采纳不错的思路,但还是不够完善:
请问大虾能做到么?谢谢。
改成这样,加个回车就可以了。。。
AttachConsole(-1);
Console.WriteLine("123");
System.Windows.Forms.SendKeys.SendWait("{ENTER}");
return;
123前的D:\>
看来本方案也无法解决
只是多了个盘符,问题应该不大吧-__# 别的没啥好办法了。
本回答被提问者采纳C#不精通,只是提个思路:主程序执行前加个“壳”Form1,Form1接收带参数的执行命令,由Form1来判断是用控制台还是用windows应用程序。
给Form1建参数入口,并在构造函数中处理参数。
load事件加自动判断,是Console还是调Form2。
Form1在托盘的图标可以作为一个控制台,加个右键菜单什么的作为扩展应用。例如可以自如切换控制台模式还是windows模式。
笨方法,不喜勿喷,谢谢。