如何获取记事本文件保存的位置

时间:2016-01-21 19:08:09

标签: c# wpf winforms notepad win32-process

如果记事本保存在驱动器中,如何检索记事本文件的实际路径。例如,记事本进程正在运行,它将保存在驱动器中的某个位置。如何检索其完整路径?使用下面的代码我可以获得流程详细信息,但不能获取特定文件的实际路径。

Process[] localByName = Process.GetProcessesByName("notepad");
foreach (Process p in localByName)
    {
      string path  =  p.MainModule.FileName.ToString();
    }

这会返回可执行路径,但我需要实际文件所在的驱动器位置。

3 个答案:

答案 0 :(得分:3)

这应该这样做:

        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的引用单击Project,Add References,然后选择Assemblies选项卡并搜索System.Management。

Step 1

Step 2

答案 1 :(得分:1)

Notepad ++在其中找到了一个session.xml文件的%APPDATA%文件夹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);
}

请注意,需要关闭记事本++,然后重新打开才能刷新此文件。

答案 2 :(得分:0)

如果你没有通过File->打开文件,

Xenon's answer绝对是最好的。在记事本中打开。为了好玩,我尝试创建一个适用于所有情况的解决方案。您可以通过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);
    }
}
}