如何获取记事本文件保存位置
How to get Notepad file saved location
如果记事本文件保存在驱动器中,如何检索它的实际路径。例如,一个记事本进程是 运行,它保存在驱动器的某个地方。我怎样才能检索它的完整路径?使用下面的代码我可以获得过程细节,但不是特定文件的实际路径。
Process[] localByName = Process.GetProcessesByName("notepad");
foreach (Process p in localByName)
{
string path = p.MainModule.FileName.ToString();
}
此 returns 可执行路径,但我需要实际文件所在的驱动器位置。
Notepad++ 的 %APPDATA% 文件夹中有一个 session.xml 文件 here。
您可以使用 XDocument 或 XPath 来解析此文件并检索文件路径。以下是使用 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);
}
请注意,notepad++ 需要先关闭,然后 re-opened 才能刷新此文件。
应该这样做:
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);
}
只有通过双击或命令行打开文件才有效。
不要忘记添加对 System.Management
的引用,方法是右键单击项目,添加引用,然后 select 程序集选项卡并搜索 System.Management。
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 和 UIAutomation。基本上,我打开“另存为...”对话框以获取当前打开文件的文件路径。这很丑陋,但它有效!注意:安装 Microsoft.TestApi nuget 包,并添加对 WindowsBase、System.Drawing、UIAutomationClient 和 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);
}
}
}
如果记事本文件保存在驱动器中,如何检索它的实际路径。例如,一个记事本进程是 运行,它保存在驱动器的某个地方。我怎样才能检索它的完整路径?使用下面的代码我可以获得过程细节,但不是特定文件的实际路径。
Process[] localByName = Process.GetProcessesByName("notepad");
foreach (Process p in localByName)
{
string path = p.MainModule.FileName.ToString();
}
此 returns 可执行路径,但我需要实际文件所在的驱动器位置。
Notepad++ 的 %APPDATA% 文件夹中有一个 session.xml 文件 here。
您可以使用 XDocument 或 XPath 来解析此文件并检索文件路径。以下是使用 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);
}
请注意,notepad++ 需要先关闭,然后 re-opened 才能刷新此文件。
应该这样做:
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);
}
只有通过双击或命令行打开文件才有效。
不要忘记添加对 System.Management
的引用,方法是右键单击项目,添加引用,然后 select 程序集选项卡并搜索 System.Management。
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);
}
}
}