2

I'm creating a C# app that should use lpr.exe and pass arguments to it. I'm currently trying to do it this way:

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

But whenever I get to a.Start(); I get an unhandled Win32 exception which states "The system cannot find the file specified". This is really confusing me becuase, at first I thought it was my arguments, but turns out, I can pass the exact same arguments from a VB app and get it to work.

Update 1:

The VB code that works is:

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()

What's more is that my issue doesn't seem to be with the arguments statement, as I can comment it out and I still receive the error.

Update 2:

The error I get at the start of the process is: The system cannot find the file specified. I do not get the error if I change the FileName to "C:\Windows\System32\cmd.exe", that works fine...

Ben
  • 704
  • 4
  • 10
  • 25
  • 1
    This smells like permissions issues... Is your c# app running with full trust? Also, is the other app VB classic or VB.NET? – RQDQ Sep 24 '12 at 19:05
  • The same trust as my VB app. And how do I discern whether it is classic or .NET? (I feel rather inept asking) – Ben Sep 24 '12 at 19:13
  • 1
    If you're using Visual Studio 2008/2010/2012, the other app is vb.net. You would have to use the old 32 bit VB5 / 6 compiler that doesn't even run on Vista or above. Oh - and show us your vb code then! – RQDQ Sep 24 '12 at 19:14
  • I've updated my question. And I'm definitely **not** using VB classic :P – Ben Sep 24 '12 at 19:20
  • 1
    The code is different... In the VB version, you're just concatenating the string filename into the .Arguments property. In the C# version you're concatenating filePathDirectory, which is not the same. – RQDQ Sep 24 '12 at 19:25
  • I have no idea, and had no clue that doing so would cause problems. But using a string of the same path doesn't solve my problem... – Ben Sep 24 '12 at 19:27
  • Have you compared the values for .Arguments in the debugger? – RQDQ Sep 24 '12 at 19:29
  • Try setting a breakpoint before calling a.Start(), and check the contents of a.StartInfo.Arguments. Make sure the arguments are what you expect. – Mike Payne Sep 24 '12 at 19:30
  • I used Console.WriteLine to confirm that both produce the same arguments. Altough, hovering over the .Arguments while debugging will show more backslashes than the VB version. As I found out in an earlier question: http://stackoverflow.com/questions/12531976/concatenate-string-literals-with-directoryinfo-enumeration-and-adding-quotation – Ben Sep 24 '12 at 19:32

2 Answers2

2

You are using a DirectoryInfo object in your c# code and concetanate it. Try to change your code to this:

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

EDIT

Found the solution to your problem! First - credits go to @Sundeep according to his given answer. He pointet me to a webSite indicating that

Yes I have, but 64-bit files located in c:\windows\system32 is not seen by a 32-bit command prompt (c:\windows\syswow64\cmd.exe) which is launched when call at batch file from a 32-bit application.

And furthermore

... trying to get a 32 bit program to launch lpr.exe inside of Windows 2008 R2. It fails because lpr.exe does not exist in the 32 bit view of the O/S. ...

For a work-around, I copied lpr*.* from a 32 bit O/S system32 folder into SYSWOW64 on the 2008 R2 machine...

Community
  • 1
  • 1
Pilgerstorfer Franz
  • 8,303
  • 3
  • 41
  • 54
  • This did not solve my problem. What's more is that I can remove the arguments statement, and I still get an error when 'a.Start();' occurs – Ben Sep 24 '12 at 21:00
  • added try catch block. pls provide **which kind of exception** has been thrown and **what error message** you got! – Pilgerstorfer Franz Sep 24 '12 at 21:05
  • can you do this ? use C:\Windows\System32\lpr.exe in run and check if that works or not. I know I sound stupid but can you check this and let me know – Pradip Sep 24 '12 at 21:08
  • I don't have a `c:\windows\System32\lpr.exe` file on my computer! won't work.. What execption do you get? – Pilgerstorfer Franz Sep 25 '12 at 04:47
  • @PilgerstorferFranz I will set up a try catch block as soon as I can. Also, I had to enable lpr services on my machine to get lpr.exe. – Ben Sep 25 '12 at 13:25
  • @Pradie Yes, I can run C:\Windows\System32\lpr.exe, even from the command line. – Ben Sep 25 '12 at 13:25
  • @PilgerstorferFranz I got the old "The system canoot find the file specified" error. Keep in mind, I get this error whether or not the Arguments line is in place or not. – Ben Sep 25 '12 at 14:45
  • I posted an answer to this question even though it is very old, as, although PlgestorgerFranz's answer is correct, a better workaround is available: use the sysnative virtual directory, instead of copying the system32 file to the syswow64 directory. – omrsafetyo Sep 15 '15 at 19:04
1

Change your code to this:

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' explanation is exactly right, but especially in an environment like mine, going and moving the location of the lpr.exe on every machine is a lot of work. The simple solution is to use the sysnative directory.

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

The 'Sysnative' folder is invisible in Windows Explorer If you start Windows Explorer and open the Windows folder on your hard disk, you may notice that the Sysnative folder is not shown. The main reason to this is that Windows Explorer is a 64-bit program (when run in a 64-bit Windows), and the Sysnative folder is only visible and accessible from 32-bit software. If 64-bit software need access to the 64-bit system folder in Windows, the only option is to use the System32 folder name (for example: C:\Windows\System32).

Using the 'Sysnative' folder will help you access 64-bit tools from 32-bit code Some tools in a 64-bit Windows only exist in a 64-bit version; there is no 32-bit version available. And some of these tools are located in the 64-bit System32 folder. One example is the nbtstat tool that is used to help troubleshoot NetBIOS name resolution problems. If you try to run the nbtstat tool from 32-bit code (for example from an application or from script) and use a path like C:\Windows\System32, you will get a "File not found" error. The file can not be found; although Windows Explorer shows that the nbtstat program file actually is located in the C:\Windows\System32 folder.
The solution to this (somewhat confusing) problem is to include the virtual Sysnative folder in the folder path when you want to run the tool. For example like this: C:\Windows\Sysnative\nbtstat.exe The file path above will give you access to the 64-bit nbtstat tool from a 32-bit application or from a 32-bit script. We recommend you to read this article / blog post (at Scottie’s Tech.Info) to get more details about this.

omrsafetyo
  • 310
  • 2
  • 7