Перетаскивание приложения C # не работает при вызове в памяти - PullRequest
0 голосов
/ 28 апреля 2011

Я создал приложение под названием MemoryLauncher, которое извлекает двоичный файл исполняемого файла другого приложения в память и запускает его.Цель MemoryLauncher - позволить мне перезаписать .EXE других программ, когда доступно обновление, не беспокоясь о том, что другой пользователь запустит и заблокирует программу.Это работает очень хорошо для меня, за исключением одного: перетаскивание.Я создал программу диспетчера устройств, которую запустит MemoryLauncher, и для этой программы требуется функция перетаскивания, но она кажется отключенной при вызове .EXE в память.Если я нормально запускаю диспетчер устройств, то функция перетаскивания работает нормально.Я подумал, что, возможно, это связано с повышенными привилегиями, поэтому я безуспешно попытался добавить следующий код в mananager и 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;
        }
    }

1 Ответ

1 голос
/ 28 апреля 2011

Я не знаю точного ответа на ваш вопрос, но это не лучший способ запустить программу без ее блокировки.
Вы должны использовать функцию .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;
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...