获取可执行文件当前位置的路径

时间:2021-04-12 22:28:41

标签: c# .net-core atmelstudio

我有一个非常简单的应用程序,它会自动从 Git 标签获取固件文件的版本号,并将固件版本写入二进制文件的末尾,并在每次构建固件时将版本附加到名称文件。对于我处理的每个项目,我想将这个可执行文件复制到固件的项目文件夹中,因此该应用程序只需在它所在的同一目录中查找所需的文件,而不管它的实际位置如何(因此我不不必每次都重新编程)。

这在 VS 项目文件夹中完美运行(我复制了所需的文件),但是当我将 .exe 文件移动到固件项目文件夹时,它不再起作用。我认为问题是获取 .exe 位置路径的代码仍然是它自己的项目文件夹,而不是新位置。让它发挥作用的正确方法是什么?

我试过了:

Environment.CurrentDirectory;
Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);
System.Reflection.Assembly.GetExecutingAssembly().Location;

和其他一些。我不明白为什么这是一件如此困难的事情。

编辑:.Net Core3.1

编辑:完整代码:

using System;
using System.IO;
using System.Diagnostics;

namespace VersionAppend
{ 
    class Program
    {
        const int INSERT_OFFSET = 0x1EFF9;
        const byte VER_NUMS = 3;
        const byte VER_SIZE = VER_NUMS * sizeof(ushort);

        static void Main(string[] args)
        {
            byte[] version = new byte[VER_SIZE];
            string versionFileName = AppContext.BaseDirectory + @"\version";

            if (!File.Exists(versionFileName))
            {
                Trace.WriteLine("Error");
                return;
            }

            // Get Firmware version as string
            string versionString = File.ReadAllText(versionFileName);

            // Break version into parts
            Version ver = Version.Parse(versionString);

            convertVersionToBytes(ver, version);

            // Search for Firmware File
            string directory = AppContext.BaseDirectory + @"\Debug";
            string firmwareKeyword = "firmware";

            var files = Directory.EnumerateFiles(directory, "*" + firmwareKeyword + ".bin");

            foreach (string item in files)
            {
                // Open firmware file
                BinaryWriter firmware = new BinaryWriter(new FileStream(item, FileMode.Open));

                firmware.Seek(INSERT_OFFSET, SeekOrigin.Begin);
                // Write version to end
                firmware.Write(version, 0, (int)VER_SIZE);

                // Close firmware file
                firmware.Close();

                string extension = Path.GetExtension(item);

                string file = Path.GetFileNameWithoutExtension(item);

                // Rename file with version
                string verString = convertVersionToString(version);
                File.Move(item, @item.Substring(0, item.Length -extension.Length) + "_" + verString + ".bin");
            }
               
        }

        private static void convertVersionToBytes (Version ver, byte [] version)
        {
            // Major.MSB, Major LSB, Minor...
            version[0] = (byte)((ushort)(ver.Major >> 8) & 0xFF);
            version[1] = (byte)((ushort)ver.Major & 0xFF);
            version[2] = (byte)((ushort)(ver.Minor >> 8) & 0xFF);
            version[3] = (byte)((ushort)ver.Minor & 0xFF);
            version[4] = (byte)((ushort)(ver.Build >> 8) & 0xFF);
            version[5] = (byte)((ushort)ver.Build & 0xFF);
        }

        private static string convertVersionToString(byte [] version)
        {
            return BitConverter.ToString(version).Replace("-", "");
        }

    }
}

1 个答案:

答案 0 :(得分:1)

不难。

但它可能取决于您的目标平台(您尚未指定)。

对于 .Net Core 1.x 和 .Net 5 或更高版本,我会使用 AppContext.BaseDirectory

以下是多年来适用于各种环境的其他一些替代方案:

<块引用>

6 ways to get the current directory in C#, August 17, 2010

  • AppDomain.CurrentDomain.BaseDirectory 这是全方位的最佳选择。它将为您提供类库的基目录, 包括 ASP.NET 应用程序中的那些。

  • Directory.GetCurrentDirectory() 注意:在 .NET Core 中,这是当前的最佳实践。以下详细信息与 .NET Framework 相关 4.5 及以下。

    这使用 winapi GetCurrentDirectory 调用进行互操作调用 在 kernel32.dll 中,这意味着启动进程的文件夹将 经常被退回。同样正如 MSDN 文档所说,不能保证 在移动设备上工作。

  • Environment.CurrentDirectory
    这只是调用 Directory.GetCurrentDirectory()

  • 装配.位置
    这将使用

    调用

    this.GetType().Assembly.Location

    这将返回调用程序集的完整路径,包括 程序集名称本身。如果您正在调用单独的类库, 然后将返回其基目录,例如“C:\myassembly.dll” - 显然取决于正在使用的程序集实例。

  • Application.StartupPath
    它位于 System.Windows.Forms 命名空间内,因此通常仅用于窗口窗体应用程序。

  • Application.ExecutablePath 与 Application.StartupPath 相同,但也包括应用程序名称,例如“myapp.exe”

相关问题