我製作了一個名爲MemoryLauncher的應用程序,將另一個應用程序的可執行程序的二進制文件拖入內存中並運行它。 MemoryLauncher的目的是允許我在更新可用時覆蓋其他程序的.EXE,而不必擔心其他用戶正在運行並鎖定程序。這對我來說非常有效,除了一件事:拖/放。我創建了一個MemoryLauncher將執行的設備管理器程序,該程序需要拖放功能,但在將.EXE調用到內存時似乎被禁用。如果我正常啓動設備管理器,那麼拖放功能可以正常工作。我想,也許這是由於較高權限的,所以我嘗試添加以下代碼到設備mananager和MemoryLauncher沒有運氣:在內存中調用時,C#應用程序dragdrop不起作用
ChangeWindowMessageFilterEx(this.Handle, WM_DROPFILES, MSGFLT_ADD, IntPtr.Zero);
ChangeWindowMessageFilterEx(this.Handle, WM_COPYDATA, MSGFLT_ADD, IntPtr.Zero);
ChangeWindowMessageFilterEx(this.Handle, WM_COPYGLOBALDATA, MSGFLT_ADD, IntPtr.Zero);
下面是該MemoryLauncher程序代碼,其實需要其他應用程序的二進制並運行它:
static class Program
{
private static string[] mainArgs;
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
mainArgs = args;
if (mainArgs.Length == 0)
MessageBox.Show("Please run from shortcut or command line.", "MemoryLauncher.EXE");
else
{
try
{
if (mainArgs[0].Substring(mainArgs[0].Length - 1) != "\\")
mainArgs[0] += "\\";
byte[] bin = makeBinary(Path.Combine(Path.Combine(Directory.GetCurrentDirectory(), mainArgs[0]), mainArgs[1]));
AppDomain ad = AppDomain.CurrentDomain;
ad.AssemblyResolve += new ResolveEventHandler(ad_AssemblyResolve);
Assembly assembly = Assembly.Load(bin);
MethodInfo method = assembly.EntryPoint;
if (method != null)
{
Object obj = assembly.CreateInstance(method.Name);
String[] argsToPass = null;
if (mainArgs.Length > 2 && mainArgs[2] == "/a")
{
argsToPass = new string[mainArgs.Length - 1];
for (int i = 3; i < mainArgs.Length; i++)
argsToPass[i - 3] = mainArgs[i];
}
if (argsToPass != null)
method.Invoke(obj, new object[] { argsToPass });
else
method.Invoke(obj, null);
}
}
catch (Exception e) { MessageBox.Show("ERROR: " + e.Message, "MemoryLauncher.EXE"); }
}
}
static Assembly ad_AssemblyResolve(object sender, ResolveEventArgs resolveArgs)
{
//Load the assembly from the specified path.
AssemblyName assemblyName = new AssemblyName(resolveArgs.Name);
string folder = mainArgs[0];
byte[] bin = makeBinary(Path.Combine(Path.Combine(Directory.GetCurrentDirectory(), folder), assemblyName.Name + ".dll"));
return Assembly.Load(bin);
}
static byte[] makeBinary(string pathName)
{
FileStream fs = new FileStream(pathName, FileMode.Open);
BinaryReader br = new BinaryReader(fs);
byte[] bin = br.ReadBytes(Convert.ToInt32(fs.Length));
fs.Close();
br.Close();
return bin;
}
}
此時應更換'和'File.ReadAllBytes' makeBinary'。 – SLaks 2011-04-28 15:25:32