我刚开始学习C#并为Minecraft启动器创建了这个简单的配置文件生成器,就像要做的事情一样。我在尝试独立于Visual C#2010运行应用程序时遇到了麻烦 - 它吐出“索引和长度必须引用字符串中的位置。参数名称:长度”首次运行时(当如果我在此之后再次启动它,那么“索引超出了数组的范围”。
我很困惑为什么会这样 - 它没有给我任何行号,只有当我不通过IDE运行应用程序时才会发生(无论我运行调试版本还是发布版本) 。任何帮助深表感谢。我为我可能可怕的编码道歉 - 我是这种语言的初学者。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Minecraft_Launcher_Config
{
public partial class mcwindow : Form
{
private void outputText(string outtext)
{
output.Text = outtext;
}
private string encrypt(string text, int key)
{
string newText = "";
for (int i = 0; i < text.Length; i++)
{
int charValue = Convert.ToInt32(text[i]);
charValue ^= key;
newText += char.ConvertFromUtf32(charValue);
}
return newText;
}
public mcwindow()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
string iuser = "";
string ipass = "";
string imem = "1024";
string iserver = "";
if (System.IO.File.Exists("config.cfg"))
{
System.IO.StreamReader configFile =
new System.IO.StreamReader("config.cfg");
string[] iconfig = System.IO.File.ReadAllLines("config.cfg");
iuser = iconfig[0];
ipass = iconfig[1];
imem = iconfig[2];
iserver = iconfig[3];
configFile.Close();
outputText("Successfully loaded and decrypted config!");
} else
{
System.IO.StreamWriter configwrite = new System.IO.StreamWriter("config.cfg");
configwrite.Close();
outputText("Welcome to Frohman's Minecraft Launcher Config!");
}
username.Text = iuser;
memselect.Value = int.Parse(imem);
int OKey = Convert.ToInt32(username.Text.Substring(0, 1));
string unenpassword = encrypt(ipass, OKey);
password.Text = unenpassword;
}
private void label1_Click(object sender, EventArgs e)
{
}
private void label4_Click(object sender, EventArgs e)
{
}
private void saveexit_Click(object sender, EventArgs e)
{
if (username.Text != "" & password.Text != "")
{
outputText("Saving and exiting!");
int IKey = Convert.ToInt32(username.Text[0]);
string enpassword = encrypt(password.Text, IKey);
string outString = username.Text + System.Environment.NewLine + enpassword + System.Environment.NewLine + memselect.Value + System.Environment.NewLine + serverip.Text;
System.IO.StreamWriter configwrite = new System.IO.StreamWriter("config.cfg");
configwrite.WriteLine(outString);
configwrite.Close();
System.Threading.Thread.Sleep(150);
Environment.Exit(0);
}
else
{
outputText("You're missing some data!");
}
}
private void password_TextChanged(object sender, EventArgs e)
{
}
}
}
答案 0 :(得分:2)
此代码:
string[] iconfig = System.IO.File.ReadAllLines("config.cfg");
iuser = iconfig[0];
ipass = iconfig[1];
imem = iconfig[2];
iserver = iconfig[3];
如果文件包含少于4行,...将抛出您所讨论的异常。或许这是发生了什么? (你确实谈到它创建一个空白文件。)
请注意,您还要使用StreamReader
打开文件但是没有任何目的,因为您也只是打电话ReadAllLines
,它会单独打开它。
当您使用以下代码写出文件时:
System.IO.StreamWriter configwrite = new System.IO.StreamWriter("config.cfg");
configwrite.WriteLine(outString);
configwrite.Close();
这只写出一行,假设outString
不包含任何换行符...所以我不确定这可能曾如何工作,即使在IDE中也是如此。 )
(请注意,如果您执行想要使用StreamReader
和StreamWriter
,则应使用using
语句,以便文件句柄即使在那里也会关闭是例外。您不需要在此使用StreamReader
或StreamWriter
- 您可以使用File.WriteAllLines
或File.WriteAllText
。)
最后,加密不可以通过文本完成。您通常会收到乱码文本,这些文本很容易包含无效的代码单元等。通常,如果您想加密文本,则将其转换为二进制文件,应用标准加密算法(不要自己编写) )然后如果你想要文本,你可以用Convert.ToBase64String
将其转换为base64。
答案 1 :(得分:1)
首先,如果您已使用StreamReader
,请不要使用File.ReadAllLines
它可能关闭文件并使方法File.readAllLines.
尝试使用完整路径加载配置文件,如
string[] iconfig = System.IO.File.ReadAllLines(@"MyPath\config.cfg");
比确定测试
if(iconfig.length >= 4)
//Proceed With Config
如果您希望使用配置而不是使用Application.Setting
,那么最后答案 2 :(得分:0)
如果是,String.SubString将抛出ArgumentOutOfRangeException startIndex加上length表示不在此实例中的位置。
在第一次运行期间,您可以调用此代码:
iuser="";
...
username.Text = iuser;
memselect.Value = int.Parse(imem);
int OKey = Convert.ToInt32(username.Text.Substring(0, 1));
当你有一个空字符串时,username.Text.Substring(0,1)超出了数组的范围。