2011-04-28 78 views
0

我製作了一個名爲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; 
     } 
    } 
+0

此時應更換'和'File.ReadAllBytes' makeBinary'。 – SLaks 2011-04-28 15:25:32

回答

1

我不知道準確的回答你的問題,但是這並不是沒有鎖定它運行一個程序的最佳途徑。
您應該使用.Net的ShadowCopy功能,該功能專門用於執行此操作。
我寫了使用它下面的啓動:

using System; 
using System.IO; 
using System.Reflection; 
using System.Security; 
using System.Security.Permissions; 
using System.Collections; 
using System.Security.Policy; 

[assembly: AssemblyVersion("1.1.0.0")] 
namespace ShadowLauncher { 
    static class Program { 
     [STAThread] 
     static int Main(string[] args) { 
      if (args.Length == 0 || !File.Exists(args[0])) 
       return 1; 

      var assembly = args[0]; 
      var realArgs = new string[args.Length - 1]; 
      if (realArgs.Length > 0) 
       Array.Copy(args, 1, realArgs, 0, realArgs.Length); 

      var permissions = new PermissionSet(PermissionState.Unrestricted); 

      AppDomain.CreateDomain(Path.GetFileNameWithoutExtension(assembly), 
       AppDomain.CurrentDomain.Evidence, 
       new AppDomainSetup { 
        ShadowCopyFiles = "true", 
        ConfigurationFile = assembly + ".config", 
        ApplicationBase = Path.GetDirectoryName(Path.GetFullPath(assembly)) 
       }, 
       permissions 
      ).ExecuteAssembly(assembly, AppDomain.CurrentDomain.Evidence, realArgs); 
      return 0; 
     } 
    } 
} 
+0

天才!您的代碼可以修復問題,並立即進行拖放操作! :) 非常感謝你 – Zac 2011-04-28 15:36:32

相關問題