aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core.Native/WixNativeExe.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/WixToolset.Core.Native/WixNativeExe.cs115
1 files changed, 115 insertions, 0 deletions
diff --git a/src/WixToolset.Core.Native/WixNativeExe.cs b/src/WixToolset.Core.Native/WixNativeExe.cs
new file mode 100644
index 00000000..8626bea3
--- /dev/null
+++ b/src/WixToolset.Core.Native/WixNativeExe.cs
@@ -0,0 +1,115 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.Core.Native
4{
5 using System;
6 using System.Collections.Generic;
7 using System.ComponentModel;
8 using System.Diagnostics;
9 using System.IO;
10 using System.Reflection;
11
12 internal class WixNativeExe
13 {
14 private const int FiveMinutesInMilliseconds = 300000;
15 private static readonly string PathToWixNativeExe;
16
17 private readonly string commandLine;
18 private readonly List<string> stdinLines = new List<string>();
19
20 static WixNativeExe()
21 {
22 PathToWixNativeExe = Path.Combine(Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath), "x86\\wixnative.exe");
23 }
24
25 public WixNativeExe(params object[] args)
26 {
27 this.commandLine = String.Join(" ", QuoteArgumentsAsNecesary(args));
28 }
29
30 public void AddStdinLine(string line)
31 {
32 this.stdinLines.Add(line);
33 }
34
35 public void AddStdinLines(IEnumerable<string> lines)
36 {
37 this.stdinLines.AddRange(lines);
38 }
39
40 public IEnumerable<string> Run()
41 {
42 var wixNativeInfo = new ProcessStartInfo(PathToWixNativeExe, this.commandLine)
43 {
44 RedirectStandardInput = true,
45 RedirectStandardOutput = true,
46 CreateNoWindow = true,
47 ErrorDialog = false,
48 UseShellExecute = false
49 };
50
51 var stdoutLines = new List<string>();
52
53 using (var process = Process.Start(wixNativeInfo))
54 {
55 process.OutputDataReceived += (s, a) => stdoutLines.Add(a.Data);
56 process.BeginOutputReadLine();
57
58 if (this.stdinLines.Count > 0)
59 {
60 foreach (var line in this.stdinLines)
61 {
62 process.StandardInput.WriteLine(line);
63 }
64
65 // Trailing blank line indicates stdin complete.
66 process.StandardInput.WriteLine();
67 }
68
69 if (process.WaitForExit(FiveMinutesInMilliseconds))
70 {
71 // If the process successfully exits documentation says we need to wait again
72 // without a timeout to ensure that all of the redirected output is captured.
73 //
74 process.WaitForExit();
75 }
76
77 if (process.ExitCode != 0)
78 {
79 throw new Win32Exception(process.ExitCode);
80 }
81 }
82
83 return stdoutLines;
84 }
85
86 private static IEnumerable<string> QuoteArgumentsAsNecesary(object[] args)
87 {
88 foreach (var arg in args)
89 {
90 if (arg is string str)
91 {
92 if (String.IsNullOrEmpty(str))
93 {
94 }
95 else if (str.Contains(" ") && !str.StartsWith("\""))
96 {
97 yield return $"\"{str}\"";
98 }
99 else
100 {
101 yield return str;
102 }
103 }
104 else if (arg is int i)
105 {
106 yield return i.ToString();
107 }
108 else
109 {
110 throw new ArgumentException(nameof(args));
111 }
112 }
113 }
114 }
115}