2010-10-29 4 views
5

Я пытаюсь запустить приложение (операционная система, мое приложение и приложение, которое я хочу запустить, все 32 бита), из .NET 3.51.Проблема запуска System.Diagnostics.Process под Windows 7

Код, запускающий Process, используется для других приложений, но есть тот, который дает нам головную боль. Если мы «дважды щелкнем» по значку приложения, он работает так, как ожидалось, что означает, что он отлично работает как приложение на компьютере. Двойной щелчок .exe напрямую, также работает.

Операционная система - Windows 7 32Bits (домашний и/или профессиональный).

Приложение .NET скомпилировано с помощью x86, чтобы избежать проблем.

Код, который запускает «Процессы», находится внутри DLL (также 32 бита), выполненного нами, в основном это простая DLL, которая содержит некоторый «Общий код» по всем направлениям, общие методы, функции и все, что мы используем во всем наш код. Один из этих методов выглядит следующим образом:

public static bool FireUpProcess(Process process, string path, bool enableRaisingEvents, 
     ProcessWindowStyle windowStyle, string arguments) 
    { 
     if (process != null) 
     { 
      try 
      { 
       process.StartInfo.FileName = @path; 
       if (arguments != null) 
       { 
        if (arguments != String.Empty) 
        { 
         process.StartInfo.Arguments = arguments; 
        } 
       } 
       process.StartInfo.WindowStyle = windowStyle; 
       process.EnableRaisingEvents = enableRaisingEvents; 
       process.Start(); 
      } 
      catch 
      { 
       try 
       { 
        process.Kill(); 
       } 
       catch (InvalidOperationException) 
       { 
       } // The process is not even created 

       return false; 
      } 
     } 
     else 
     { 
      return false; 
     } 
     return true; 
    } 

Я не знаю, кто написал этот метод, но он работает в течение примерно шести лет с различными приложениями, поэтому я предполагаю, что это «нормально». Тем не менее, у нас есть клиент с программным обеспечением, которое не будет запускаться при передаче этого аргумента.

Аргументы:

  1. процесс является System.Diagnostics.Process создан с помощью простого «нового процесса();»
  2. путь полный путь к. ехе. «C: /path/to/my.exe»
  3. enableRaisingEvents ложна
  4. windowStyle Максимизирован (но попробовал другие).

Это дает crappy MessageBox ... который я счастливо увековечил. Это на испанском языке, но перевод должен быть легким:

alt text

Он говорит:

Ошибка приложения непредвиденное исключение произошло за программу (0x0eedfade) в ...

погуглить что 0x0eedfade дает странные результаты, которые выглядят страшно, но, по правде говоря, если я иду в .exe, который я пытаюсь запустить и дважды щелкнуть по нему, он отлично работает.

For The Record: Если я пытаюсь запустить другие вещи (т.е .: notepad.exe, Adobe Acrobat Reader) он работает, но Firefox не открывается и не показывает ошибку.

Такое поведение «некоторая работа, некоторые из них» приводит меня к мысли, что может возникнуть проблема с механизмом безопасности Windows 7 или подобным, который я не знаю.

Что мне не хватает или что-то не так?

ОБНОВЛЕНИЕ: Хорошо; У меня есть копия программного обеспечения. Это грязное программное обеспечение, но оно работает. Теперь, когда я могу отлаживать, я вижу, что программа запускает мой метод FireUpProcess.

Как предложил я добавил код WorkingDirectory, но вот код:

public static bool FireUpProcess(Process process, string path, bool enableRaisingEvents, ProcessWindowStyle windowStyle) 
    { 
     if (process != null) 
     { 
      try 
      { 
       if (!String.IsNullOrEmpty(@path)) 
       { 
        process.StartInfo.FileName = @path; 
        process.StartInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(@path); 
        process.StartInfo.WindowStyle = windowStyle; 
        // Suscribe to the exit notification 
        process.EnableRaisingEvents = enableRaisingEvents; 
        // Disable to prevent multiple launchs 
        Framework.Check.LogWarning("LAUNCHING EXTERNAL DEVICE WITH PATH: " + path); 
        process.Start(); // HERE The program reports the following: 

alt text

Это означает, что «Программа не может быть запущена, поскольку ddip.dll отсутствует ... попробуйте переустановить бла бла ».

Дело в том, если я исполню же @Path из командной строки, программа открывает совершенно:

alt text

Это открывает программу. И то же самое происходит, если я нажму на «ярлык», который находится в меню «программы». В этом ярлыке нет никаких параметров, это простой вызов исполняемого файла.

Вопрос: В чем разница между моим кодом и другими методами?

Должно быть что-то другое, что заставляет мой процесс не запускаться.

Любые идеи?

ОБНОВЛЕНИЕ И РЕШЕНИЕ

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

Я добавил приложение к нашим приложениям (должно было быть, это было с возраста перспективы, не знаю, почему его там не было на первом месте). Я продемонстрировал приложение, добавленное с помощью приложения VStudio 2008 add file -> application manifest.

В этом, я уверен, у нас есть это:

<requestedExecutionLevel level=“asInvoker” uiAccess=“false” /> 

Нам не нужно администратора или что-нибудь подобное, но, видимо, Vista/7 нужно знать это.

После этого процесс запускается правильно.

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

+0

Я знаю, это не вопрос, но вы можете упростить 'if' to' if (! String.IsNullOrEmpty (arguments)) '. SCNR – Bobby

+0

Что такое 'DBSWIN.EXE'? По многим сайтам это может быть проблемой с расширением третьей стороны для IE ... может ли ПК быть заражен? – Bobby

+0

@Bobby DBSWIN.EXE является частью программного обеспечения, которое эти парни используют: http://www.duerrdental.de/en/home-dd/ (это на самом деле: http://www.duerrdental.de/en/products/ imaging/dbswin-imaging-software /) –

ответ

5

Если exe имеет манифест, перед вызовом Start вы должны установить UseShellExecute в true для объекта процесса. В любом случае это неплохая идея.

+0

@ Kate вы могли бы указать мне на более «расширенное» объяснение об этом? Благодарю. –

+0

Ответы на http://stackoverflow.com/questions/3224804/ начинаются ... –

+0

@Kate Большое спасибо. –

8

Вы не устанавливаете свойство process.StartInfo.WorkingDirectory. Там много плохо написанного программного обеспечения, которое предполагает, что рабочий каталог будет каталогом, в котором хранится EXE.По крайней мере, добавьте эту строку:

process.StartInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(@path); 

Исключение, однако, довольно странно. Я определенно рекомендую вам сообщить клиенту обновить свои средства защиты от вредоносных программ.

+0

спасибо, попробуем это. –

+0

К сожалению, это ничего не изменило (но я все равно оставлю его в коде). Мы загружаем последнюю версию программного обеспечения, чтобы увидеть, если это произойдет там. –

+0

Hmya, сосредоточиться на последнем абзаце в моем ответе. Вы видели хиты google. –

1

У меня были подобные проблемы в прошлом. Я решил его, выполнив CMD приложение следующим образом:

public static bool FireUpProcess(Process process, string path, bool enableRaisingEvents, ProcessWindowStyle windowStyle) 
{ 
    //if path contains " ", surround it with quotes. 
    //add /c and the path as parameters to the cmd process. 
    //Any other parameters can be added after the path. 

    ProcessStartInfo psi = new ProcessStartInfo("cmd", "/c" + path));    
    psi.WorkingDirectory = System.IO.Path.GetDirectoryName(@path);   
    psi.WindowStyle = windowStyle;   
    // Suscribe to the exit notification   
    process.EnableRaisingEvents = enableRaisingEvents;   
    // Disable to prevent multiple launchs   
    Framework.Check.LogWarning("LAUNCHING EXTERNAL DEVICE WITH PATH: " + path);   
    process.Start(); ...} 
+1

Я не уверен, как это поможет вам устранить неполадки, но вам нужно добавить пробел после «/ c». Также необходимо назначить объект psi для обработки объекта, чтобы он имел какой-либо эффект. –

1

Если это возможно, я хотел бы попробовать использовать Process Monitor от Sysinternals. При запуске вы можете отменить выбор реестра и сетевой активности на панели инструментов (5 значков с правой стороны). Затем вы видите активность процесса и диска. Поскольку это выглядит как проблема с файлом, вы должны использовать диалог «Фильтр» (значок слева слева), выберите «Имя процесса» в раскрывающемся списке (по умолчанию «Архитектура») и введите имя неудачного исполняемого файла. Это значительно ограничит захваченный вывод, чтобы вы могли видеть, что происходит. Затем запустите exectuable и проверьте в столбце результата результат NAME NOT FOUND. Это места, где был обыскан файл, но не найден. Если вы знаете оскорбительное имя dll, вы можете найти его с помощью Ctrl + F, как обычно, чтобы выкопать его. Затем вы можете сравнить различные пути поиска от своего рабочего приложения и когда он был запущен из вашего приложения.

Может ли быть, что переменная окружения PATH имеет другое значение внутри вашего процесса? Может быть, это добавление. (текущий каталог) помогает исправить путь поиска dll. Или приложение запускается из другой учетной записи пользователя? Это также может быть новая функция, когда приложение устанавливает файлы в Programm Files, но не имеет прав (только администратор может это сделать). Windows перенаправит записи в профиль пользователя. Это безопасный и прозрачный способ обеспечения большей безопасности. Но это может вызвать, например, во время первого запуска приложения некоторые, например, файл конфигурации, который будет развернут в профиль «Администраторы», когда он запускает приложение не с согласия диалогового окна UAC. Затем другие пользователи могут также запускать приложение, но сбой, потому что дополнительный файл конфигурации находится в профиле Администраторы, а не в Program Files, как ожидалось для всех.

3

Как заметила Кейт Грегори, если вы хотите «подражать» пользователю, дважды щелкнув по значку, у вас есть, чтобы установить UseShellExecute в true. Установка этих флагов позволяет использовать код совершенно другого пути, используя базовые окна ShellExecute.

Теперь, я добавлю к этому, что, если вы работаете на UAC оборудованного Windows (Vista, 7, 2008, ...) Вы, возможно, должны также попытаться использовать RUNAS глагола, как описано here и here.

С .NET, который был бы:

if (System.Environment.OSVersion.Version.Major >= 6) // UAC's around... 
{ 
    processStartInfo.Verb = "runas"; 
} 
+0

спасибо за информацию, она обязательно сохранит ее. Обратите внимание: согласно MSDN, UseShellExecute по умолчанию является истинным. –

0

Я считаю, что Ганс Passant находится на правильном пути. В дополнение к тому, что он сказал, проверьте, чтобы ddip.dll и exe находились в одном каталоге. Это не всегда так, как есть other ways для привязки сборок вне корзины. А именно, событие GAC и AssemblyResolve. Учитывая вашу ситуацию, я не вижу причин, по которым задействован ПКК. Проверьте код exe, который запускается для любых крючков в событие AssemblyResolve. Если он подключен, вам может потребоваться обновить реализацию, чтобы разрешить запуск другого процесса.

Поскольку вы получаете исключение из-за недостающей библиотеки DLL, я не уверен в ответах на проблемы с разделителями путей. Тем не менее, у вас есть код приложения, поэтому убедитесь, что он ссылается на ddip.dll. Это даст вам большую уверенность в том, что вы на самом деле ссылаетесь на правильный .exe, и поэтому это не просто проблема с разделителем пути с командной строкой (E.G. misinterpreted spaces).

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