Why does a process started in dll work when tested

2019-06-17 08:38发布

问题:

Last week I posted this question: How can I obtain console application output when running it as a process in a C# dll 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 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. 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.

Does anyone know why it would 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?

EDIT: 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 app it returns 0.

EDIT: 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 app and the real world use. I found differences but I am not sure what to make of them.

Working console test app:

-       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    

Another EDIT: 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 dlls, though according to dependency walker these are all found.

回答1:

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 apps first line. This will allow you to attach the debugger after it is invoked and then you can observe the behaviour.



回答2:

I would start with a "Hello, world!" console app and debug the process stuff separately from your real app. That might help you nail down what is causing the return code (ie. your calling code, or the console app).



回答3:

It works when run from a console app, but fails when run from a DLL running from a different program. To me, it sounds like a problem with security context. Your console app may be running with higher privileges than the other program.