Откройте файл в редакторе по умолчанию на языке C#

#c# #file

#c# #файл

Вопрос:

В C# я хочу открыть файл в редакторе по умолчанию. То есть я хочу сделать то, что произошло бы, если бы пользователь открыл папку, содержащую файл, и вручную открыл файл для редактирования. Конкретно:

  1. Если я щелкну файл правой кнопкой мыши в Проводнике и в диалоговом окне правой кнопки мыши появится запись «Редактировать», он откроет файл в этом редакторе,
  2. Если запись редактирования отсутствует, он использует приложение, которое будет использоваться при двойном щелчке по файлу, если это приложение поддерживает редактирование,
  3. Если нет связи с редактором, позволяет пользователю выбрать программу, используя тот же «Как вы хотите открыть этот файл?» диалоговое окно, как при двойном щелчке в Проводнике без связи (т. Е. Щелкните правой кнопкой мыши, Откройте с помощью gt; Выберите другое приложение),
  4. В противном случае открывается в явно заданном резервном варианте (например, в блокноте).

Это также должно быть как можно более кроссплатформенным (как кроссплатформенным, как что-то вроде процесса.Начало, во всяком случае), так что никаких взломов реестра или p/вызовов. Не говоря уже об этом Процессе.Start, похоже, вызывает те же собственные API, в которые я бы p/вызывал, поэтому, что бы ни делал ShellExecuteEx, это не должно удовлетворять вышеизложенному.

Кроме того, если файл не существует, должно произойти что-то разумное. Не открывайте, например, папку «Документы» текущего пользователя, как это будет сделано в примере ниже.

Следующее решение неверно:

 ProcessStartInfo psi = new ProcessStartInfo(file) {  UseShellExecute = true };  psi.Verb = "edit"; Process p = Process.Start(psi);  

Поскольку есть некоторые ситуации, когда при этом не используется тот же редактор, что и в Проводнике. (Я точно не знаю, почему это происходит, и документация, похоже, подразумевает, что этого не должно быть, но я видел ситуации, когда это происходит.)

Кроме того, это, похоже, не удовлетворяет №3.

Следующее также неверно:

 ProcessStartInfo psi = new ProcessStartInfo("explorer") {  Argument = file, };  Process p = Process.Start(psi);  

Как это удовлетворяет 2 (по крайней мере, иногда?) и 3, это не удовлетворяет 1. Например, если я попытаюсь открыть «foo.js», проводник пытается использовать узел сценариев Windows, а не редактор, даже если в контекстном меню есть запись «редактировать».

Для потомков следующее решение, очевидно, не соответствует моим требованиям и, похоже, основывается на недокументированном поведении:

 Process.Start("rundll32.exe shell32.dll,OpenAs_RunDLL file")  

Комментарии:

1. Process Тип должен работать в контекстах, где есть только консоль или даже вообще нет видимого пользовательского интерфейса. Из-за этого я не верю, что вы найдете что-нибудь встроенное, что будет соответствовать всем вашим критериям.

2. Может быть проблема x86/x64 (по крайней мере, в Windows). На какой платформе находится ваше приложение?

3. Вам придется написать это в виде серии шагов. Сначала используется StartInfo.Verb = "edit"; , если это вызывает исключение, попробуйте следующее, а затем так далее. Нет ничего одного, но это может быть выполнимо, если вы решите каждый шаг как отдельную проблему.