Необработанное исключение C# во время процесса LPR

Я создаю приложение C#, которое должно использовать lpr.exe и передавать ему аргументы. В настоящее время я пытаюсь сделать это следующим образом:

DirectoryInfo filePathDirectory = new DirectoryInfo(filePath);              
Process a = new Process();
a.StartInfo.FileName = @"C:\Windows\System32\lpr.exe";
a.StartInfo.Arguments = "-SServerName.Domain.net -Plp " + "\"" + filePathDirectory + "\"";
a.StartInfo.UseShellExecute = false;
a.Start();
a.WaitForExit();

Но всякий раз, когда я добираюсь до a.Start();, я получаю необработанное исключение Win32, в котором говорится: «Система не может найти указанный файл». Это действительно сбивает меня с толку, потому что сначала я подумал, что это мои аргументы, но оказалось, что я могу передать точно такие же аргументы из приложения VB и заставить его работать.

Обновление 1:

Код VB, который работает:

Dim RPname As String
RPname = FileName.ToString
Dim a As New Process
a.StartInfo.FileName = "C:\Windows\system32\lpr.exe"
a.StartInfo.Arguments = "-SServerName.Domain.net -Plp " & Chr(34) & RPname & Chr(34)
a.StartInfo.UseShellExecute = False
a.Start()
a.WaitForExit()

Более того, моя проблема, похоже, не связана с оператором arguments, поскольку я могу прокомментировать его, но все равно получаю сообщение об ошибке.

Обновление 2:

Ошибка, которую я получаю в начале процесса: Система не может найти указанный файл. Я не получаю сообщение об ошибке, если изменяю имя файла на "C:\Windows\System32\cmd.exe". ", работает нормально...


person Ben    schedule 24.09.2012    source источник
comment
Это пахнет проблемами с разрешениями... Ваше приложение С# работает с полным доверием? Кроме того, другое приложение VB classic или VB.NET?   -  person RQDQ    schedule 24.09.2012
comment
То же доверие, что и мое приложение VB. И как мне определить, классический это или .NET? (я чувствую себя довольно неуместным спрашивать)   -  person Ben    schedule 24.09.2012
comment
Если вы используете Visual Studio 2008/2010/2012, другим приложением будет vb.net. Вам придется использовать старый 32-битный компилятор VB5/6, который даже не работает в Vista или выше. О, и покажи нам тогда свой vb-код!   -  person RQDQ    schedule 24.09.2012
comment
Я обновил свой вопрос. И я определенно не использую VB classic :P   -  person Ben    schedule 24.09.2012
comment
Код отличается... В версии VB вы просто объединяете строковое имя файла со свойством .Arguments. В версии C# вы объединяете filePathDirectory, что не одно и то же.   -  person RQDQ    schedule 24.09.2012
comment
Я понятия не имею и понятия не имел, что это вызовет проблемы. Но использование строки того же пути не решает мою проблему...   -  person Ben    schedule 24.09.2012
comment
Вы сравнивали значения .Arguments в отладчике?   -  person RQDQ    schedule 24.09.2012
comment
Попробуйте установить точку останова перед вызовом a.Start() и проверьте содержимое a.StartInfo.Arguments. Убедитесь, что аргументы соответствуют вашим ожиданиям.   -  person Mike Payne    schedule 24.09.2012
comment
Я использовал Console.WriteLine, чтобы убедиться, что оба они производят одни и те же аргументы. Однако при наведении указателя мыши на .Arguments во время отладки будет отображаться больше обратных косых черт, чем в версии VB. Как я узнал из предыдущего вопроса: stackoverflow.com/questions/12531976/   -  person Ben    schedule 24.09.2012


Ответы (2)


Вы используете DirectoryInfo объект в вашем коде С# и объедините его. Попробуйте изменить свой код на это:

try
{
  DirectoryInfo filePathDirectory = new DirectoryInfo(filePath);              
  Process a = new Process();
  a.StartInfo.FileName = @"C:\Windows\syswow64\lpr.exe";  // ADAPTED to the new path!! worked!
  // use filePathDirectory.FullName!!
  a.StartInfo.Arguments = "-SServerName.Domain.net -Plp " + "\"" + filePathDirectory.FullName + "\"";
  // or change it to - found it more readable imo
  a.StartInfo.Arguments = string.Format(
                               "-SServerName.Domain.net -Plp \"{0}\"", 
                               filePathDirectory.FullName);
  a.StartInfo.UseShellExecute = false;
  a.Start();
  a.WaitForExit();
} 
catch (Exception ex)
{
  Debug.WriteLine(ex.Message);
}

ИЗМЕНИТЬ

Нашли решение вашей проблемы! Во-первых, кредиты идут @Sundeep в соответствии с его данный ответ. Он указал мне на веб-сайт указывая, что

Да, есть, но 64-разрядные файлы, расположенные в папке c:\windows\system32, не видны 32-разрядной командной строке (c:\windows\syswow64\cmd .exe), который запускается при вызове командного файла из 32-битного приложения.

И, кроме того

... пытаюсь получить 32-битную программу для запуска lpr.exe в Windows 2008 R2. Это не удается, потому что lpr.exe не существует в 32-битном представлении операционной системы. ...

В качестве обходного пути я скопировал lpr*.* из папки system32 32-битной операционной системы в SYSWOW64 на машине 2008 R2...

person Pilgerstorfer Franz    schedule 24.09.2012
comment
Это не решило мою проблему. Более того, я могу удалить оператор arguments, но все равно получаю сообщение об ошибке, когда 'a.Start();' имеет место - person Ben; 25.09.2012
comment
добавлен блок try catch. пожалуйста, предоставьте какое исключение было выдано и какое сообщение об ошибке вы получили! - person Pilgerstorfer Franz; 25.09.2012
comment
можешь так сделать ? используйте C:\Windows\System32\lpr.exe при запуске и проверьте, работает ли это или нет. Я знаю, что звучу глупо, но не могли бы вы проверить это и дайте мне знать? - person Pradip; 25.09.2012
comment
У меня нет файла c:\windows\System32\lpr.exe на моем компьютере! не сработает .. Какое исключение вы получаете? - person Pilgerstorfer Franz; 25.09.2012
comment
@PilgerstorferFranz Я настрою блок try catch, как только смогу. Кроме того, мне пришлось включить службы lpr на моей машине, чтобы получить lpr.exe. - person Ben; 25.09.2012
comment
@Pradie Да, я могу запустить C:\Windows\System32\lpr.exe даже из командной строки. - person Ben; 25.09.2012
comment
@PilgerstorferFranz Я получил старую ошибку. Система не может найти указанный файл. Имейте в виду, я получаю эту ошибку независимо от того, находится ли строка Arguments на месте или нет. - person Ben; 25.09.2012
comment
Я опубликовал ответ на этот вопрос, хотя он очень старый, поскольку, хотя ответ PlgestorgerFranz верен, доступен лучший обходной путь: используйте виртуальный каталог sysnative вместо копирования файла system32 в каталог syswow64. - person omrsafetyo; 15.09.2015

Измените свой код на это:

DirectoryInfo filePathDirectory = new DirectoryInfo(filePath);              
Process a = new Process();
a.StartInfo.FileName = @"C:\Windows\Sysnative\lpr.exe";
a.StartInfo.Arguments = "-SServerName.Domain.net -Plp " + "\"" + filePathDirectory + "\"";
a.StartInfo.UseShellExecute = false;
a.Start();
a.WaitForExit();

Объяснение Pilgerstorfer Franz абсолютно правильное, но особенно в такой среде, как моя, переход и перемещение местоположения lpr.exe на каждой машине требует большой работы. Простое решение — использовать каталог sysnative.

http://www.samlogic.net/articles/sysnative-folder-64-bit-windows.htm

Папка «Sysnative» невидима в проводнике Windows. Если вы запустите проводник Windows и откроете папку Windows на жестком диске, вы можете заметить, что папка Sysnative не отображается. Основная причина этого заключается в том, что Windows Explorer является 64-битной программой (при запуске в 64-битной Windows), а папка Sysnative видна и доступна только из 32-битного программного обеспечения. Если 64-разрядному программному обеспечению требуется доступ к 64-разрядной системной папке в Windows, единственным вариантом является использование имени папки System32 (например: C:\Windows\System32).

Использование папки «Sysnative» поможет вам получить доступ к 64-битным инструментам из 32-битного кода. Некоторые инструменты в 64-битной Windows существуют только в 64-битной версии; нет 32-битной версии. И некоторые из этих инструментов находятся в папке 64-битной системы System32. Одним из примеров является средство nbtstat, которое используется для устранения проблем с разрешением имен NetBIOS. Если вы попытаетесь запустить инструмент nbtstat из 32-битного кода (например, из приложения или из скрипта) и использовать путь, например C:\Windows\System32, вы получите ошибку «Файл не найден». Файл не может быть найден; хотя Проводник Windows показывает, что файл программы nbtstat на самом деле находится в папке C:\Windows\System32.
Решение этой (несколько запутанной) проблемы состоит в том, чтобы включить виртуальную папку Sysnative в путь к папке, когда вы хотите запустить инструмент. Например, так: C:\Windows\Sysnative\nbtstat.exe Указанный выше путь к файлу даст вам доступ к 64-разрядному инструменту nbtstat из 32-разрядного приложения или 32-разрядного сценария. Мы рекомендуем вам прочитать эту статью / сообщение в блоге (на Scottie’s Tech.Info), чтобы получить более подробную информацию об этом.

person omrsafetyo    schedule 15.09.2015