I am trying to cleanly close the Excel,Powerpoint or word process based on the process id.
Workflow: The purpose is we have 2 folders. 1 for each screen. We are working with a dual screen setup and want to display word on 1 page and excel on the other. This works like charm. When 1 of the files gets edited. Or they place another file in 1 of the folders. I ask the program to kill the processes. and reload the files (the new ones) I do this with the watcher event handling.
So i fill a list with all the processID's when the program starts ( Powerpoint/excel/word )
///list of all CREATED processes ( word / excel / powerpoint + adds in the list
public static List<int> pids = new List<int>();
p.Start();
pids.Add(p.Id);
When the Changes happen. I launch a method that checks if the processes in the Pids list match 1 of the processes in the processes list of all the processes running on the host.
Process[] runningProcs = Process.GetProcesses();
foreach (Process proc in runningProcs) {
foreach (int pid in pids) {
if (pid == proc.Id) {
TryKillProcessByMainWindowHwnd(pid);
}
}
}
This works perfectly. As this only returns true when it matches and it passes thru the processid.
I import the DLL through this statement
[DllImport("user32.dll")]
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
I recall to this method through here
public static bool TryKillProcessByMainWindowHwnd(int hWnd) {
uint processID;
GetWindowThreadProcessId((IntPtr)hWnd, out processID);
if (processID == 0) return false;
try {
Process.GetProcessById((int)processID).CloseMainWindow();
}
catch (ArgumentException) {
return false;
}
catch (Win32Exception) {
return false;
}
catch (NotSupportedException) {
return false;
}
catch (InvalidOperationException) {
return false;
}
return true;
}
///Watcher event service that checks both subfolders for changes
public static void watch(string scherm)
{
watcher.Path = "C:\\test\\";
watcher.IncludeSubdirectories = true;
watcher.NotifyFilter = NotifyFilters.LastWrite;
watcher.Filter = "*.*";
watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.Created += new FileSystemEventHandler(OnChanged);
watcher.EnableRaisingEvents = true;
}
/// Onchanged event handling
public static void OnChanged(object source, FileSystemEventArgs e) {
watcher.EnableRaisingEvents = false;
///This code first deletes all processes and then tries to clean up the folder (method explains beneath this topic)
ReleaseOlderFiles();
///checkfolder launches the new edited files. + screen allocation
checkFolder();
Debug.WriteLine("Onchanged fired!");
watcher.EnableRaisingEvents = true;
}
///ReleaseOlderFilesMethod
public static void ReleaseOlderFiles()
{
string[] files = Directory.GetFiles(scherm1);
foreach (string file in files)
{
FileInfo fi = new FileInfo(file);
if (fi.LastAccessTime < DateTime.Now.AddMilliseconds(-5000))
{
try
{
Process[] runningProcs = Process.GetProcesses();
foreach (Process proc in runningProcs)
{
foreach (int pid in pids)
{
if (pid == proc.Id)
{
TryKillProcessByMainWindowHwnd(pid);
}
}
}
}
catch { }
fi.Delete();
}
}
The hWnd variable is filled every time with the hWnd from either Excel/Powerpoint/Word. For some odd reason the processID always returns a 0 value. So the call to the method does not seem to output anything
I tried it all but what am I not seeing? Thanks in advance, this would be such a major help in the finalization of my project !
Found the solution ! Simple as that ! As @Maksim Simkin said. just change the processID. Like so:
public static bool TryKillProcessByMainWindowHwnd(int processID)
{
try
{
Process.GetProcessById((int)processID).CloseMainWindow();
}
catch (ArgumentException)
{
return false;
}
catch (Win32Exception)
{
return false;
}
catch (NotSupportedException)
{
return false;
}
catch (InvalidOperationException)
{
return false;
}
return true;
}
And in my Method that deletes the file. I needed to add a little sleep towards the thread.
public static void ReleaseOlderFiles()
{
string[] files = Directory.GetFiles(scherm1);
foreach (string file in files)
{
FileInfo fi = new FileInfo(file);
if (fi.LastAccessTime < DateTime.Now.AddMilliseconds(-5000))
{
try
{
Process[] runningProcs = Process.GetProcesses();
foreach (Process proc in runningProcs)
{
foreach (int pid in pids)
{
if (pid == proc.Id)
{
TryKillProcessByMainWindowHwnd(pid);
}
}
}
}
catch { }
Thread.Sleep(500);
fi.Delete();
}
}
}
works like charm !
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.