|
|
|
@ -1,11 +1,8 @@
@@ -1,11 +1,8 @@
|
|
|
|
|
using System; |
|
|
|
|
using System.Collections.Generic; |
|
|
|
|
using System.Collections.Generic; |
|
|
|
|
using System.Diagnostics; |
|
|
|
|
using System.IO; |
|
|
|
|
using System.Linq; |
|
|
|
|
using System.Runtime.InteropServices; |
|
|
|
|
using System.Text; |
|
|
|
|
using System.Threading.Tasks; |
|
|
|
|
|
|
|
|
|
namespace ICSharpCode.ILSpy.AddIn |
|
|
|
|
{ |
|
|
|
@ -47,85 +44,28 @@ namespace ICSharpCode.ILSpy.AddIn
@@ -47,85 +44,28 @@ namespace ICSharpCode.ILSpy.AddIn
|
|
|
|
|
{ |
|
|
|
|
var commandLineArguments = parameters?.AssemblyFileNames?.Concat(parameters.Arguments); |
|
|
|
|
string ilSpyExe = GetILSpyPath(); |
|
|
|
|
var process = new Process() { |
|
|
|
|
StartInfo = new ProcessStartInfo() { |
|
|
|
|
FileName = ilSpyExe, |
|
|
|
|
UseShellExecute = false, |
|
|
|
|
Arguments = "/navigateTo:none" |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
process.Start(); |
|
|
|
|
|
|
|
|
|
const string defaultOptions = "--navigateto:none"; |
|
|
|
|
string argumentsToPass = defaultOptions; |
|
|
|
|
|
|
|
|
|
if ((commandLineArguments != null) && commandLineArguments.Any()) |
|
|
|
|
{ |
|
|
|
|
// Only need a message to started process if there are any parameters to pass
|
|
|
|
|
SendMessage(ilSpyExe, "ILSpy:\r\n" + string.Join(Environment.NewLine, commandLineArguments), true); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD110:Observe result of async calls", Justification = "<Pending>")] |
|
|
|
|
void SendMessage(string ilSpyExe, string message, bool activate) |
|
|
|
|
{ |
|
|
|
|
string expectedProcessName = Path.GetFileNameWithoutExtension(ilSpyExe); |
|
|
|
|
// We wait asynchronously until target window can be found and try to find it multiple times
|
|
|
|
|
Task.Run(async () => { |
|
|
|
|
bool success = false; |
|
|
|
|
int remainingAttempts = 20; |
|
|
|
|
do |
|
|
|
|
{ |
|
|
|
|
NativeMethods.EnumWindows( |
|
|
|
|
(hWnd, lParam) => { |
|
|
|
|
string windowTitle = NativeMethods.GetWindowText(hWnd, 100); |
|
|
|
|
if (windowTitle.StartsWith("ILSpy", StringComparison.Ordinal)) |
|
|
|
|
{ |
|
|
|
|
string processName = NativeMethods.GetProcessNameFromWindow(hWnd); |
|
|
|
|
Debug.WriteLine("Found {0:x4}: '{1}' in '{2}'", hWnd, windowTitle, processName); |
|
|
|
|
if (string.Equals(processName, expectedProcessName, StringComparison.OrdinalIgnoreCase)) |
|
|
|
|
{ |
|
|
|
|
IntPtr result = Send(hWnd, message); |
|
|
|
|
Debug.WriteLine("WM_COPYDATA result: {0:x8}", result); |
|
|
|
|
if (result == (IntPtr)1) |
|
|
|
|
{ |
|
|
|
|
if (activate) |
|
|
|
|
NativeMethods.SetForegroundWindow(hWnd); |
|
|
|
|
success = true; |
|
|
|
|
return false; // stop enumeration
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return true; // continue enumeration
|
|
|
|
|
}, IntPtr.Zero); |
|
|
|
|
string assemblyArguments = string.Join(" ", commandLineArguments); |
|
|
|
|
|
|
|
|
|
// Wait some time before next attempt
|
|
|
|
|
await Task.Delay(500); |
|
|
|
|
remainingAttempts--; |
|
|
|
|
} while (!success && (remainingAttempts > 0)); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
string filepath = Path.GetTempFileName(); |
|
|
|
|
File.WriteAllText(filepath, assemblyArguments); |
|
|
|
|
|
|
|
|
|
unsafe static IntPtr Send(IntPtr hWnd, string message) |
|
|
|
|
{ |
|
|
|
|
const uint SMTO_NORMAL = 0; |
|
|
|
|
argumentsToPass = $"@\"{filepath}\""; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
CopyDataStruct lParam; |
|
|
|
|
lParam.Padding = IntPtr.Zero; |
|
|
|
|
lParam.Size = message.Length * 2; |
|
|
|
|
fixed (char* buffer = message) |
|
|
|
|
{ |
|
|
|
|
lParam.Buffer = (IntPtr)buffer; |
|
|
|
|
IntPtr result; |
|
|
|
|
// SendMessage with 3s timeout (e.g. when the target process is stopped in the debugger)
|
|
|
|
|
if (NativeMethods.SendMessageTimeout( |
|
|
|
|
hWnd, NativeMethods.WM_COPYDATA, IntPtr.Zero, ref lParam, |
|
|
|
|
SMTO_NORMAL, 3000, out result) != IntPtr.Zero) |
|
|
|
|
{ |
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
return IntPtr.Zero; |
|
|
|
|
var process = new Process() { |
|
|
|
|
StartInfo = new ProcessStartInfo() { |
|
|
|
|
FileName = ilSpyExe, |
|
|
|
|
UseShellExecute = false, |
|
|
|
|
Arguments = argumentsToPass |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
process.Start(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|