C# - 确定文件路径

C# - Determine file path

我正在使用以下代码为我的程序加载自定义光标:

public static Cursor LoadCustomCursor(string path)
{
    IntPtr hCurs = LoadCursorFromFile(path);
    if (hCurs == IntPtr.Zero) throw new Win32Exception(-2147467259, "Key game file missing. Please try re-installing the game to fix this error.");
    Cursor curs = new Cursor(hCurs);
    // Note: force the cursor to own the handle so it gets released properly.
    FieldInfo fi = typeof(Cursor).GetField("ownHandle", BindingFlags.NonPublic | BindingFlags.Instance);
    fi.SetValue(curs, true);
    return curs;
}
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
static extern IntPtr LoadCursorFromFile(string path);

然后:

Cursor gameCursor = NativeMethods.LoadCustomCursor(@"C:/Users/User/Documents/Visual Studio 2015/Projects/myProj/myProj/Content/Graphics/Cursors/cursor_0.xnb");
Form gameForm = (Form)Control.FromHandle(Window.Handle);

我想知道如果项目文件夹例如移动到 D:/ 分区或 C:/ 上的另一个文件夹,上面的这个绝对路径是否也有效?我可以这样做吗:

string myStr = Assembly.GetExecutingAssembly().Location;
string output = myStr.Replace("bin\Windows\Debug\myProj.exe", "Content\Graphics\Cursors\cursor_0.xnb");

并使用output作为光标文件的路径? Assembly.GetExecutingAssembly().Location 是动态的吗(每次移动程序文件夹时都会更改)?还是一直和项目建的时候一样?

您可以使用 Environment.CurrentDirectory。示例:

string cursorPath = @"Content\Graphics\Cursors\cursor_0.xnb";
string output = Path.Combine(Environment.CurrentDirectory, cursorPath);

Environment.CurrentDirectory returns 当前工作目录的完整路径,如果放在前面,可以使用 @ 一次性转义文字 \的字符串。

这种方法不是最好的方法。

最好使用相对路径,而不是绝对路径。

您可以使用“..”将文件夹从当前位置上移一个。 例如

var output = @"..\..\..\Content\Graphics\Cursors\cursor_0.xnb";

等于

string myStr = System.Reflection.Assembly.GetExecutingAssembly().Location;
string output = myStr.Replace("bin\Windows\Debug\myProj.exe", "Content\Graphics\Cursors\cursor_0.xnb");

只有当您的光标文件位于指定的确切路径时,您的绝对路径才会继续工作:@"C:/Users/User/Documents/Visual Studio 2015/Projects/myProj/myProj/Content/Graphics/Cursors/cursor_0.xnb"。将光标文件的位置与您的 .EXE 文件相关联是一个更好的主意,但您需要维护您在代码中指定的相对文件夹结构。您的代码现在依赖于目录 <appRoot>\bin\Windows\Debug 中的 .EXE,您在部署应用程序时可能不需要它。 (相反,您可能会将 .EXE 放在应用程序的根文件夹中,资源文件放入子目录中。)对于这样的结构,您可以编写(代码从未编译过,因此可能包含拼写错误或其他错误):

var exe = Assembly.GetExecutingAssembly().Location;
var exeFolder = System.IO.Path.GetDirectoryName(exe);
var cursorFile = System.IO.Path.Combine(exeFolder, "relative/path/to/your.cur";

(为了增加好处,重命名 .EXE 文件后,此代码将继续工作。) 使用这种方法,您只需确保可以在相对于 .EXE 的特定位置找到光标文件。当然,您的开发箱和目标机器上都需要存在相同的结构。使用 Visual Studio 中的 MSBuild 任务将资源文件复制到 $(OutDir)\relative\path\to。要部署到其他机器,只需复制+粘贴输出文件夹的内容,或创建一个安装程序,将文件部署到所需的文件夹结构。