我有一个程序,它是游戏mod的启动器。发射器适用于大多数使用它的人,包括我自己,但是对于一些人而言,有一个奇怪的错误确实让我难以修复它,而且更让我绝对精神错乱!
基本思想是我的mod文件包含在一个文件夹中,启动器遍历这些文件,读取文件的某个字节并根据结果移动文件,或移动文件和< / em>将某些文本写入某个文件,然后启动游戏。看似简单。
主要启动功能如下:
private void Launch()
{
using (StreamWriter writer = new StreamWriter(userScriptPath, false, Encoding.Unicode))
{
foreach (string file in Directory.GetFiles(modFolderPath + "\\Files\\", "*.pack"))
{
int p = GetPackType(file);
if (p == 3)
{
if (File.Exists(modFolderPath + "\\Files\\" + Path.GetFileName(file)))
{
File.Move(modFolderPath + "\\Files\\" + Path.GetFileName(file), dataPath + "\\" + Path.GetFileName(file));
}
writer.WriteLine("mod \"" + Path.GetFileName(file) + "\";");
}
else if (p == 4)
{
if (File.Exists(modFolderPath + "\\Files\\" + Path.GetFileName(file)))
{
File.Move(modFolderPath + "\\Files\\" + Path.GetFileName(file), dataPath + "\\" + Path.GetFileName(file));
}
}
}
}
Process game = Process.Start(gamePath);
// There is code here that waits for a minute until the game process is actually found, incase its slow starting up
game.WaitForExit();
RestorePacks(); // <- Method to put back the files after finishing
}
一些用户遇到的问题是,当启动mod时游戏启动但看起来好像启动器没有移动文件,因为游戏仍处于正常状态,很难确定为什么这个发生了,因为我无法在他们的计算机上调试它,程序对我和我的所有测试用户都很好。
为了试图找出发生了什么,我添加了一些检查和一些记录到启动器,以便如果启动器不起作用,我至少知道为什么。 (请注意,即使用户不起作用,也不会引发任何错误)
我添加的检查包括在尝试移动文件以确保它实际移动后使用File.Exists()
,日志记录保留了移动尝试的记录以及此检查的结果以查看文件是否实际移动。
我甚至在Process.Start函数中添加了一个特定的if语句,特别是在启动游戏之前检查某个文件确实在所需的位置。
最后,在启动mod文件应该的文件夹中的所有文件都写入日志之前。
启动器不能共享共享一个共同点的用户的所有日志程序试图移动文件,没有错误,然后在检查文件确实被移动时,文件似乎是那里。但是当达到将所需目录中的所有文件写入日志的程度时,目录中只有一个所需的30多个mod文件。
示例输出日志如下所示:
文件移动: modfile1.txt
检查文件是否是我们尝试将其移至的位置:是
文件移动: modfile2.txt
检查文件是否是我们尝试将其移至的位置:是
文件移动: modfile3.txt
检查文件是否是我们尝试将其移至的位置:是
写出目录中的所有文件:
normalgamefile1.txt
normalgamefile2.txt
normalgamefile3.txt
modfile1.txt
看到这一点并注意到它总是只有一个文件已经移动而没有其他文件,而且程序确实认为文件是他们应该在的位置,这种混乱真的开始起作用。
这是读取文件以确定文件类型的方法:
private int GetPackType(string path)
{
FileStream fs = File.OpenRead(path);
BinaryReader reader = new BinaryReader(fs);
reader.ReadChars(4);
int packType = reader.ReadInt32();
fs.Close();
fs.Dispose();
return packType;
}
你可能已经看到了,我刚刚注意到的是我没有关闭/处置reader
,我猜测并且有点希望这可能是我问题的原因。
(注意我现在正在使用此方法中的Using语句,但很长时间内无法测试此修复程序)
所以,如果你读过这篇文章,那么谢谢你,我的问题是......
首先你知道问题是什么吗?可能是reader
仍然可能打开文件并且没有关闭,因此文件无法移动,如果那么为什么它对我和大多数其他人来说都是完美的,但对某些人来说却不是这样?当然,仍在其他地方使用的文件会引发错误吗?
我已经完成了所有简单的事情,例如确保程序以管理员权限运行等等。
非常感谢您的帮助!
修改
正如评论中所述,这是我添加了检查和日志记录的代码版本。简单的东西,这就是为什么我省略它,日志只是添加到一个字符串,然后字符串打印到文件完成所有。
private void Launch()
{
using (StreamWriter writer = new StreamWriter(userScriptPath, false, Encoding.Unicode))
{
foreach (string file in Directory.GetFiles(modFolderPath + "\\Files\\", "*.pack"))
{
int p = GetPackType(file);
if (p == 3)
{
if (File.Exists(modFolderPath + "\\Files\\" + Path.GetFileName(file)))
{
File.Move(modFolderPath + "\\Files\\" + Path.GetFileName(file), dataPath + "\\" + Path.GetFileName(file));
}
log += "Move File: " + Path.GetFileName(file) + "\r\n";
writer.WriteLine("mod \"" + Path.GetFileName(file) + "\";");
log += "Write mod line: " + Path.GetFileName(file) + "\r\n";
}
else if (p == 4)
{
if (File.Exists(modFolderPath + "\\Files\\" + Path.GetFileName(file)))
{
File.Move(modFolderPath + "\\Files\\" + Path.GetFileName(file), dataPath + "\\" + Path.GetFileName(file));
}
log += "Move File: " + Path.GetFileName(file) + "\r\n";
}
// Check the file did actually move
if (File.Exists(dataPath + "\\" + Path.GetFileName(file)) == false)
{
MessageBox.Show("The mod could not launch successfully!\n\nError: Packs failed to move", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
else
{
log += "File Found\r\n";
}
}
}
if (File.Exists(dataPath + "\\_GreatWar5_DB.pack")) // This pack should always be there if things have worked
{
Process game = Process.Start(gamePath);
}
else
{
MessageBox.Show("The mod could not launch successfully!\n\nError: Data pack missing", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
// There is code here waits for a minute until the game process is actually found, incase its slow starting up
game.WaitForExit();
RestorePacks(); // <- Method to put back the files after finishing
}