Как перехватить закрытие Windows-приложения без формы?
Код:
[STAThread]
static void Main()
{
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = "C:\\";
watcher.NotifyFilter = NotifyFilters.LastAccess;
watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.Created += new FileSystemEventHandler(OnChanged);
watcher.Deleted += new FileSystemEventHandler(OnChanged);
watcher.Renamed += new RenamedEventHandler(OnRenamed);
Application.SetCompatibleTextRenderingDefault(false);
Application.Run();
}
static void Main()
{
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = "C:\\";
watcher.NotifyFilter = NotifyFilters.LastAccess;
watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.Created += new FileSystemEventHandler(OnChanged);
watcher.Deleted += new FileSystemEventHandler(OnChanged);
watcher.Renamed += new RenamedEventHandler(OnRenamed);
Application.SetCompatibleTextRenderingDefault(false);
Application.Run();
}
после Мейна идут фукнции-обработчики событий, который пишут все в текстовый файл.
Мне надо так сделать, чтобы при выключении компьютера, когда система посылает всем программам команду закрыться, чтобы в этот момент моя программа перед своим закрытием сбрасывала содержимое всех буферов файлового потока в файл (то есть, выполнялась функция Flush()), а то сейчас получается неприятная ситуация, что мое приложение виндой убивается, и все данные, что должны были записаться в файл, но остались в буфере файлового потока, так и пропадают, не записавшись в файл.
Как перехватить закрытие приложения?
P.S. Как перехвачивать закрытие приложения с формой, я знаю. Но просто в моем приложении нет формы...
Подписывайся на событие Application.ApplicationExit. И в нём выполняй действия, нужные перед закрытием приложения.
Я также пробовал подписываться на другие события, такие как Application.ThreadExit и AppDomain.CurrentDomain.ProcessExit, но ни то ни другое событие не происходит при закрытии приложения виндой. Уже надоело из-за этих тестов комп перезагружать... А как можно еще послать команду приложению закрыться, чтобы компьютер перезагрузками не мучать? Я для тестов написал вот такое приложение для послания команды закрыться:
Код:
private void buttonRun_Click(object sender, EventArgs e)
{
processPath = "F:\\Projects\\C#\\Test\\FSEvents\\FSEvents\\bin\\Debug\\FSEvents.exe";
this.process = System.Diagnostics.Process.Start(processPath);
}
private void buttonExit_Click(object sender, EventArgs e)
{
process.CloseMainWindow();
}
{
processPath = "F:\\Projects\\C#\\Test\\FSEvents\\FSEvents\\bin\\Debug\\FSEvents.exe";
this.process = System.Diagnostics.Process.Start(processPath);
}
private void buttonExit_Click(object sender, EventArgs e)
{
process.CloseMainWindow();
}
но оно не закрывает приложение FSEvents.exe
Если я для примера напишу в processPath "notepad.exe", то он кнопкой Run запускается и кнопкой Exit закрывается. А если FSEvents.exe написать, то открывать он его открывает, а кнопка Exit не действует на него никак =-O То есть, приложение FSEvents.exe продолжает работать.
Вот полный код моего приложения FSEvents. Может я где-то и накрутил, из-за того и не работает событие... Покажите пожалуйста.
Код:
using System;
using System.Windows.Forms;
using System.IO;
namespace FSEvents
{
static class Program
{
public static StreamWriter flog;
public static string fileLogName = "history.txt";
public static string fileSettingsName = "settings.ini";
public static DateTime dt = DateTime.Now;
public static DateTime dtNow;
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
flog = new StreamWriter(fileLogName, true);
flog.WriteLine("{0} FS START", dt);
StreamReader fileSettings;
try
{
fileSettings = new StreamReader(fileSettingsName);
}
catch (Exception e)
{
flog.WriteLine("{0} ERROR. {1}", DateTime.Now, e.Message);
flog.Close();
return;
}
string nameDrives = fileSettings.ReadLine(); ////
if (nameDrives == null)
{
flog.WriteLine("{0} ERROR. File '{1}' not have drive letters", DateTime.Now, fileSettingsName);
flog.Close();
return;
}
int numberDrives = nameDrives.Length;
FileSystemWatcher[] fsw = new FileSystemWatcher[numberDrives];
// Create a FileSystemWatcher to monitor all files on drives.
for (int i = 0; i < numberDrives; i++)
{
try
{
fsw = new FileSystemWatcher(nameDrives + ":\\");
// Watch for changes in LastAccess and LastWrite times, and
// the renaming of files or directories.
fsw.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
| NotifyFilters.FileName | NotifyFilters.DirectoryName;
// Register a handler that gets called when a
// file is created, changed, or deleted.
fsw.Changed += new FileSystemEventHandler(OnChanged);
fsw.Created += new FileSystemEventHandler(OnChanged);
fsw.Deleted += new FileSystemEventHandler(OnChanged);
// Register a handler that gets called when a file is renamed.
fsw.Renamed += new RenamedEventHandler(OnRenamed);
// Register a handler that gets called if the
// FileSystemWatcher needs to report an error.
fsw.Error += new ErrorEventHandler(OnError);
// Begin watching.
fsw.EnableRaisingEvents = true;
}
catch (Exception e)
{
flog.WriteLine("{0} ERROR. {1}", DateTime.Now, e.Message);
}
}
Application.ApplicationExit += new EventHandler(Application_ApplicationExit);
Application.ThreadExit += new EventHandler(Application_ApplicationExit);
AppDomain.CurrentDomain.ProcessExit += new EventHandler(Application_ApplicationExit);
Application.SetCompatibleTextRenderingDefault(false);
Application.Run();
}
// This method is called when a file is created, changed, or deleted.
private static void OnChanged(object source, FileSystemEventArgs e)
{
// Show that a file has been created, changed, or deleted.
dtNow = DateTime.Now;
WatcherChangeTypes wct = e.ChangeType;
try
{
flog.WriteLine("{2} \"{0}\" {1}", e.FullPath, wct.ToString(), dtNow);
}
catch
{
return;
}
ForceFlush();
}
// This method is called when a file is renamed.
private static void OnRenamed(object source, RenamedEventArgs e)
{
// Show that a file has been renamed.
dtNow = DateTime.Now;
WatcherChangeTypes wct = e.ChangeType;
try
{
flog.WriteLine("{3} \"{0}\" {2} to \"{1}\"", e.OldFullPath, e.FullPath, wct.ToString(), dtNow);
}
catch
{
return;
}
ForceFlush();
}
// This method is called when the FileSystemWatcher detects an error.
private static void OnError(object source, ErrorEventArgs e)
{
// Show that an error has been detected.
dtNow = DateTime.Now;
flog.WriteLine("{0} The FileSystemWatcher has detected an error", dtNow);
// Give more information if the error is due to an internal buffer overflow.
if (e.GetException().GetType() == typeof(InternalBufferOverflowException))
{
// This can happen if Windows is reporting many file system events quickly
// and internal buffer of the FileSystemWatcher is not large enough to handle this
// rate of events. The InternalBufferOverflowException error informs the application
// that some of the file system events are being lost.
flog.WriteLine(("{0} The file system watcher experienced an internal buffer overflow: " + e.GetException().Message), dtNow);
}
ForceFlush();
}
private static void ForceFlush()
{
if (dtNow.Minute != dt.Minute)
flog.Flush();
dt = dtNow;
}
private static void Application_ApplicationExit(object sender, EventArgs e)
{
MessageBox.Show("ApplicationExit"); //for tests... delete after tests
flog.WriteLine("{0} FS EXIT", DateTime.Now);
flog.Close();
}
}
}
using System.Windows.Forms;
using System.IO;
namespace FSEvents
{
static class Program
{
public static StreamWriter flog;
public static string fileLogName = "history.txt";
public static string fileSettingsName = "settings.ini";
public static DateTime dt = DateTime.Now;
public static DateTime dtNow;
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
flog = new StreamWriter(fileLogName, true);
flog.WriteLine("{0} FS START", dt);
StreamReader fileSettings;
try
{
fileSettings = new StreamReader(fileSettingsName);
}
catch (Exception e)
{
flog.WriteLine("{0} ERROR. {1}", DateTime.Now, e.Message);
flog.Close();
return;
}
string nameDrives = fileSettings.ReadLine(); ////
if (nameDrives == null)
{
flog.WriteLine("{0} ERROR. File '{1}' not have drive letters", DateTime.Now, fileSettingsName);
flog.Close();
return;
}
int numberDrives = nameDrives.Length;
FileSystemWatcher[] fsw = new FileSystemWatcher[numberDrives];
// Create a FileSystemWatcher to monitor all files on drives.
for (int i = 0; i < numberDrives; i++)
{
try
{
fsw = new FileSystemWatcher(nameDrives + ":\\");
// Watch for changes in LastAccess and LastWrite times, and
// the renaming of files or directories.
fsw.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
| NotifyFilters.FileName | NotifyFilters.DirectoryName;
// Register a handler that gets called when a
// file is created, changed, or deleted.
fsw.Changed += new FileSystemEventHandler(OnChanged);
fsw.Created += new FileSystemEventHandler(OnChanged);
fsw.Deleted += new FileSystemEventHandler(OnChanged);
// Register a handler that gets called when a file is renamed.
fsw.Renamed += new RenamedEventHandler(OnRenamed);
// Register a handler that gets called if the
// FileSystemWatcher needs to report an error.
fsw.Error += new ErrorEventHandler(OnError);
// Begin watching.
fsw.EnableRaisingEvents = true;
}
catch (Exception e)
{
flog.WriteLine("{0} ERROR. {1}", DateTime.Now, e.Message);
}
}
Application.ApplicationExit += new EventHandler(Application_ApplicationExit);
Application.ThreadExit += new EventHandler(Application_ApplicationExit);
AppDomain.CurrentDomain.ProcessExit += new EventHandler(Application_ApplicationExit);
Application.SetCompatibleTextRenderingDefault(false);
Application.Run();
}
// This method is called when a file is created, changed, or deleted.
private static void OnChanged(object source, FileSystemEventArgs e)
{
// Show that a file has been created, changed, or deleted.
dtNow = DateTime.Now;
WatcherChangeTypes wct = e.ChangeType;
try
{
flog.WriteLine("{2} \"{0}\" {1}", e.FullPath, wct.ToString(), dtNow);
}
catch
{
return;
}
ForceFlush();
}
// This method is called when a file is renamed.
private static void OnRenamed(object source, RenamedEventArgs e)
{
// Show that a file has been renamed.
dtNow = DateTime.Now;
WatcherChangeTypes wct = e.ChangeType;
try
{
flog.WriteLine("{3} \"{0}\" {2} to \"{1}\"", e.OldFullPath, e.FullPath, wct.ToString(), dtNow);
}
catch
{
return;
}
ForceFlush();
}
// This method is called when the FileSystemWatcher detects an error.
private static void OnError(object source, ErrorEventArgs e)
{
// Show that an error has been detected.
dtNow = DateTime.Now;
flog.WriteLine("{0} The FileSystemWatcher has detected an error", dtNow);
// Give more information if the error is due to an internal buffer overflow.
if (e.GetException().GetType() == typeof(InternalBufferOverflowException))
{
// This can happen if Windows is reporting many file system events quickly
// and internal buffer of the FileSystemWatcher is not large enough to handle this
// rate of events. The InternalBufferOverflowException error informs the application
// that some of the file system events are being lost.
flog.WriteLine(("{0} The file system watcher experienced an internal buffer overflow: " + e.GetException().Message), dtNow);
}
ForceFlush();
}
private static void ForceFlush()
{
if (dtNow.Minute != dt.Minute)
flog.Flush();
dt = dtNow;
}
private static void Application_ApplicationExit(object sender, EventArgs e)
{
MessageBox.Show("ApplicationExit"); //for tests... delete after tests
flog.WriteLine("{0} FS EXIT", DateTime.Now);
flog.Close();
}
}
}