Since .NET offers an amazing class: System.IO.FileInfo, it's almost impossible to fudge things up with paths and file operations like creation, opening, etc.
Imagine that you use the FileInfo class in a script in RunUO to initialize a text file for dumping an error log and you wanted it to be "relative" to the RunUO server executable in the Data directory, you wouldn't have to do anything more than construct the FileInfo object as simply as:
Code:
FileInfo fi = new FileInfo( @"Data\Error.txt" );
Not sure if there is a more suitable method to detect and create missing files, but I commonly use this when not needing to open a stream:
Code:
if( !fi.Exists )
{ fi.Create( ).Close( ); }
There is also a mirror class for directories too, System.IO.DirectoryInfo, which provides the same functions as FileInfo with slightly different methods:
Code:
DirectoryInfo di = new DirectoryInfo( @"NewDirectory\NewSubDirectory" );
The above would initialize the path "relative" to the RunUO server executable, just as with FileInfo.
Directory creation is slightly different, because the Create function does not return a stream (You can't read/write a directory on the byte-level, because it's simply a file-system index entry).
Code:
if( !di.Exists )
{ di.Create( ); }
So the results of the above code would be:
File 'Error.txt' is created in the Data directory within the RunUO server executable's "relative" path.
Directories 'NewDirectory' is created within the RunUO server executable's "relative" path and the directory 'NewSubDirectory' is created within 'NewDirectory'.
There will be errors if the file/directory names are not supported, so it's advisable to use try/catch when creating files/directories.