执行C#时在系统上移动目录?

时间:2016-08-27 03:46:02

标签: c# visual-studio-2015

我想移动我的C#应用​​程序.EXE,当运行时让我们说...文件然后从它执行的地方删除。

例如,如果我在桌面上运行我的.EXE,然后运行程序将其自身复制到目录“documents”,然后在文件中运行新目录后删除执行目录(在我的情况下是桌面)中的那个。

流程:运行>转到C:// Documents>在文档中启动.EXE>从执行的目录中删除.EXE。

很抱歉,如果某些人难以理解这一点,我会尽力明确说明我想要完成的事情。

2 个答案:

答案 0 :(得分:1)

我希望你能以这种方式编写程序,这将有所帮助。

1)程序  i)检查如果程序的执行目录不是C:/ Documents     然后它应该复制文件夹并将其放在C:/ Documents中      启动文档中的exe ii)否则获取exe及其执行目录的运行列表     (如果它不是C:/ Documents停止exe,并删除执行文件夹

不确定这是否会有所帮助,但这只是我的想法

答案 1 :(得分:0)

使用单个进程无法执行此操作,因为要移动的exe将在内存中运行。

您可以让应用程序自行复制,执行副本,然后自行终止。

这肯定需要调整并且非常基础,但希望能给你一些想法。对不起,这是控制台应用程序中的所有静态,所有方法都应该在他们自己合适的类中。

using System;
using System.Globalization;
using System.IO;
using System.Linq;

namespace StackExchangeSelfMovingExe
{
    class Program
    {
        static void Main(string[] args)
        {
            // check if we are running in the correct path or not?
            bool DoMoveExe = !IsRunningInDocuments();
                        string runningPath = Directory.GetCurrentDirectory();
            if (DoMoveExe)
            {
                // if we get here then we are not, copy our app to the right place.
                string newAppPath = GetDesiredExePath();
                CopyFolder(runningPath, newAppPath);
                CreateToDeleteMessage(newAppPath, runningPath); // leave a message so new process can delete the old app path

                // start the application running in the right directory.
                string newExePath = $"{GetDesiredExePath()}\\{System.AppDomain.CurrentDomain.FriendlyName}";
                ExecuteExe(newExePath);

                // kill our own process since a new one is now running in the right place.
                KillMyself();
            }
            else
            {
                // if we get here then we are running in the right place. check if we need to delete the old exe before we ended up here.
                string toDeleteMessagePath = $"{runningPath}\\CopiedFromMessage.txt";
                if (File.Exists(toDeleteMessagePath))
                {
                    // if the file exists then we have been left a message to tell us to delete a path.
                    string pathToDelete = System.IO.File.ReadAllText(toDeleteMessagePath);
                    // kill any processes still running from the old folder.
                    KillAnyProcessesRunningFromFolder(pathToDelete);
                    Directory.Delete(pathToDelete, true);
                }

                // remove the message so next time we start, we don't try to delete it again.
                File.Delete(toDeleteMessagePath);
            }

            // do application start here since we are running in the right place.
        }



        static string GetDesiredExePath()
        {
            // this is the directory we want the app running from.
            string userPath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
            return $"{userPath}\\documents\\MyExe".ToLower();
        }
        static bool IsRunningInDocuments()
        {
            // returns true if we are running from within the root of the desired directory.
            string runningPath = Directory.GetCurrentDirectory();
            return runningPath.StartsWith(GetDesiredExePath());
        }

        // this copy method is from http://stackoverflow.com/questions/58744/best-way-to-copy-the-entire-contents-of-a-directory-in-c-sharp
        public static void CopyFolder(string SourcePath, string DestinationPath)
        {
            if (!Directory.Exists(DestinationPath))
            {
                Directory.CreateDirectory(DestinationPath);
            }

            //Now Create all of the directories
            foreach (string dirPath in Directory.GetDirectories(SourcePath, "*",
                SearchOption.AllDirectories))
                Directory.CreateDirectory(DestinationPath + dirPath.Remove(0, SourcePath.Length));

            //Copy all the files & Replaces any files with the same name
            foreach (string newPath in Directory.GetFiles(SourcePath, "*.*",
                SearchOption.AllDirectories))
                File.Copy(newPath, DestinationPath + newPath.Remove(0, SourcePath.Length), true);
        }

        private static void CreateToDeleteMessage(string newPath, string runningPath)
        {
            // simply write a file with the folder we are in now so that this folder can be deleted later.
            using (System.IO.StreamWriter file =
            new System.IO.StreamWriter($"{newPath}\\CopiedFromMessage.txt", true))
            {
                file.Write(runningPath);
            }
        }

        private static void ExecuteExe(string newExePath)
        {
            // launch the process which we just copied into documents.
            System.Diagnostics.Process.Start(newExePath);
        }

        private static void KillMyself()
        {
            // this is one way, depending if you are using console, forms, etc you can use more appropriate method to exit gracefully.
            System.Diagnostics.Process.GetCurrentProcess().Kill();
        }

        private static void KillAnyProcessesRunningFromFolder(string pathToDelete)
        {
            // kill any processes still running from the path we are about to delete, just incase they hung, etc.
            var processes = System.Diagnostics.Process.GetProcesses()
                            .Where(p => p.MainModule.FileName.StartsWith(pathToDelete, true, CultureInfo.InvariantCulture));
            foreach (var proc in processes)
            {
                proc.Kill();
            }
        }
    }
}