Pārlūkot izejas kodu

Calling directly into Win API to get current process exe

On Windows the MonoToolsLocator tries to determine which mono.exe
to use by looking at the current process. Due to problems with
AppDomains and shadow copying (which happens in System.Web) we
could not use this approach. Instead we now call GetModuleFileName
directly using p-invoke to get the exe file of the running process.
This is only used when running on Windows.
Henric Müller 9 gadi atpakaļ
vecāks
revīzija
33263bd790

+ 1 - 1
mcs/class/System.Web/System.Web.dll.sources

@@ -2,7 +2,7 @@ Assembly/AssemblyInfo.cs
 ../../build/common/Consts.cs
 ../../build/common/Locale.cs
 ../../build/common/MonoTODOAttribute.cs
-../System/System/MonoExeLocator.cs
+../System/System/MonoToolsLocator.cs
 ../System.Windows.Forms/System.Resources/AssemblyNamesTypeResolutionService.cs
 ../System.Windows.Forms/System.Resources/ByteArrayFromResXHandler.cs
 ../System.Windows.Forms/System.Resources/ResXNullRef.cs

+ 1 - 1
mcs/class/System.Windows.Forms/System.Windows.Forms.dll.sources

@@ -2,7 +2,7 @@
 ../../build/common/MonoTODOAttribute.cs
 Assembly/AssemblyInfo.cs
 Assembly/Locale.cs
-../System/System/MonoExeLocator.cs
+../System/System/MonoToolsLocator.cs
 System.Resources/AssemblyNamesTypeResolutionService.cs
 System.Resources/ByteArrayFromResXHandler.cs
 System.Resources/ResXNullRef.cs

+ 1 - 1
mcs/class/System/System.dll.sources

@@ -161,7 +161,7 @@ System.Diagnostics/TraceImpl.cs
 System.Diagnostics/TraceSourceInfo.cs
 System.Diagnostics/Win32EventLog.cs
 System/Platform.cs
-System/MonoExeLocator.cs
+System/MonoToolsLocator.cs
 System.IO.Compression/CompressionLevel.cs
 System.IO.Compression/CompressionMode.cs
 System.IO.Compression/DeflateStream.cs

+ 17 - 6
mcs/class/System/System/MonoExeLocator.cs → mcs/class/System/System/MonoToolsLocator.cs

@@ -4,6 +4,7 @@ using System.Diagnostics;
 using System.IO;
 using System.Reflection;
 using System.Runtime.InteropServices;
+using System.Text;
 
 namespace System {
 
@@ -22,12 +23,12 @@ namespace System {
 			var GacPath = Path.GetDirectoryName ((string) getGacMethod.Invoke (null, null));
 
 			if (Path.DirectorySeparatorChar == '\\') {
-				string processExe = Process.GetCurrentProcess ().MainModule.FileName;
-				if (processExe != null) {
-					string fileName = Path.GetFileName (processExe);
-					if (fileName.StartsWith ("mono") && fileName.EndsWith (".exe"))
-						Mono = processExe;
-				}
+				StringBuilder moduleName = new StringBuilder (1024);
+				GetModuleFileName (IntPtr.Zero, moduleName, moduleName.Capacity);
+				string processExe = moduleName.ToString ();
+				string fileName = Path.GetFileName (processExe);
+				if (fileName.StartsWith ("mono") && fileName.EndsWith (".exe"))
+					Mono = processExe;
 
 				if (!File.Exists (Mono))
 					Mono = Path.Combine (
@@ -79,6 +80,16 @@ namespace System {
 					AssemblyLinker = "al";
 			}
 		}
+
+		// Due to an issue with shadow copying  and app domains in mono, we cannot currently use 
+		// Process.GetCurrentProcess ().MainModule.FileName (which would give the same result)
+		// when running in an AppDomain (eg System.Web hosts).
+		//
+		// Using native Windows API to get current process filename. This will only
+		// be called when running on Windows. 
+		[DllImport ("kernel32.dll")]
+		static extern uint GetModuleFileName ([In] IntPtr hModule, [Out] StringBuilder lpFilename, [In] int nSize);
+
 	}
 }