2015-04-10 3 views
0

В настоящее время я пытаюсь выполнить следующее:C# получить полный путь еще не запущенного процесса объекта

Для SDK, который мы предоставляем нашим клиентам, мы хотим, чтобы SDK-разработчиков, чтобы иметь возможность обеспечивают внешние вызовы приложений, чтобы они могли вставлять дополнительные кнопки. Эти кнопки, чем запускают внешнее приложение или открывают файл с приложением по умолчанию для него (например, Word for * .docx).

Должно быть какое-то визуальное различие между различными кнопками, поэтому наш подход заключается в том, чтобы показать значок приложения, которое будет вызываться.

Теперь есть три различные виды звонков: (Приводимые ниже строки всегда будут значение ProcessStartInfo.FileName)

  1. Вызов приложения, предоставляющее полный путь к приложению, возможно, с environement варов (например, "C:\Program Files\Internet Explorer\iexplore.exe"/"%ProgramFiles%\Internet Explorer\iexplore.exe")
  2. Вызов приложения, обеспечивающий только имя исполняемого файла, поскольку приложение может быть найден в PATH переменной (например, "iexplore")
  3. Открытие документа без предоставления заявления в ор ru (см. "D:\test.html")

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


Есть ли способ найти полный путь или значок объекта System.Diagnostics.Process или System.Diagnostics.ProcessStartInfo, до процесс начат?

Важно: Мы не должны начать процесс, прежде чем (может иметь побочные эффекты)

Пример кода:

var process = new Process 
{ 
    StartInfo = 
    { 
     //applicationPath could be any of the stated above calls 
     FileName = Environment.ExpandEnvironmentVariables(applicationPath) 
    } 
}; 
//we have to find the full path here, but MainModule is null as long as the process object has not yet started 
var icon = Icon.ExtractAssociatedIcon(process.MainModule.FullPath) 

Solution Спасибо вам, ребята, я нашел свое решение , Проект, связанный с here at CodeProject, предлагает решение для моей точной проблемы, которая работает в равной степени с программами и файлами и может предоставить значок перед запуском процесса. Спасибо за ссылку @wgraham

+1

Вам необходимо запросить список программ по умолчанию. затем найдите программу по умолчанию, связанную с расширением, которое вы хотите открыть. затем получите путь к запуску, и вы можете получить значок программы с помощью одного из методов win api. – Franck

ответ

0

Если вы хотите, чтобы ваш пользовательский интерфейс, чтобы быть визуально в соответствии с остальной частью компьютера пользователя, вы можете extract the icon from the file с помощью Icon.ExtractAssociatedIcon(string path). Это работает в мире WinForms/GDI. В качестве альтернативы this question описывает, как завершить его с помощью P/Invoke.

+0

Спасибо за ссылку на вопрос о P/Invoke, это прекрасно. Проект [связанный код] (http://www.codeproject.com/Articles/2532/Obtaining-and-managing-file-and-folder-icons-using) project (^^) работает с файлами и их приложениями по умолчанию и нормальные аплодисменты. –

0

Класс Process может делать именно то, что вы хотите. Переменные среды, такие как% ProgramFiles%, необходимо сначала развернуть с помощью Environment.ExpandEnvironmentVariables (string).


1.

using System.IO; 
using System.Diagnostics; 

string iexplore = @"C:\Program Files\Internet Explorer\iexplore.exe"); 

string iexploreWithEnvVars = Environment.ExpandEnvironmentVariables(@"%ProgramFiles%\Internet Explorer\iexplore.exe"); 

2.

public static string FindFileInPath(string name) 
{ 
    foreach (string path in Environment.ExpandEnvironmentVariables("%path%").Split(';')) 
    { 
     string filename; 
     if (File.Exists(filename = Path.Combine(path, name))) 
     { 
      return filename; // returns the absolute path if the file exists 
     } 
    } 
    return null; // will return null if it didn't find anything 
} 

3.

Process.Start("D:\\test.html"); 

Вы хотите поместить свой код в примерочных улове блоков, а так Process.Start будет сгенерировано исключение, если файл не существует.

Редактировать: Обновлен код, благодаря Dan Field, указав, что я пропустил смысл вопроса. :/

+0

Первые два примера хороши, но он не хочет на самом деле запускать программу, он просто хочет путь. Ваш третий пример не получит его. –

+0

Спасибо за ваш ответ, хотя я использовал ответ wgrahams, мне все еще нужна часть FindFileInPath. Однако есть небольшая ошибка, поэтому метод должен искать рекурсивно для исполняемого файла. В противном случае, большое спасибо :) –

0

Ваши первые два примера не должны быть слишком сложными, чтобы выяснить, используя Environment.ExpandEnvironmentVariables. Последний из них является более жестким - лучше всего использовать PInvoke для вызова AssocCreate. Адаптированные страницы PInvoke (http://www.pinvoke.net/default.aspx/shlwapi/AssocCreate.html):

public static class GetDefaultProgramHelper 
{ 
    public unsafe static string GetDefaultProgram(string ext) 
    { 
     try 
     { 
      object obj; 
      AssocCreate(
      ref CLSID_QueryAssociations, 
      ref IID_IQueryAssociations, 
      out obj); 
      IQueryAssociations qa = (IQueryAssociations)obj; 
      qa.Init(
      ASSOCF.INIT_DEFAULTTOSTAR, 
      ext, //".doc", 
      UIntPtr.Zero, IntPtr.Zero); 

      int size = 0; 
      qa.GetString(ASSOCF.NOTRUNCATE, ASSOCSTR.COMMAND, 
      "open", null, ref size); 

      StringBuilder sb = new StringBuilder(size); 
      qa.GetString(ASSOCF.NOTRUNCATE, ASSOCSTR.COMMAND, 
      "open", sb, ref size); 

      //Console.WriteLine(".doc is opened by : {0}", sb.ToString()); 
      return sb.ToString(); 
     } 
     catch(Exception e) 
     { 
      if((uint)Marshal.GetHRForException(e) == 0x80070483) 
      //Console.WriteLine("No command line is associated to .doc open verb."); 
      return null; 
      else 
      throw; 
     } 
    } 

    [DllImport("shlwapi.dll")] 
    extern static int AssocCreate(
     ref Guid clsid, 
     ref Guid riid, 
     [MarshalAs(UnmanagedType.Interface)] out object ppv); 

    [Flags] 
    enum ASSOCF 
    { 
     INIT_NOREMAPCLSID = 0x00000001, 
     INIT_BYEXENAME = 0x00000002, 
     OPEN_BYEXENAME = 0x00000002, 
     INIT_DEFAULTTOSTAR = 0x00000004, 
     INIT_DEFAULTTOFOLDER = 0x00000008, 
     NOUSERSETTINGS = 0x00000010, 
     NOTRUNCATE = 0x00000020, 
     VERIFY = 0x00000040, 
     REMAPRUNDLL = 0x00000080, 
     NOFIXUPS = 0x00000100, 
     IGNOREBASECLASS = 0x00000200, 
     INIT_IGNOREUNKNOWN = 0x00000400 
    } 

    enum ASSOCSTR 
    { 
     COMMAND = 1, 
     EXECUTABLE, 
     FRIENDLYDOCNAME, 
     FRIENDLYAPPNAME, 
     NOOPEN, 
     SHELLNEWVALUE, 
     DDECOMMAND, 
     DDEIFEXEC, 
     DDEAPPLICATION, 
     DDETOPIC, 
     INFOTIP, 
     QUICKTIP, 
     TILEINFO, 
     CONTENTTYPE, 
     DEFAULTICON, 
     SHELLEXTENSION 
    } 

    enum ASSOCKEY 
    { 
     SHELLEXECCLASS = 1, 
     APP, 
     CLASS, 
     BASECLASS 
    } 

    enum ASSOCDATA 
    { 
     MSIDESCRIPTOR = 1, 
     NOACTIVATEHANDLER, 
     QUERYCLASSSTORE, 
     HASPERUSERASSOC, 
     EDITFLAGS, 
     VALUE 
    } 

    [Guid("c46ca590-3c3f-11d2-bee6-0000f805ca57"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
    interface IQueryAssociations 
    { 
     void Init(
     [In] ASSOCF flags, 
     [In, MarshalAs(UnmanagedType.LPWStr)] string pszAssoc, 
     [In] UIntPtr hkProgid, 
     [In] IntPtr hwnd); 

     void GetString(
     [In] ASSOCF flags, 
     [In] ASSOCSTR str, 
     [In, MarshalAs(UnmanagedType.LPWStr)] string pwszExtra, 
     [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszOut, 
     [In, Out] ref int pcchOut); 

     void GetKey(
     [In] ASSOCF flags, 
     [In] ASSOCKEY str, 
     [In, MarshalAs(UnmanagedType.LPWStr)] string pwszExtra, 
     [Out] out UIntPtr phkeyOut); 

     void GetData(
     [In] ASSOCF flags, 
     [In] ASSOCDATA data, 
     [In, MarshalAs(UnmanagedType.LPWStr)] string pwszExtra, 
     [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] out byte[] pvOut, 
     [In, Out] ref int pcbOut); 

     void GetEnum(); // not used actually 
    } 

    static Guid CLSID_QueryAssociations = new Guid("a07034fd-6caa-4954-ac3f-97a27216f98a"); 
    static Guid IID_IQueryAssociations = new Guid("c46ca590-3c3f-11d2-bee6-0000f805ca57"); 

} 

Вы могли бы назвать это с помощью string filePathToProgram = GetDefaultProgramHelper.GetDefaultProgram(".docx");

Смежные вопросы