1

I have a solution with two projects, a master and a slave. Both these projects are WinForms Applications. There's always one instance of the master running and multiple instances of the slaves. The slaves are started by the master. Right now I have the executable name of the slave hardcoded into the master's code, which works fine. However, I want to be able to get the executable name of the slave without hardcoding it, but by getting it through its reference. Is this possible, and how should I go about doing this?

This is what I currently have:

ProcessStartInfo startInfo = new ProcessStartInfo("Slave.exe") { Arguments = Args };
Process.Start(startInfo);

But I would like to replace "Slave.exe" with something dynamical. I have added an assembly reference to the slave project, having namespace Slave.

Bart van der Drift
  • 1,287
  • 12
  • 30
  • What reference are you referring to? A name is a reference, too. – MicroVirus Sep 03 '14 at 09:59
  • 1
    I mean a project reference as in project > references > Add reference – Bart van der Drift Sep 03 '14 at 10:04
  • I think you can place all the slave exe names/path in a config file. And according to your logic at the time of starting slave process you can start any one of it from the config file. and your method which starts the process will have the string parameter of your slave exe.name/path – kishore V M Sep 03 '14 at 10:07
  • @BartvanderDrift that's an assembly reference. And it's purpose is to "project" assembly's types to your code. – Eldar Dordzhiev Sep 03 '14 at 10:07
  • What about custom assembly attributes? [Custom Assembly Attributes](http://stackoverflow.com/questions/1936953/custom-assembly-attributes) or [.Net 4 - Include custom information in assembly](http://stackoverflow.com/questions/6354852/net-4-include-custom-information-in-assembly) – Leon Pro Sep 03 '14 at 10:25
  • @kishoreVM: Actually, that is what I have right now. In my question I use a simplification, but I want something more dynamical. – Bart van der Drift Sep 03 '14 at 10:50
  • @LeonPro: That is possible, but it would also still be a form of hard coding, would it not? I would only move the code to another assembly. – Bart van der Drift Sep 03 '14 at 10:51
  • 1
    You could generate your config file dynamically in a pre/post build event. – Postlagerkarte Sep 03 '14 at 10:59
  • Use your `appdomain.currentdomain` - you can discover references, etc – T.S. Sep 03 '14 at 13:38

1 Answers1

0

Thanks to @Postlagerkarte's suggestion, I solved my problem by using post build events. I have 4 different slave processes, let's call them SlaveProcessA to SlaveProcessD. First thing I did was make a class which can hold the executable names, and (de)serialize them:

public class ExeNames {
    [XmlIgnore]
    public bool IsLoaded {get; private set;}
    [XmlIgnore]
    const string Filename = "exenames.xml";
    public string SlaveAExe {get; set;}
    public string SlaveBExe {get; set;}
    public string SlaveDExe {get; set;}
    public string SlaveCExe {get; set;}

    public void Load() {
      var serializer = new XmlSerializer(typeof(ExeNames));
      using (StreamReader reader = new StreamReader(Filename)) {
        ExeNames End = serializer.Deserialize(reader) as ExeNames;
        if (End == null) return;
        SlaveAExe = End.SlaveAExe;
        SlaveBExe = End.SlaveBExe;
        SlaveDExe = End.SlaveDExe;
        SlaveCExe = End.SlaveCExe;
        IsLoaded = true;
      }
    }

    public void Save() {
      var serializer = new XmlSerializer(typeof(ExeNames));
      using (StreamWriter writer = new StreamWriter(Filename)) {
        serializer.Serialize(writer, this);
      }
    }
  }

After that, I created a new project called ExeNameSaver. This program takes 2 parameters: the code of the process, and the executable name:

namespace ExeNameSaver {
  class Program {
    static void Main(string[] args) {
      if (args.Length < 2) throw new ArgumentException("2 Parameters are required");
      var Code = args[0];
      var Exe = args[1];
      ExeNames.ExeNames Exn = new ExeNames.ExeNames();
      try {
        Exn.Load();
      }
      catch {
        Console.WriteLine("Starting new file...");
      }
      switch (Code) {
        case "SlaveA":
          Exn.SlaveAExe = Exe;
          break;
        case "SlaveB":
          Exn.SlaveBExe = Exe;
          break;
        case "SlaveC":
          Exn.SlaveCExe = Exe;
          break;
        case "SlaveD":
          Exn.SlaveDExe = Exe;
          break;
        default:
          Console.WriteLine("Invalid process code: " + Code);
          break;
      }
      Exn.Save();
    }
  }
}

Then, I make sure that the ExeNameSaver is built first by altering the dependencies. Now I can use the ExeNameSaver program to save my executable names to an XML-file, by putting the following in the Post-build event command line of SlaveProcessA:

$(OutDir)ExeNameSaver.exe SlaveA $(TargetFileName)

And similarly for the other 3 slaves.

$(OutDir)ExeNameSaver.exe SlaveB $(TargetFileName)

...

$(OutDir)ExeNameSaver.exe SlaveC $(TargetFileName)

...

$(OutDir)ExeNameSaver.exe SlaveD $(TargetFileName)

Now after each build, the exenames.xml file will contain the executable names of my 4 processes. I can then load this XML using the same ExeNames class in my master program and use their names from there.

Bart van der Drift
  • 1,287
  • 12
  • 30