我已经制作了一个简单的Windows应用程序(虽然没有任何Form),并且在我根据C#Cookbook中的recipe19.1使用SessionEnding在操作系统关闭之前做了一些事情(我修改了,因为Debug无论如何都不会工作)
应用程序在启动时创建文本文件(确实如此),然后在发生任何事件时应创建另一个空白文本文件。 代码如下,它不能按预期工作。事件发生时不会创建任何内容。有人能告诉我这有什么问题吗?
作为旁注,我这次使用WndProc的覆盖尝试了其他示例,如the documentation中所述,它似乎有效,但我不知道如何将其应用于没有表单的应用程序
代码
using Microsoft.Win32;
using System;
using System.Diagnostics;
using System.Threading;
namespace NoConsoleApp2
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
RegisterForSystemEvents();
System.IO.File.Create(AppDomain.CurrentDomain.BaseDirectory + "Onstart.txt");
bool keepRunning = true;
Debug.WriteLine("Start");
for (int i = 0; i < 100 && keepRunning; i++)
{
Thread.Sleep(1000);
}
Debug.WriteLine("End");
}
public static void RegisterForSystemEvents()
{
//Always get the final notification when the event thread is shutting down
//so we can unregister.
SystemEvents.EventsThreadShutdown += new EventHandler(OnEventsThreadShutdown);
SystemEvents.PowerModeChanged += new PowerModeChangedEventHandler(OnPowerModeChanged);
SystemEvents.SessionSwitch += new SessionSwitchEventHandler(OnSessionSwitch);
SystemEvents.SessionEnding += new SessionEndingEventHandler(OnSessionEnding);
SystemEvents.SessionEnded += new SessionEndedEventHandler(OnSessionEnded);
}
private static void UnregisterFromSystemEvents()
{
SystemEvents.EventsThreadShutdown -= new EventHandler(OnEventsThreadShutdown);
SystemEvents.PowerModeChanged -= new PowerModeChangedEventHandler(OnPowerModeChanged);
SystemEvents.SessionSwitch -= new SessionSwitchEventHandler(OnSessionSwitch);
SystemEvents.SessionEnding -= new SessionEndingEventHandler(OnSessionEnding);
SystemEvents.SessionEnded -= new SessionEndedEventHandler(OnSessionEnded);
}
/* Notifies you when the thread that is distributing the events from the SystemEvents class is
* shutting down so that we can unregister events on the SystemEvents class
*/
private static void OnEventsThreadShutdown(object sender, EventArgs e)
{
System.IO.File.Create(AppDomain.CurrentDomain.BaseDirectory + "END.txt");
Debug.WriteLine("System event thread is shutting down, no more notifications");
//Unregister all our events as the notification thread is goin away
UnregisterFromSystemEvents();
}
/* Triggers when the user suspends or resumes the system from a suspended state
*/
private static void OnPowerModeChanged(object sender, PowerModeChangedEventArgs e)
{
System.IO.File.Create(AppDomain.CurrentDomain.BaseDirectory + "power.txt");
switch (e.Mode)
{
case PowerModes.Resume:
Debug.WriteLine("PowerMode: OS is resuming from suspended state");
break;
case PowerModes.StatusChange:
Debug.WriteLine("PowerMode: There was a change relating to the power supply (weak battery, unplug, etc...)");
break;
case PowerModes.Suspend:
Debug.WriteLine("PowerMode: OS is about to be suspended");
break;
}
}
/* Triggered by a change in the logged-on user
*/
private static void OnSessionSwitch(object sender, SessionSwitchEventArgs e)
{
System.IO.File.Create(AppDomain.CurrentDomain.BaseDirectory + "sessionswitch.txt");
switch (e.Reason)
{
case SessionSwitchReason.ConsoleConnect:
Debug.WriteLine("Session connected from the console");
break;
case SessionSwitchReason.ConsoleDisconnect:
Debug.WriteLine("Session disconnected from the console");
break;
case SessionSwitchReason.RemoteConnect:
Debug.WriteLine("Remote Session connected");
break;
case SessionSwitchReason.RemoteDisconnect:
Debug.WriteLine("Remote Session disconnected");
break;
case SessionSwitchReason.SessionLock:
Debug.WriteLine("Session has been locked");
break;
case SessionSwitchReason.SessionLogoff:
Debug.WriteLine("User was logged off from a session");
break;
case SessionSwitchReason.SessionLogon:
Debug.WriteLine("User has logged on to a session");
break;
case SessionSwitchReason.SessionRemoteControl:
Debug.WriteLine("Session changed to or from remote status");
break;
case SessionSwitchReason.SessionUnlock:
Debug.WriteLine("Session has been unlocked");
break;
}
}
/* Triggered when the user is trying to log off or shut down the system
*/
private static void OnSessionEnding(object sender, SessionEndingEventArgs e)
{
System.IO.File.Create(AppDomain.CurrentDomain.BaseDirectory + "sessionend.txt");
//True to cancel the user request to end the session, false otherwise
e.Cancel = false;
switch(e.Reason)
{
case SessionEndReasons.Logoff:
Debug.WriteLine("Session ending as the user is logging off");
System.IO.File.Create(AppDomain.CurrentDomain.BaseDirectory + "Logoff.txt");
break;
case SessionEndReasons.SystemShutdown:
Debug.WriteLine("Session ending as the OS is shutting down");
System.IO.File.Create(AppDomain.CurrentDomain.BaseDirectory + "Shutdown.txt");
break;
}
}
/* Triggered when the user is actually logging off or shutting down the system
*/
private static void OnSessionEnded(object sender, SessionEndedEventArgs e )
{
switch(e.Reason)
{
case SessionEndReasons.Logoff:
Debug.WriteLine("Session ended as the user is logging off");
System.IO.File.Create(AppDomain.CurrentDomain.BaseDirectory + "Loggedoff.txt");
break;
case SessionEndReasons.SystemShutdown:
Debug.WriteLine("Session ended as the OS is shutting down");
System.IO.File.Create(AppDomain.CurrentDomain.BaseDirectory + "Shutted.txt");
break;
}
}
}
}
编辑:
我被告知我应该使用Application.Run并且事件正在响应。但是我假设Run生成一个循环所以我想知道在哪里放置我自己的逻辑(在这个例子中是for循环)
static void Main()
{
RegisterForSystemEvents();
System.IO.File.Create(AppDomain.CurrentDomain.BaseDirectory + "Onstart.txt");
bool keepRunning = true;
Debug.WriteLine("Start");
Application.Run(); //this activates the events
System.IO.File.Create(AppDomain.CurrentDomain.BaseDirectory + "GoFOrloop.txt");
for (int i = 0; i < 100 && keepRunning; i++)
{
Thread.Sleep(1000);
}
Debug.WriteLine("End");
}
在这种情况下,永远不会创建文件GoForLoop.txt(意味着循环本身永远不会被执行)
EDIT2: 我在EDIT中尝试了解决方案并且它可以工作(事件被触发)但是主要逻辑(在这种情况下是循环)不起作用所以我尝试了第二个建议来使用应用程序上下文。可悲的是,这次循环工作时,事件不再被触发:(
class Context : ApplicationContext
{
public Context()
{
System.IO.File.Create(AppDomain.CurrentDomain.BaseDirectory + "GoFOrLoop.txt");
for (int i = 0; i < 60; i++)
{
// Console.WriteLine("Number: " + i);
Thread.Sleep(1000);
}
System.IO.File.Create(AppDomain.CurrentDomain.BaseDirectory + "end.txt");
Debug.WriteLine("End");
// Environment.Exit(1);
ExitThread();
}
}
并在主
中 [STAThread]
static void Main()
{
/* Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
*/
RegisterForSystemEvents();
System.IO.File.Create(AppDomain.CurrentDomain.BaseDirectory + "Onstart.txt");
// bool keepRunning = true;
Debug.WriteLine("Start");
// Application.Run(); //this works
Application.Run(new Context()); //this DOES NOT work
}
答案 0 :(得分:1)