问题
How to retrieve the actual path of the notepad file if it is saved in drive. For example a notepad process is running and it is saved somewhere in the drive. How can I retrieve its full path? Using below code I can get the process detail, but not the actual path of particular files.
Process[] localByName = Process.GetProcessesByName("notepad");
foreach (Process p in localByName)
{
string path = p.MainModule.FileName.ToString();
}
this returns executeable path but i need Drive location whre the actual file reside.
回答1:
This should do it:
string wmiQuery = string.Format("select CommandLine from Win32_Process where Name='{0}'", "notepad.exe");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(wmiQuery);
ManagementObjectCollection retObjectCollection = searcher.Get();
foreach (ManagementObject retObject in retObjectCollection)
{
string CommandLine = retObject["CommandLine"].ToString();
string path = CommandLine.Substring(CommandLine.IndexOf(" ") + 1, CommandLine.Length - CommandLine.IndexOf(" ") - 1);
}
It will work only if the file is opened by double click or through command line.
Don't forget to add reference to System.Management
by right Click on Project, Add References then select the Assemblies Tab and Search for System.Management.
回答2:
Notepad++ has a session.xml file in it's %APPDATA% folder found here.
You can use XDocument or XPath to parse this file and retrieve the file paths. Here's how you get them with XPath:
XmlDocument doc = new XmlDocument();
doc.Load(@"C:\Users\USERNAME_HERE\AppData\Roaming\Notepad++\session.xml");
XmlNodeList files = doc.SelectNodes("//NotepadPlus/Session/mainView/File");
foreach (XmlNode file in files)
{
Console.WriteLine(file.Attributes["filename"].Value);
}
Please note that notepad++ needs to be closed then re-opened to refresh this file.
回答3:
Xenon's answer is definitely the best if you didn't open the file via File-> Open in notepad. For fun, I tried to create a solution that will work in all cases. You can achieve this with a combination of Microsoft TestApi and UIAutomation. Basically I'm opening the Save As... dialog to get the file path of the currently opened file. It's ugly but it works! Note: Intall the Microsoft.TestApi nuget package, and add references to WindowsBase, System.Drawing, UIAutomationClient, and UIAutomationTypes.
using Microsoft.Test.Input;
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows;
using System.Windows.Automation;
namespace ConsoleApplication1
{
class Program
{
[DllImport("user32.dll")]
static extern bool SetForegroundWindow(IntPtr hWnd);
static void Main(string[] args)
{
Process[] localByName = Process.GetProcessesByName("notepad");
foreach (Process p in localByName)
{
string fileName = p.MainWindowTitle; // get file name from notepad title
SetForegroundWindow(p.MainWindowHandle);
AutomationElement windowAutomationElement = AutomationElement.FromHandle(p.MainWindowHandle);
var menuElements = windowAutomationElement.FindAll(TreeScope.Descendants, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.MenuItem));
AutomationElement fileMenuElement = null;
foreach (AutomationElement element in menuElements)
{
if (element.Current.Name == "File")
{
fileMenuElement = element;
break;
}
}
if (fileMenuElement != null)
{
fileMenuElement.SetFocus();
fileMenuElement.Click();
Thread.Sleep(800); // Sleeping an arbitrary amount here since we must wait for the file menu to appear before the next line can find the menuItems. A better way to handle it is probably to run the FindAll in the next line in a loop that breaks when menuElements is no longer null.
menuElements = fileMenuElement.FindAll(TreeScope.Descendants, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.MenuItem));
var saveAsMenuElement = fileMenuElement.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.NameProperty, "Save As..."));
if (saveAsMenuElement != null)
{
saveAsMenuElement.SetFocus();
saveAsMenuElement.Click();
Thread.Sleep(800);
var saveAsWindow = windowAutomationElement.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Window));
var toolbarElements = saveAsWindow.FindAll(TreeScope.Descendants, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.ToolBar));
foreach (AutomationElement element in toolbarElements)
if (element.Current.Name.StartsWith("Address:"))
Console.WriteLine(element.Current.Name + @"\" + fileName); // Parse out the file name from this concatenation here!
var closeButtonElement = saveAsWindow.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.NameProperty, "Close"));
closeButtonElement.Click();
}
}
}
Console.ReadLine();
}
}
public static class AutomationElementExtensions
{
public static void MoveTo(this AutomationElement automationElement)
{
Point somePoint;
if (automationElement.TryGetClickablePoint(out somePoint))
Mouse.MoveTo(new System.Drawing.Point((int)somePoint.X, (int)somePoint.Y));
}
public static void Click(this AutomationElement automationElement)
{
automationElement.MoveTo();
Mouse.Click(MouseButton.Left);
}
}
}
来源:https://stackoverflow.com/questions/34932301/how-to-get-notepad-file-saved-location