1010import java .nio .file .Files ;
1111import java .nio .file .Path ;
1212import java .nio .file .Paths ;
13+ import java .util .Arrays ;
1314import java .util .List ;
1415
1516/** Utility class for using external programs.
@@ -83,13 +84,17 @@ public static void showStringInPager(String string, String filename) {
8384 public static void showFileInPager (Path file ) {
8485 String pager = System .getenv ("PAGER" );
8586 if (pager == null ) {
86- if (System . getProperty ( "os.name" ). toLowerCase (). contains ( "windows" )) {
87+ if (EnvironmentUtil . isWindows ( )) {
8788 pager = "more" ;
8889 } else {
8990 pager = "less -R" ;
9091 }
9192 }
92- execExternal (pager , file .toString (), true );
93+ if (EnvironmentUtil .isWindows ()) {
94+ execExternal (new String []{"cmd.exe" , "/c" , pager , file .toString ()}, true );
95+ } else {
96+ execExternal (pager , file .toString (), true );
97+ }
9398 }
9499
95100 public static void runUpdater (Io io , String pathToNewBinary ) {
@@ -128,29 +133,50 @@ public static void openInBrowser(URI uri) {
128133 }
129134
130135 private static boolean execExternal (String program , String arg , boolean wait ) {
131- return execExternal (program + " \' " + arg + " \' " , wait );
136+ return execExternal (new String []{ program , arg } , wait );
132137 }
133138
134139 private static boolean execExternal (String program , boolean wait ) {
135- logger .info ("Launching external program " + program );
136- String [] exec ;
140+ return execExternal (new String []{program }, wait );
141+ }
142+
143+ private static boolean execExternal (String [] args , boolean wait ) {
137144 if (EnvironmentUtil .isWindows ()) {
138- exec = new String []{program };
145+ logger .info ("Launching external program " + Arrays .toString (args ));
146+ try {
147+ Process proc = new ProcessBuilder (args ).start ();
148+ if (wait ) {
149+ logger .info ("Waiting for " + Arrays .toString (args ) + " to finish executing" );
150+ proc .waitFor ();
151+ }
152+ } catch (Exception e ) {
153+ logger .error ("(Windows) Exception when running external program "
154+ + Arrays .toString (args ), e );
155+ return false ;
156+ }
139157 } else {
140- exec = new String []{
141- "sh" , "-c" , program + " </dev/tty >/dev/tty" };
142- }
143- try {
144- Process proc = Runtime .getRuntime ().exec (exec );
145- if (wait ) {
146- logger .info ("Waiting for " + program + " to finish executing" );
147- proc .waitFor ();
158+
159+ String [] exec = new String [args .length + 3 ];
160+ exec [0 ] = "sh" ;
161+ exec [1 ] = "-c" ;
162+ for (int i = 0 ; i < args .length ; i ++) {
163+ exec [2 + i ] = args [i ];
164+ }
165+ exec [args .length + 2 ] = " </dev/tty >/dev/tty" ;
166+ try {
167+ Process proc = Runtime .getRuntime ().exec (exec );
168+ if (wait ) {
169+ logger .info ("Waiting for " + Arrays .toString (exec ) + " to finish executing" );
170+ proc .waitFor ();
171+ }
172+ return proc .exitValue () == 0 ;
173+ } catch (Exception e ) {
174+ logger .error ("(Unix) Exception when running external program "
175+ + Arrays .toString (exec ), e );
176+ return false ;
148177 }
149- return proc .exitValue () == 0 ;
150- } catch (Exception e ) {
151- logger .error ("Exception when running external program " + program , e );
152- return false ;
153178 }
179+ return false ;
154180 }
155181
156182 /**
@@ -160,6 +186,9 @@ private static boolean execExternal(String program, boolean wait) {
160186 * @return: Whether or not writing was successful
161187 */
162188 private static boolean writeToFile (Path path , String string ) {
189+ if (EnvironmentUtil .isWindows ()) {
190+ string = string .replace ("\n " , "\r \n " );
191+ }
163192 try {
164193 if (path .getParent () != null && !Files .exists (path .getParent ())) {
165194 Files .createDirectories (path .getParent ());
0 commit comments