-
October 1st, 2010, 01:16 PM
#1
Problem with args
I am trying to write a program that the user launches with at least one argument. The problem is that there is a file that is in the same directory as the exe that the program opens to get some data. When the program is launched with an argument, when it tried to load the file in the same directory as the exe it is using the directory of the args.
This is what I am using to load the file in the same directory as the exe.
Code:
StreamReader sr = new StreamReader("Table.tbl");
-
October 1st, 2010, 01:26 PM
#2
Re: Problem with args
What do you mean "using the directory of the args"? The program won't change directories unless you tell it to change.
-
October 1st, 2010, 01:37 PM
#3
Re: Problem with args
if the folder with the exe and the tbl was C:/temp and the file for the argument was in c:/temp2. it tries to load c:/temp2/Table.tbl.
If I had the file for the argument in c:/temp or had Table.tbl in C:/temp2 it works fine.
Here is the program with a example file.
http://dl.dropbox.com/u/3706406/Files/pokeshift.rar
Last edited by KazoWAR; October 1st, 2010 at 01:41 PM.
-
October 1st, 2010, 02:03 PM
#4
Re: Problem with args
The program exe isn't going to do much good without the source code - I can't see what's wrong without the sources. Can you post the source code?
-
October 1st, 2010, 02:13 PM
#5
Re: Problem with args
Code:
using System;
using System.IO;
using System.Globalization;
namespace pokeshift
{
class Program
{
static void Main(string[] args)
{
UInt32 PID = 0x00, Letter = 0x00, ReadLetter = 0x00, Pokeball = 0x00, Checksum = 0x00;
String OTName = "", PKMName = "", ReadLine = "", OutputPath = "";
MemoryStream ms = new MemoryStream(136);
StreamReader sr = new StreamReader("Table.tbl");
Console.WriteLine("Pokeshift v0.01 by Kazo - Research by kaphotics\n");
if (args.Length > 0)
{
//shifts each file
for (int i = 0; i < args.Length; i++)
{
FileStream fs = File.OpenRead(Convert.ToString(args[i]));
BinaryReader br = new BinaryReader(fs);
ms = new MemoryStream(136);
br.BaseStream.Position = 0x00;
ms.Position = 0x00;
//Copies file in to memory.
for (int j = 0; j < 136; j++)
{
ms.WriteByte(br.ReadByte());
}
br.Close();
//Removes item.
ms.Position = 0x0A;
ms.WriteByte(0x00);
ms.WriteByte(0x00);
//Sets Nature.
ms.Position = 0x00;
PID = Convert.ToUInt32(ms.ReadByte()) + (Convert.ToUInt32(ms.ReadByte()) * 0x100) + (Convert.ToUInt32(ms.ReadByte()) * 0x10000) + (Convert.ToUInt32(ms.ReadByte()) * 0x1000000);
ms.Position = 0x41;
ms.WriteByte(Convert.ToByte(PID % 25));
//Removes Pt/HGSS locations.
ms.Position = 0x44;
ms.WriteByte(0x00);
ms.WriteByte(0x00);
ms.WriteByte(0x00);
ms.WriteByte(0x00);
//Name conversion.
ms.Position = 0x48;
PKMName = "";
for (int j = 0; j < 10; j++)
{
ReadLetter = 0xFFFF;
Letter = Convert.ToUInt32(ms.ReadByte()) + (Convert.ToUInt32(ms.ReadByte()) * 0x100);
if (Letter != 0xFFFF)
{
sr = new StreamReader("Table.tbl");
while (Letter != ReadLetter)
{
ReadLine = sr.ReadLine();
ReadLetter = UInt32.Parse(ReadLine.Substring(0, 4), NumberStyles.AllowHexSpecifier);
}
PKMName += ReadLine[5];
sr.Close();
}
else
{
j = 10;
}
}
ms.Position = 0x48;
for (int j = 0; j < PKMName.Length; j++)
{
ms.WriteByte(Convert.ToByte((Convert.ToUInt32(PKMName[j])) - ((Convert.ToUInt32(PKMName[j]) / 0x100) * 0x100)));
ms.WriteByte(Convert.ToByte(Convert.ToUInt32(PKMName[j]) / 0x100));
}
//OTName conversion.
ms.Position = 0x68;
OTName = "";
for (int j = 0; j < 7; j++)
{
ReadLetter = 0x00;
Letter = Convert.ToUInt32(ms.ReadByte()) + (Convert.ToUInt32(ms.ReadByte()) * 0x100);
if (Letter != 0xFFFF)
{
sr = new StreamReader("Table.tbl");
while (Letter != ReadLetter)
{
ReadLine = sr.ReadLine();
ReadLetter = UInt32.Parse(ReadLine.Substring(0, 4), NumberStyles.AllowHexSpecifier);
}
OTName += ReadLine[5];
sr.Close();
}
else
{
j = 10;
}
}
ms.Position = 0x68;
for (int j = 0; j < OTName.Length; j++)
{
ms.WriteByte(Convert.ToByte((Convert.ToUInt32(OTName[j])) - ((Convert.ToUInt32(OTName[j]) / 0x100) * 0x100)));
ms.WriteByte(Convert.ToByte(Convert.ToUInt32(OTName[j]) / 0x100));
}
//Met location.
ms.Position = 0x80;
ms.WriteByte(0x31);
ms.WriteByte(0x75);
//Pokeball.
ms.Position = 0x86;
Pokeball = Convert.ToUInt32(ms.ReadByte());
if (Pokeball != 0x00)
{
ms.Position = 0x86;
ms.WriteByte(0x00);
ms.Position = 0x83;
ms.WriteByte(Convert.ToByte(Pokeball));
}
//Removes Pokethlon stats.
ms.Position = 0x87;
ms.WriteByte(0x00);
//Updates checksum.
ms.Position = 0x08;
Checksum = 0;
for (int j = 0; j < 64; j++)
{
Checksum += Convert.ToUInt32(ms.ReadByte()) + (Convert.ToUInt32(ms.ReadByte()) * 0x100);
Checksum = (Checksum - ((Checksum / 0x10000) * 0x10000));
}
ms.Position = 0x06;
ms.WriteByte(Convert.ToByte((Checksum) - ((Checksum / 0x100) * 0x100)));
ms.WriteByte(Convert.ToByte(Checksum / 0x100));
//Saves new file.
Console.WriteLine(PKMName + " was shifted.");
OutputPath = args[i].Substring(0, args[i].Length - 4) + "_Shifted.pkm";
ms.Position = 0x00;
File.WriteAllBytes(OutputPath, ms.ToArray());
}
}
else
{
Console.WriteLine("Please drag a .pkm file on to the exe.");
Console.ReadLine();
}
}
}
}
-
October 1st, 2010, 04:21 PM
#6
Re: Problem with args
Here's how to debug this:
1) Set the command line params in debug mode.
Right click on the project in the Solution Explorer and choose "Properties"
Click on the debug tab
Enter the cmd line args into the "Command line Arguments" textbox
2) Modify the main method
from
Code:
static void Main(string[] args)
{
UInt32 PID = 0x00, Letter = 0x00, ReadLetter = 0x00, Pokeball = 0x00, Checksum = 0x00;
[...]
}
to
Code:
static void Main(string[] args)
{
var currentDirectory = Environment.CurrentDirectory;
UInt32 PID = 0x00, Letter = 0x00, ReadLetter = 0x00, Pokeball = 0x00, Checksum = 0x00;
[...]
}
3) Check the currentDirectory value. Is it where the table.tbl file is located?
4) Try removing the command line arguments made in step 1). Perform step 3). Is it different?
I would be surprised if the currentDirectory value changes whether there are command line parameters or not.
-
October 1st, 2010, 11:20 PM
#7
Re: Problem with args
i added the line
Code:
static void Main(string[] args)
{
Console.WriteLine(Environment.CurrentDirectory);
Console.ReadLine();
UInt32 PID = 0x00, Letter = 0x00, ReadLetter = 0x00, Pokeball = 0x00, Checksum = 0x00;
[...]
rebuilt the program. if double clicked
Code:
C:\Users\Kazo\documents\visual studio 2010\Projects\pokeshift\pokeshift\bin\Release
if drag and drop test file from desktop
Code:
C:\Users\Kazo\Desktop
if i run it from the compiler in debug mode with the argument set
Code:
C:\Users\Kazo\documents\visual studio 2010\Projects\pokeshift\pokeshift\bin\Debug
-
October 2nd, 2010, 01:36 PM
#8
Re: Problem with args
It seems reasonable.
Do you understand why it behaves this way?
Do you know how to change this behavior?
-
October 3rd, 2010, 06:36 AM
#9
Re: Problem with args
Originally Posted by Arjay
It seems reasonable.
Do you understand why it behaves this way?
Do you know how to change this behavior?
I don't know. This is the first time I ever tried to write a console application that requires arguments. I usually just use a window form with an open button.
-
October 3rd, 2010, 07:35 AM
#10
Re: Problem with args
Originally Posted by KazoWAR
I don't know. This is the first time I ever tried to write a console application that requires arguments. I usually just use a window form with an open button.
The reason for this is because the Environment.CurrentDirectory property changes depending on how your app gets started up. In fact, any assembly can change this property at any time while your app is running.
For this reason you shouldn't rely on the CurrentDirectory property (and as a result should rely on specifying just the file name when opening files). Instead specifiy the full file path by getting the location of the exe.
Fortujnately, it's real easy to do this:
Code:
var appDirectory = Path.GetDirectoryName( AppDomain.CurrentDomain.SetupInformation.ConfigurationFile );
using( var sr = StreamReader( Path.Combine( appDirectory, "Table.tbl" ) ) )
{
// and so on
}
Tip: The 'using' syntax above will automatically close and dispose the streamreader object. This simplifies the code and ensures that the object gets properly cleaned up. Generally you can use a using block on any object where you normally call Dispose( ).
-
October 3rd, 2010, 07:53 AM
#11
Re: Problem with args
Originally Posted by Arjay
The reason for this is because the Environment.CurrentDirectory property changes depending on how your app gets started up. In fact, any assembly can change this property at any time while your app is running.
For this reason you shouldn't rely on the CurrentDirectory property (and as a result should rely on specifying just the file name when opening files). Instead specifiy the full file path by getting the location of the exe.
Fortujnately, it's real easy to do this:
Code:
var appDirectory = Path.GetDirectoryName( AppDomain.CurrentDomain.SetupInformation.ConfigurationFile );
using( var sr = StreamReader( Path.Combine( appDirectory, "Table.tbl" ) ) )
{
// and so on
}
Tip: The 'using' syntax above will automatically close and dispose the streamreader object. This simplifies the code and ensures that the object gets properly cleaned up. Generally you can use a using block on any object where you normally call Dispose( ).
Thanks, it is working perfectly now.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|