33
44using System ;
55using System . IO ;
6+ using System . Linq ;
67using System . Runtime . InteropServices ;
78using System . Text ;
9+ using System . Xml . Linq ;
810using Microsoft . DotNet . Cli . Utils ;
911using Microsoft . DotNet . Tools ;
1012using Microsoft . Extensions . EnvironmentAbstractions ;
@@ -13,34 +15,57 @@ namespace Microsoft.DotNet.ShellShim
1315{
1416 public class ShellShimMaker
1517 {
18+ private const string LauncherExeNet45ResourceName = "Microsoft.DotNet.Tools.Launcher.Executable.Net45" ;
19+ private const string LauncherExeNet35ResourceName = "Microsoft.DotNet.Tools.Launcher.Executable.Net35" ;
20+ private const string LauncherConfigNet45ResourceName = "Microsoft.DotNet.Tools.Launcher.Config.Net45" ;
21+ private const string LauncherConfigNet35ResourceName = "Microsoft.DotNet.Tools.Launcher.Config.Net35" ;
22+
23+ private readonly string _launcherExeResourceName ;
24+ private readonly string _launcherConfigResourceName ;
1625 private readonly string _pathToPlaceShim ;
1726
1827 public ShellShimMaker ( string pathToPlaceShim )
1928 {
2029 _pathToPlaceShim =
2130 pathToPlaceShim ?? throw new ArgumentNullException ( nameof ( pathToPlaceShim ) ) ;
31+
32+ if ( OSVersionUtil . IsWindows8OrNewer ( ) )
33+ {
34+ _launcherExeResourceName = LauncherExeNet45ResourceName ;
35+ _launcherConfigResourceName = LauncherConfigNet45ResourceName ;
36+ }
37+ else
38+ {
39+ _launcherExeResourceName = LauncherExeNet35ResourceName ;
40+ _launcherConfigResourceName = LauncherConfigNet35ResourceName ;
41+ }
2242 }
2343
2444 public void CreateShim ( string packageExecutablePath , string shellCommandName )
2545 {
26- var packageExecutable = new FilePath ( packageExecutablePath ) ;
46+ FilePath shimPath = GetShimPath ( shellCommandName ) ;
2747
28- var script = new StringBuilder ( ) ;
2948 if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) )
3049 {
31- script . AppendLine ( "@echo off" ) ;
32- script . AppendLine ( $ "dotnet { packageExecutable . ToQuotedString ( ) } %*") ;
50+ CreateConfigFile ( shimPath . Value + ".config" , entryPoint : packageExecutablePath , runner : "dotnet" ) ;
51+ using ( var shim = File . Create ( shimPath . Value ) )
52+ using ( var exe = typeof ( ShellShimMaker ) . Assembly . GetManifestResourceStream ( _launcherExeResourceName ) )
53+ {
54+ exe . CopyTo ( shim ) ;
55+ }
3356 }
3457 else
3558 {
59+ var packageExecutable = new FilePath ( packageExecutablePath ) ;
60+
61+ var script = new StringBuilder ( ) ;
3662 script . AppendLine ( "#!/bin/sh" ) ;
3763 script . AppendLine ( $ "dotnet { packageExecutable . ToQuotedString ( ) } \" $@\" ") ;
38- }
3964
40- FilePath scriptPath = GetScriptPath ( shellCommandName ) ;
41- File . WriteAllText ( scriptPath . Value , script . ToString ( ) ) ;
65+ File . WriteAllText ( shimPath . Value , script . ToString ( ) ) ;
4266
43- SetUserExecutionPermissionToShimFile ( scriptPath ) ;
67+ SetUserExecutionPermissionToShimFile ( shimPath ) ;
68+ }
4469 }
4570
4671 public void EnsureCommandNameUniqueness ( string shellCommandName )
@@ -53,28 +78,43 @@ public void EnsureCommandNameUniqueness(string shellCommandName)
5378 }
5479 }
5580
81+ internal void CreateConfigFile ( string outputPath , string entryPoint , string runner )
82+ {
83+ XDocument config ;
84+ using ( var resource = typeof ( ShellShimMaker ) . Assembly . GetManifestResourceStream ( _launcherConfigResourceName ) )
85+ {
86+ config = XDocument . Load ( resource ) ;
87+ }
88+
89+ var appSettings = config . Descendants ( "appSettings" ) . First ( ) ;
90+ appSettings . Add ( new XElement ( "add" , new XAttribute ( "key" , "entryPoint" ) , new XAttribute ( "value" , entryPoint ) ) ) ;
91+ appSettings . Add ( new XElement ( "add" , new XAttribute ( "key" , "runner" ) , new XAttribute ( "value" , runner ?? string . Empty ) ) ) ;
92+ config . Save ( outputPath ) ;
93+ }
94+
5695 public void Remove ( string shellCommandName )
5796 {
58- File . Delete ( GetScriptPath ( shellCommandName ) . Value ) ;
97+ File . Delete ( GetShimPath ( shellCommandName ) . Value ) ;
5998 }
6099
61- private FilePath GetScriptPath ( string shellCommandName )
100+ private FilePath GetShimPath ( string shellCommandName )
62101 {
63102 var scriptPath = Path . Combine ( _pathToPlaceShim , shellCommandName ) ;
64103 if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) )
65104 {
66- scriptPath += ".cmd " ;
105+ scriptPath += ".exe " ;
67106 }
68107
69108 return new FilePath ( scriptPath ) ;
70109 }
71110
72111 private static void SetUserExecutionPermissionToShimFile ( FilePath scriptPath )
73112 {
74- if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) ) return ;
113+ if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) )
114+ return ;
75115
76116 CommandResult result = new CommandFactory ( )
77- . Create ( "chmod" , new [ ] { "u+x" , scriptPath . Value } )
117+ . Create ( "chmod" , new [ ] { "u+x" , scriptPath . Value } )
78118 . CaptureStdOut ( )
79119 . CaptureStdErr ( )
80120 . Execute ( ) ;
0 commit comments