7

Last week I posted the question How can I obtain console application output when running it as a process in a C# DLL file? as I was trying to find out the cause of a problem I was having. However, I have not been able to find the reason I was getting an error, so I thought I would ask a follow up that is directly about the problem I am having.

I am working on method in a DLL file and I have to start a process in it. The code used to do this is:

ProcessStartInfo psi = new ProcessStartInfo();
psi.UseShellExecute = false;
psi.ErrorDialog = false;
psi.RedirectStandardError = true;
psi.RedirectStandardOutput = true;
psi.RedirectStandardInput = true;
psi.CreateNoWindow = true;
psi.FileName = @"C:\Program Files\OpenMS-1.6\XTandemAdapter.exe";
psi.Arguments = @"-ini C:\XTandemAdapter.ini";

Process getIDs = new Process();
getIDs.StartInfo = psi;
getIDs.Start();
StreamWriter inputWriter = getIDs.StandardInput;
StreamReader outputReader = getIDs.StandardOutput;
StreamReader errorReader = getIDs.StandardError;
getIDs.WaitForExit();
System.Diagnostics.EventLog.WriteEntry("FMANWiff", "ID output: " + outputReader.ReadToEnd());
System.Diagnostics.EventLog.WriteEntry("FMANWiff", "ID error: " + errorReader.ReadToEnd());

The application XTandemAdapter.exe is normally run as a console application and the FileName and Arguments are meant to reproduce this format:

XtandemAdapter.exe -ini XTandemAdapter.ini

I have a console test application that calls my method in this DLL file. When I use this I am able to see the results of the redirect of standoutput and I can see that the process executed successfully (the executable that is called also produces an XML file as output and I can see that this was created). However, the normal mode of operation has a application call a method in a DLL which in turn ends up calling mine. When I run it this way I can see that the process was created by looking in the task manager, but it quickly exits and there is no output to the eventlog and no output file is created by the executable that was run.

Why would it run properly in one case, but not in another? Is something done differently when called via console application vs. being called by a method in a DLL file?

I noticed that the Exitcode returned by the process is Exitcode: -529697949 so I guess something is going wrong within the process. I will take a look at the code for xtandemadapter and try to figure out where this is coming from. When I run it from the console application it returns 0.

When I added the debugger break statement, I ended up stepping through the method and watched the value of the process objects, both when using the console test application and the real world use. I found differences, but I am not sure what to make of them.

Working console test application:

-       getIDs  {System.Diagnostics.Process (XTandemAdapter)}   System.Diagnostics.Process
+       base    {System.Diagnostics.Process (XTandemAdapter)}   System.ComponentModel.Component {System.Diagnostics.Process}
        BasePriority    8   int
        EnableRaisingEvents false   bool
        ExitCode    9   int
+       ExitTime    {10/4/2011 1:21:33 AM}  System.DateTime
+       Handle  1036    System.IntPtr
        HandleCount 53  int
        HasExited   true    bool
        Id  2732    int
        MachineName "." string
+       MainModule  'getIDs.MainModule' threw an exception of type 'System.ComponentModel.Win32Exception'   System.Diagnostics.ProcessModule {System.ComponentModel.Win32Exception}
+       MainWindowHandle    0   System.IntPtr
        MainWindowTitle ""  string
+       MaxWorkingSet   'getIDs.MaxWorkingSet' threw an exception of type 'System.InvalidOperationException'    System.IntPtr {System.InvalidOperationException}
+       MinWorkingSet   'getIDs.MinWorkingSet' threw an exception of type 'System.InvalidOperationException'    System.IntPtr {System.InvalidOperationException}
+       Modules 'getIDs.Modules' threw an exception of type 'System.ComponentModel.Win32Exception'  System.Diagnostics.ProcessModuleCollection {System.ComponentModel.Win32Exception}
        NonpagedSystemMemorySize    3240    int
        NonpagedSystemMemorySize64  3240    long
        PagedMemorySize 3010560 int
        PagedMemorySize64   3010560 long
        PagedSystemMemorySize   120196  int
        PagedSystemMemorySize64 120196  long
        PeakPagedMemorySize 3010560 int
        PeakPagedMemorySize64   3010560 long
        PeakVirtualMemorySize   137424896   int
        PeakVirtualMemorySize64 137424896   long
        PeakWorkingSet  9064448 int
        PeakWorkingSet64    9064448 long
+       PriorityBoostEnabled    'getIDs.PriorityBoostEnabled' threw an exception of type 'System.InvalidOperationException' bool {System.InvalidOperationException}
+       PriorityClass   'getIDs.PriorityClass' threw an exception of type 'System.InvalidOperationException'    System.Diagnostics.ProcessPriorityClass {System.InvalidOperationException}
        PrivateMemorySize   3010560 int
        PrivateMemorySize64 3010560 long
+       PrivilegedProcessorTime {00:00:00.0937500}  System.TimeSpan
        ProcessName "XTandemAdapter"    string
+       ProcessorAffinity   'getIDs.ProcessorAffinity' threw an exception of type 'System.InvalidOperationException'    System.IntPtr {System.InvalidOperationException}
        Responding  true    bool
        SessionId   0   int
+       StandardError   {System.IO.StreamReader}    System.IO.StreamReader
+       StandardInput   {System.IO.StreamWriter}    System.IO.StreamWriter
+       StandardOutput  {System.IO.StreamReader}    System.IO.StreamReader
+       StartInfo   {System.Diagnostics.ProcessStartInfo}   System.Diagnostics.ProcessStartInfo
+       StartTime   {10/4/2011 1:21:32 AM}  System.DateTime
        SynchronizingObject null    System.ComponentModel.ISynchronizeInvoke
+       Threads {System.Diagnostics.ProcessThreadCollection}    System.Diagnostics.ProcessThreadCollection
+       TotalProcessorTime  {00:00:00.8125000}  System.TimeSpan
+       UserProcessorTime   {00:00:00.7187500}  System.TimeSpan
        VirtualMemorySize   132001792   int
        VirtualMemorySize64 132001792   long
        WorkingSet  9064448 int
        WorkingSet64    9064448 long
+       Static members      
+       Non-Public members      

When I call the dll as I expect to and when it does not work:

-       getIDs  {System.Diagnostics.Process}    System.Diagnostics.Process
+       base    {System.Diagnostics.Process}    System.ComponentModel.Component {System.Diagnostics.Process}
+       BasePriority    'getIDs.BasePriority' threw an exception of type 'System.InvalidOperationException' int {System.InvalidOperationException}
        EnableRaisingEvents false   bool
        ExitCode    -529697949  int
+       ExitTime    {10/4/2011 1:03:09 AM}  System.DateTime
+       Handle  4176    System.IntPtr
+       HandleCount 'getIDs.HandleCount' threw an exception of type 'System.InvalidOperationException'  int {System.InvalidOperationException}
        HasExited   true    bool
        Id  596 int
        MachineName "." string
-       MainModule  'getIDs.MainModule' threw an exception of type 'System.ComponentModel.Win32Exception'   System.Diagnostics.ProcessModule {System.ComponentModel.Win32Exception}
+       base    {"Access is denied"}    System.Runtime.InteropServices.ExternalException {System.ComponentModel.Win32Exception}
        NativeErrorCode 5   int
+       Non-Public members      
-       MainWindowHandle    'getIDs.MainWindowHandle' threw an exception of type 'System.InvalidOperationException' System.IntPtr {System.InvalidOperationException}
+       base    {"Process has exited, so the requested information is not available."}  System.SystemException {System.InvalidOperationException}
+       MainWindowTitle 'getIDs.MainWindowTitle' threw an exception of type 'System.InvalidOperationException'  string {System.InvalidOperationException}
+       MaxWorkingSet   'getIDs.MaxWorkingSet' threw an exception of type 'System.InvalidOperationException'    System.IntPtr {System.InvalidOperationException}
+       MinWorkingSet   'getIDs.MinWorkingSet' threw an exception of type 'System.InvalidOperationException'    System.IntPtr {System.InvalidOperationException}
+       Modules 'getIDs.Modules' threw an exception of type 'System.ComponentModel.Win32Exception'  System.Diagnostics.ProcessModuleCollection {System.ComponentModel.Win32Exception}
+       NonpagedSystemMemorySize    'getIDs.NonpagedSystemMemorySize' threw an exception of type 'System.InvalidOperationException' int {System.InvalidOperationException}
+       NonpagedSystemMemorySize64  'getIDs.NonpagedSystemMemorySize64' threw an exception of type 'System.InvalidOperationException'   long {System.InvalidOperationException}
+       PagedMemorySize 'getIDs.PagedMemorySize' threw an exception of type 'System.InvalidOperationException'  int {System.InvalidOperationException}
+       PagedMemorySize64   'getIDs.PagedMemorySize64' threw an exception of type 'System.InvalidOperationException'    long {System.InvalidOperationException}
+       PagedSystemMemorySize   'getIDs.PagedSystemMemorySize' threw an exception of type 'System.InvalidOperationException'    int {System.InvalidOperationException}
+       PagedSystemMemorySize64 'getIDs.PagedSystemMemorySize64' threw an exception of type 'System.InvalidOperationException'  long {System.InvalidOperationException}
+       PeakPagedMemorySize 'getIDs.PeakPagedMemorySize' threw an exception of type 'System.InvalidOperationException'  int {System.InvalidOperationException}
+       PeakPagedMemorySize64   'getIDs.PeakPagedMemorySize64' threw an exception of type 'System.InvalidOperationException'    long {System.InvalidOperationException}
+       PeakVirtualMemorySize   'getIDs.PeakVirtualMemorySize' threw an exception of type 'System.InvalidOperationException'    int {System.InvalidOperationException}
+       PeakVirtualMemorySize64 'getIDs.PeakVirtualMemorySize64' threw an exception of type 'System.InvalidOperationException'  long {System.InvalidOperationException}
+       PeakWorkingSet  'getIDs.PeakWorkingSet' threw an exception of type 'System.InvalidOperationException'   int {System.InvalidOperationException}
+       PeakWorkingSet64    'getIDs.PeakWorkingSet64' threw an exception of type 'System.InvalidOperationException' long {System.InvalidOperationException}
+       PriorityBoostEnabled    'getIDs.PriorityBoostEnabled' threw an exception of type 'System.InvalidOperationException' bool {System.InvalidOperationException}
+       PriorityClass   'getIDs.PriorityClass' threw an exception of type 'System.InvalidOperationException'    System.Diagnostics.ProcessPriorityClass {System.InvalidOperationException}
+       PrivateMemorySize   'getIDs.PrivateMemorySize' threw an exception of type 'System.InvalidOperationException'    int {System.InvalidOperationException}
+       PrivateMemorySize64 'getIDs.PrivateMemorySize64' threw an exception of type 'System.InvalidOperationException'  long {System.InvalidOperationException}
+       PrivilegedProcessorTime {00:00:00.0468750}  System.TimeSpan
+       ProcessName 'getIDs.ProcessName' threw an exception of type 'System.InvalidOperationException'  string {System.InvalidOperationException}
+       ProcessorAffinity   'getIDs.ProcessorAffinity' threw an exception of type 'System.InvalidOperationException'    System.IntPtr {System.InvalidOperationException}
+       Responding  'getIDs.Responding' threw an exception of type 'System.InvalidOperationException'   bool {System.InvalidOperationException}
+       SessionId   'getIDs.SessionId' threw an exception of type 'System.InvalidOperationException'    int {System.InvalidOperationException}
+       StandardError   {System.IO.StreamReader}    System.IO.StreamReader
+       StandardInput   {System.IO.StreamWriter}    System.IO.StreamWriter
+       StandardOutput  {System.IO.StreamReader}    System.IO.StreamReader
+       StartInfo   {System.Diagnostics.ProcessStartInfo}   System.Diagnostics.ProcessStartInfo
+       StartTime   {10/4/2011 1:03:09 AM}  System.DateTime
        SynchronizingObject null    System.ComponentModel.ISynchronizeInvoke
+       Threads 'getIDs.Threads' threw an exception of type 'System.InvalidOperationException'  System.Diagnostics.ProcessThreadCollection {System.InvalidOperationException}
+       TotalProcessorTime  {00:00:00.0781250}  System.TimeSpan
+       UserProcessorTime   {00:00:00.0312500}  System.TimeSpan
+       VirtualMemorySize   'getIDs.VirtualMemorySize' threw an exception of type 'System.InvalidOperationException'    int {System.InvalidOperationException}
+       VirtualMemorySize64 'getIDs.VirtualMemorySize64' threw an exception of type 'System.InvalidOperationException'  long {System.InvalidOperationException}
+       WorkingSet  'getIDs.WorkingSet' threw an exception of type 'System.InvalidOperationException'   int {System.InvalidOperationException}
+       WorkingSet64    'getIDs.WorkingSet64' threw an exception of type 'System.InvalidOperationException' long {System.InvalidOperationException}
+       Static members  System.Diagnostics.Process  System.Diagnostics.Process
+       Non-Public members  {System.Diagnostics.Process}    System.Diagnostics.Process
        'getIDs.MainModule' threw an exception of type 'System.ComponentModel.Win32Exception'   Too many characters in character literal    

I found that I was getting this error in the system event viewer. I had not noticed it until now.

"Application popup: XTandemAdapter.exe - Application Error : The application failed to initialize properly (0xe06d7363). Click on OK to terminate the application."

Does this help anyone understand the problem? I should note, the executable does need to make use of a few DLL files, though according to dependency walker these are all found.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Travis
  • 659
  • 13
  • 28
  • Since it is second request for help, +1 to get it noticed. – Adnan Bhatti Sep 26 '11 at 01:39
  • I think `XTandemAdapter.exe` decided to stop the program for some reason in your DLL case. We don't know why it stops the program exactly but some common reasons can be there is no permissions for XTandemAdapter.exe to write to ini file or the ini file already exists, etc. – Harvey Kwok Sep 26 '11 at 01:46
  • Actually, it just uses the ini file to get settings for the execution of XtandemAdapter. It defines the input and output files, and some parameters for the program it wraps around, XTandem! – Travis Sep 26 '11 at 01:51
  • Could this be a 64-bit 32-bit problem? I think if you start a new process where UseShellExecute is false the new process must run with the same architecture as the parent process. So if XTandemAdapter.exe is a 32-bit executable and your console test application is also running as 32-bit there is no problem. But if the other exe where you are having the problem is running under 64-bit it could result in the problem you're having. But then you probably wouldn't see it in the Task Manager at all... – Stefan Podskubka Sep 28 '11 at 17:40
  • Both are 32-bit architectures so sadly this is probably not the problem. I have not had a lot of time in the lab to test this so sadly I have yet to solve it...but hopefully this weekend I can. – Travis Sep 30 '11 at 21:14
  • I am starting to wonder if this could be some sort of problem with the executable. I replaced the executable I start with ipconfig.exe and ran my code with it. This generated output and the exit code was 0. However, when I use the application I want to use the error code is -529697949. I have not been able to find much about this other than these posts: http://tinyurl.com/5rf5zkd and http://tinyurl.com/6gyjsv2 but they have not been much help. The process seems to fail without it even entering the application. I modified it to print output to a file and there is never any output. – Travis Oct 04 '11 at 03:36
  • A quick web search shows that 0xe06d7363 is the code for an unhandled C++ exception. You should be able to attach a Just-in-time debugger to see who is throwing the exception. – Raymond Chen Oct 13 '11 at 04:04
  • 1
    In the end I found that it was related to the processes not being able to find a DLL they depend on. For some reason it was not a problem when using the test application. But I added the directory to the path and it worked. – Travis Nov 20 '11 at 18:23
  • 2
    @Travis: would you mind putting that last comment on an answer and accept it? When someone's looking for unanswered questions, it's not very efficient to go all the way through this issue only to find out in a buried comment that it's already solved. Time spent by people reading this could otherwise be used on answering the questions that aren't yet solved ;) – Edurne Pascual Mar 10 '12 at 20:58

3 Answers3

0

Why you aren't getting an event logged is far more interesting though. I suggest that you put a System.Diagnostics.Debugger.Break(); in your application's first line. This will allow you to attach the debugger after it is invoked and then you can observe the behaviour.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Spence
  • 28,526
  • 15
  • 68
  • 103
  • Oh, I think I might have been a bit misleading or I am not reading your message correctly. I do get an event log entry but there is simply no output, the entry will just say: "ID: " – Travis Sep 26 '11 at 01:53
  • Also, the documentation says "You must set UseShellExecute to false if you want to set RedirectStandardOutput to true. Otherwise, reading from the StandardOutput stream throws an exception.", so I do not think I can set shell execute to true and ever hope to get standard out. – Travis Sep 26 '11 at 01:56
  • Fail. But my second comment still holds. Sorry long day. – Spence Sep 26 '11 at 03:25
  • No problem, I understand completely. I will give it a try tomorrow when I am in the lab. – Travis Sep 26 '11 at 05:23
0

I would start with a "Hello, World!!" console application and debug the process stuff separately from your real application.

That might help you nail down what is causing the return code (i.e., your calling code, or the console application).

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
dviljoen
  • 1,612
  • 1
  • 16
  • 28
0

It works when run from a console application, but it fails when run from a DLL file running from a different program.

To me, it sounds like a problem with security context. Your console application may be running with higher privileges than the other program.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Derreck Dean
  • 3,708
  • 1
  • 26
  • 45