2016-01-21 7 views
1

Как получить фактический путь к файлу блокнота, если он сохранен на диске. Например, выполняется блокнот, и он сохраняется где-то на диске. Как я могу получить полный путь? Используя нижеприведенный код, я могу получить детали процесса, но не фактический путь к определенным файлам.Как получить сохраненное место в файле Notepad

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

это возвращает допустимый путь, но мне нужно место на диске, где находится фактический файл.

+0

Когда вы говорите блокнот, вы имеете в виду файл .txt? Или вы имеете в виду только какой-либо файл, который в настоящее время открыт в экземпляре блокнота? –

+0

любой файл, который открыт в блокноте. – navi

+0

Вы знаете, что можете открыть Блокнот без файла? – LarsTech

ответ

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 по праву. Нажмите «Проект», «Добавить ссылки», затем выберите вкладку «Ассемблемы» и «Поиск системы».

Step 1

Step 2

+0

Я не могу добавить ссылку для ManagementObjectSearcher – navi

+0

@navi ответ отредактирован, чтобы добавить фотографии, чтобы показать вам, как добавить ссылку на «System.Management» – Xenon

+0

Вам также нужно будет добавить эту строку в usings (вверху вашего кода) «using System.Management;» – Xenon

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); 
} 

Пожалуйста, обратите внимание, что Notepad ++ должен быть закрыт затем вновь открыт, чтобы обновить этот файл.

+1

Вопрос о Windows Notepad not Notepad ++ – Steve

+0

Упс. Я никогда не использую обычный блокнот, поэтому я всегда ассоциировал Notepad ++ как «Блокнот». Ну что ж! – GabeMeister

0

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); 
    } 
} 
}