33

I have a .NET class library that has a class with a static method. I want my code to run that static method in a separate process - the same way I'd run it in a separate thread just in a separate process.

I know I can create a separate console application project call the static method from inside Main() but that's not convenient for my deployment scenario - I'd rather not carry an extra .exe file around. I know I can use Powershell to invoke it but that would mean being dependent on Powershell which I'd rather avoid.

Is there a way to run code in a separate process using .NET only? Maybe I could create the executable for that separate process during runtime?

Community
  • 1
  • 1
sharptooth
  • 167,383
  • 100
  • 513
  • 979
  • Can you use a command line option to your existing app? – Gabe Oct 18 '12 at 10:29
  • Why do you need to do this? Should the process keep running once the initial one has finished? – Ash Burlaczenko Oct 18 '12 at 10:31
  • @Gabe: Nope, my current code is a class library loaded into a surrogate. – sharptooth Oct 18 '12 at 10:32
  • @Ash Burlaczenko: I want that separate process to run code that may hang - if that happens I can kill the process. I don't need it to run longer that the process with my initial code. – sharptooth Oct 18 '12 at 10:34
  • 5
    Would it not make sense then just to create a new app domain to run the task, and tear that down on failure, rather than launching a whole new process? – Fergus Bown Oct 18 '12 at 10:36
  • @Fergus Bown: I dunno. Will that reliably guard against code running an infinite loop? – sharptooth Oct 18 '12 at 10:45
  • Yes it will. AppDomains are bullet-proof against managed code issues. The only thing you can't protect yourself from is that you cannot tear down an AppDomain that gets stuck in a call to unmanaged code. – David Pfeffer Oct 18 '12 at 11:18
  • 1
    If it's a thread with no calls to unmanaged code then you don't have to mess with an appdomain - if the thread hangs you can kill it. – Onkelborg Oct 18 '12 at 11:23
  • @DavidPfeffer - This is not true. AppDomains will separate only data, but code is shared. If there is an unhandled exception in any domain than the whole application will crash. – Ondra Oct 18 '12 at 11:36
  • @OndraMorský Yes, but this question is about freezes/hang-ups, and not unhandled exceptions. It is true that you need to try..catch any call into the AppDomain to avoid a bubbled-up exception from crashing the main domain. – David Pfeffer Oct 18 '12 at 11:44

1 Answers1

30

Unfortunately, you cannot fork in C# like you can in C on POSIX-compatible operating systems.

You have a few options. Since you're just looking to protect against infinite loops, you could just spawn a new Thread (a new one, not a ThreadPool one or a Task one). Then, you can call Abort on the thread if you need to kill it. This will trigger a ThreadAbortException in the other thread.

Your other option is an AppDomain. You can create a new AppDomain using the currently running assembly relatively trivially. Then, you make a call into a proxy object that actually exists across the domain. The proxy will use old-school .NET remoting to call the method on the real object (so no generic-passing, etc., since you're limited by .NET 1.1-based constructs).

Be aware that none of the above strategies will protect you from a crash in unmanaged code. Since AppDomains are a managed construct, you cannot use them to abort unmanaged hang-ups.

If you're really, really, really determined to get a second OS-level process, you can also generate a new executable assembly in a temporary file on the fly and start that in a new process. See here for an MSDN article on new assembly generation. Be aware that this is not trivial at all.

Community
  • 1
  • 1
David Pfeffer
  • 38,869
  • 30
  • 127
  • 202
  • 6
    +1 for the terrifying idea of generating assemblies on the fly to run in a separate process. – Paul Turner Oct 18 '12 at 11:37
  • @sharptooth Does this answer the question? – David Pfeffer Nov 03 '12 at 20:37
  • 3
    Well, I've found this great answer http://stackoverflow.com/a/826435/57428 about how to craft the console application at runtime. That isn't hard at all. – sharptooth Jan 14 '13 at 13:10
  • 1
    I know this is really old and am trying to solve this same problem but now in .NET Core. That example you linked to does not start a new process and I believe that was one of your requirements? – CarCar Oct 18 '21 at 15:45