在Windows系统做网络开发,很多时候都是使用Windows服务的模式,但在调度阶段,我们更多的是使用控制台的模式。在开发程序的时候,我们在Program的Main入口进行判断。最初开始使用Environment.UserInteractive属性,在系统不系统服务的交互模式时,程序运行是正常的,但试过有Win7下,系统允许交互模式,结果在服务启动的时候,跳转到控制台的模式了,服务启动不起来。只能在服务的调用方式下带参数,然后在Main的参数中判断是否为服务方式。这在一般的情况下是可以解决问题的。
后来有好几个项目,使用了开源的Socket框架,框架本身是通过配置来启动服务的,这样,就没有经过用户的Main方法了,启动带参数的方法不行了,如果为了判断启动模式而加单独的配置,不是很好的做法,通过Program加全局标识是可以解决程序自身启动同框架启动的判断,但服务如果是通过自身的Main启动,又只能靠加参数的方法了,整个实现感觉都是有点别扭。
在几次的服务程序开发中,遇到一个写文件的路径问题,即取路径总是不对,通过分析,Windows服务启动时的环境默认路径是从System32目录,可能是Windows服务的宿主程序是从这开始的吧,这就有了解决如何判断启动模式的方法了。主要是通过宿主程序是程序集所在的目录来判断。具体如下 :
string curPath = System.Environment.CurrentDirectory;
string basePath = Path.GetDirectoryName(System.AppDomain.CurrentDomain.BaseDirectory);
bool isRunWinService = (curPath != basePath);
如果两个路径不相同,我就认为是启动Windows服务了。我们只要在程序的开始做判断,这样Environment.CurrentDirectory的路径还是宿主程序,一般来说,开发人员很少去改动Environment.CurrentDirectory的。这样我们做好的Exe程序支持用户启动,服务启动,或框架自动的服务管理等模式了。
2024-08-13 08:52:01【出处】:https://www.cnblogs.com/Yjianyong/p/5560442.html
=======================================================================================
C# 当前进程是否为控制台窗口
WPF应用程序,在VS的项目属性中,可以设置输出类型:
那我们在代码中,如何判断应用的类型呢。有没有控制台?是否Windows应用程序还是控制台应用程序?
Kernel32下函数GetConsoleWindow可以解决这个问题:
[DllImport("kernel32.dll")]
private static extern IntPtr GetConsoleWindow();
1 var consoleWindowHandle = GetConsoleWindow(); 2 if (consoleWindowHandle == IntPtr.Zero) 3 { 4 Debug.WriteLine("输出类型为 Windows应用程序"); 5 } 6 else 7 { 8 Debug.WriteLine("输出类型为 控制台应用程序"); 9 }
另外,如果需要判断控制台应用程序内,主窗口是否为控制台,可以根据窗口句柄来确认:
1 var consoleWindowHandle = GetConsoleWindow(); 2 var mainWindowHandle = Process.GetCurrentProcess().MainWindowHandle; 3 4 if (consoleWindowHandle == IntPtr.Zero) 5 { 6 Debug.WriteLine("输出类型为 Windows应用程序"); 7 } 8 else if (consoleWindowHandle == mainWindowHandle) 9 { 10 Debug.WriteLine("输出类型为 控制台应用程序,主窗口也是控制台窗口"); 11 } 12 else 13 { 14 Debug.WriteLine("输出类型为 控制台应用程序,但主窗口为Windows窗口"); 15 }
我们设置输出类型为控制台应用,并在ShowMainWindow前后,输出结果,验证okay:
注:这里输出到VS控制台,是因为使用了Debug类型。如果是Console.Write,程序会优先输出到控制台窗口内。
如果需要在Windows应用程序下,使用控制台窗口输出日志。可以使用AllocConsole:
[DllImport("kernel32.dll")] static extern bool AllocConsole();
AllocConsole,可以创建控制台窗口。bool返回值,true表示之前没有控制台窗口、创建成功,false表示已经有控制台窗口、创建失败。
2024-08-13 08:52:30【出处】:https://www.cnblogs.com/kybs0/p/17273872.html
=======================================================================================
标签:窗口,启动,C#,应用程序,Windows,服务,控制台 From: https://www.cnblogs.com/mq0036/p/18356149