2

I know this may seem to be a duplicated question but I highly doubt it. I am currently making a Windows Form application where the user can select an XSD file using the OpenFileDialog

Once the XSD is uploaded/selected I want it to create a .cs file from it using the default developer XSD tool.

But for some reason, it just opens the selected XSD file in notepad(?)

I've tried to comment the code to give it some sense.

 //Filter only .xsd files
            ofd.Filter = "XSD|*.xsd";
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                //Read file name
                string File = ofd.FileName;
                string z = ofd.InitialDirectory;
                //Start making commands for in the CMD 
                //Change directory to the folder where the Dev Command prompt is located
                string changeDirectory = @"cd C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\";
                //Open the Dev CMD
                string bat = "VsDevCmd";
                //Change folder to our test folder 
                string cd = @"cd C:\Users\Pierre\Desktop\testxsd";
                //execute xsd /c *selected file* /c is used to create the .cs file.
                string command = @"xsd /c " + File;
                //Combine the commands into 1 line.
                string x = cd + "&" + command;
                string xyz = changeDirectory + "&" + bat + "&" + x;
                //print the outcome -> When I copy paste this into CMD the .cs file is generated

                Console.WriteLine(xyz);
                ProcessStartInfo oInfo = new ProcessStartInfo(Environment.ExpandEnvironmentVariables(@"C:\WINDOWS\system32\cmd.exe"), xyz);
                oInfo.UseShellExecute = false;
                oInfo.ErrorDialog = false;
                oInfo.CreateNoWindow = true;
                oInfo.RedirectStandardOutput = true;
                try
                {
                    Process p = System.Diagnostics.Process.Start(oInfo);
                    System.IO.StreamReader oReader2 = p.StandardOutput;
                    string sRes = oReader2.ReadToEnd();
                    oReader2.Close();
                    // sRes now contains the output from xsd.exe     
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }

So, as you can see in the comments, when I copy paste the console.writeline(xyz) into CMD it got properly executed and the .cs file is generated as it should.

However, when I just launch this code it opens the selected xsd in notepad. Literally no idea what could be wrong

Falcon
  • 837
  • 1
  • 9
  • 28

2 Answers2

2

You are kind of taking the very long panoramic route when there is actually a very quick one... As @PatrickHofman stated in the comments use xsd directly...

To do this, open the Visual Studio command prompt, and write where xsd to find exact path of xsd executable.

Then start a process using xsd from the path you found and the various options ie. /c and filename.

using System.Diagnostics;
...
FileInfo fi = new FileInfo(ofd.FileName);
Process process = new Process();
process.StartInfo.FileName = xsdPath;
process.StartInfo.Arguments = "/c " + fi.FullName;
process.StartInfo.WorkingDirectory = fi.DirectoryName;
process.Start();
//wait for exit if needed...
process.WaitForExit();

If for some reason this is not working, capture the output from the command by doing this before process.Start():

process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.OutputDataReceived += 
(sender, args) => Console.WriteLine("received output: {0}", args.Data);
process.BeginOutputReadLine();
Leo
  • 5,013
  • 1
  • 28
  • 65
  • 1
    Don't forget to escape `File`. – Patrick Hofman Sep 14 '18 at 12:20
  • Process.start() should have the path to the xsd + argument? right? – Falcon Sep 14 '18 at 12:22
  • 1
    erm... `process.StartInfo.Arguments = "/c " + fi.FullName;` – Leo Sep 14 '18 at 12:23
  • I think the problem is that this is not correct: `var xsd = @"C:\Program Files(x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\xsd.exe";` which I got from the `where xsd` Do I have to trim the white space between Prgram Files(x86) – Falcon Sep 14 '18 at 12:25
  • uhm that doesn't seems right can't compile that. but wait I will check the console. – Falcon Sep 14 '18 at 12:34
  • string value: "C:\\Program Files(x86)\\Microsoft SDKs\\Windows\\v10.0A\\bin\\NETFX 4.6.1 Tools\\xsd.exe" error: System.ComponentModel.Win32Exception: 'The system cannot find the file specified' – Falcon Sep 14 '18 at 12:35
  • what does `where xsd` return? do you get multiple values? – Leo Sep 14 '18 at 12:37
  • I checked the path again and copy pasted it from the file explorer directly. seems to work! +++ – Falcon Sep 14 '18 at 12:38
0

I think you should use the XmlSchemaClassGenerator package for this (Nuget). That way you wont have to do all the process juggling yourself.

Example from GitHub readme:

var generator = new Generator
{
    OutputFolder = outputFolder,
    Log = s => Console.Out.WriteLine(s),
    GenerateNullables = true,
    NamespaceProvider = new Dictionary<NamespaceKey, string> 
        { 
            { new NamespaceKey("http://wadl.dev.java.net/2009/02"), "Wadl" } 
        }
        .ToNamespaceProvider(new GeneratorConfiguration { NamespacePrefix = "Wadl" }.NamespaceProvider.GenerateNamespace)
};

generator.Generate(files);
wanton
  • 271
  • 1
  • 9