C#判断程序是由Windows服务启动还是用户启动
在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应用程序还是控制台应用程序
在C#中,您可以通过检查当前应用程序的Main方法的参数来判断是Windows应用程序还是控制台应用程序。对于控制台应用程序,Main
方法通常有一个 string[] args
参数;而对于Windows应用程序,Main
方法位于一个形为 Application
的类中,并且通常没有参数。
以下是一个简单的示例代码,用于判断当前应用程序是控制台应用程序还是Windows应用程序:
如果您的应用程序是通过命令行启动的,并且带有参数,那么它是控制台应用程序。否则,它可能是Windows应用程序。需要注意的是,这种方法并不完美,因为某些情况下可能需要更复杂的检查。但对于大多数简单的场景,上述代码应该足够使用。
=======================================================================================
另外,还有一些其他的方式方法进行判断,以下供参考:
-------------------------------------------------------
可能需要尝试Process对象的SessionId属性。根据我的经验,如果进程正在运行服务,则将SessionId设置为0。
-------------------------------------------------------
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr GetStdHandle(int nStdHandle);
const int STD_OUTPUT_HANDLE = -11;
IntPtr iStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
if (iStdOut == IntPtr.Zero)
{
app.RunAsWindowsService = true;
}
// Run as Service
if (runAsWindowsService)
{
// .....
ServiceBase.Run(myService);
}
else
{
// Run as Console
// Register Ctrl+C Handler...
}
-------------------------------------------------------
使用this answer中关于查找父进程的ParentProcessUtilities结构,您可以执行以下操作:
static bool RunningAsService() {
var p = ParentProcessUtilities.GetParentProcess();
return ( p != null && p.ProcessName == "services" );
}
请注意,父进程的进程名称不包括扩展名".exe“。
-------------------------------------------------------
我不知道这是否有效,但您可能想尝试在this代码中使用PInvoke,并检查父对象是否为"services.exe“。
-------------------------------------------------------
我最终通过检查Console.IsErrorRedirected来检测我是否在控制台应用程序中。对于控制台应用程序,它返回"false“,对于我测试的非控制台应用程序,它返回"true”。我也可以使用IsOutputRedirected。
我想在某些情况下,这些并不准确,但这对我来说效果很好。
出处:https://cloud.tencent.com/developer/ask/sof/102504823
======================================================================
c# 在Windowns应用程序如何使用console
在Windows应用程序中使用Console通常是指在Windows Forms或WPF应用程序中模拟控制台输入输出。这可以通过AllocConsole
函数在程序启动时分配一个新的控制台,并通过FreeConsole
在需要时释放它。
以下是一个简单的示例,展示如何在Windows Forms应用程序中使用控制台:
using System; using System.Runtime.InteropServices; using System.Windows.Forms; public class ConsoleInWPF : Form { [DllImport("kernel32.dll")] private static extern bool AllocConsole(); [DllImport("kernel32.dll")] private static extern bool FreeConsole(); public ConsoleInWPF() { // 分配控制台 AllocConsole(); // 写入到控制台 Console.WriteLine("Hello, Console!"); // 在此处添加其他初始化代码... } protected override void OnFormClosed(FormClosedEventArgs e) { base.OnFormClosed(e); // 窗体关闭时释放控制台 FreeConsole(); } [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new ConsoleInWPF()); } }
在这个例子中,AllocConsole
在窗体构造函数中被调用,从而在应用程序启动时为它分配一个控制台。然后,你可以使用Console.WriteLine
等方法来写入到这个控制台。在窗体关闭时,通过FreeConsole
释放控制台资源。
请注意,这种方法并不是在所有情况下都适用,例如,如果你的应用程序是基于.NET Core的,或者你正在使用更现代的项目模板,可能需要不同的方法来实现控制台输入输出。
关注我】。(●'◡'●)
如果,您希望更容易地发现我的新博客,不妨点击一下绿色通道的【因为,我的写作热情也离不开您的肯定与支持,感谢您的阅读,我是【Jack_孟】!
本文来自博客园,作者:jack_Meng,转载请注明原文链接:https://www.cnblogs.com/mq0036/p/18356149
【免责声明】本文来自源于网络,如涉及版权或侵权问题,请及时联系我们,我们将第一时间删除或更改!