C# System.IO.File.Exists does not work in Unity - c#

I am trying to locate a file on my computer so I can store my game's login data on that certain file. I have a string that contains the path.
public string path = "C:/Users/DevelopVR/Documents";
//DevelopVR is my username
Then I have this later on:
if (System.IO.File.Exists(path))
{
Debug.Log("Path exists on this computer");
}
else
{
Debug.LogWarning("Path does NOT exist on this computer");
}
I have also tried swapping out this:
else
{
Debug.LogWarning("Path does NOT exist on this computer");
}
With this:
else if (!System.IO.File.Exists(path))
{
Debug.LogWarning("Path does NOT exist on this computer");
}
But every time it logs the error. So I don't know what to do. It seems like other people are having the same problem. Thanks, If you have the answer.

Documents is a Directory, not a File, so instead of checking for File, check for Directory like:
if(File.Exists(path))
{
// This path is a file
ProcessFile(path);
}
else if(Directory.Exists(path))
{
// This path is a directory
ProcessDirectory(path);
}
Remember that if you want to search for a File, your path should have the file name and extension like:
public string path = #"C:/Users/DevelopVR/Documents/MyFile.txt";

"Documents" is not a real path, it's a convenience link to the 'special folder' that Windows provides.
From https://learn.microsoft.com/en-us/dotnet/api/system.environment.specialfolder?view=netcore-3.1
// Sample for the Environment.GetFolderPath method
using System;
class Sample
{
public static void Main()
{
Console.WriteLine();
Console.WriteLine("GetFolderPath: {0}", Environment.GetFolderPath(Environment.SpecialFolder.System));
}
}
/*
This example produces the following results:
GetFolderPath: C:\WINNT\System32
*/

Related

Question about File Paths and opening those files C#

I have Three strings that are set to the current: year, month, day respectively using the "DateTimeNow". and I have set a path to a string of the root folder named "Custom_project" by grabbing the file path from a text file on the desktop.
They are named:
public string CurrentYear;
public string CurrentMonth;
public string CurrentDay;
public string CustomOrderFilePathTopFolder = File.ReadAllText("C:/desktop/Custom_project.txt");
//CustomOrderFilePathTopFolder now ='s C:/desktop/Custom_project/
Okay so I am trying to check to see if a folder exists(Folder Named: "CurrentYear" or in this case "2020" inside of the: "Custom_project" folder) and if not then create the folder with the string, if it does exist then it will then proceed to my next step which is essentially opening the file: "CurrentYear" or "2020, then repeating the same thing but inside of that folder: Custom_project/2020, for month and repeat one last time for day.
So In the end I would have a file path that looks like so: "C:/desktop/Custom_project/2020/07/12".
Now To My Question:
"HOW DO I GO ABOUT CHECKING IF A FILE NAMED "2020" EXISTS INSIDE OF THE CUSTOMPATHFOLDER AND IF IT DOESN'T THEN CREATE THAT FOLDER
I just tried using This(Which doesn't seem to work):
if (CustomOrderFilePathTopFolder == "")
{
MessageBox.Show("ERROR FILE PATH CANNOT BE EMPTY!");
}
else if (!Directory.Exists(CustomOrderFilePathTopFolder + CurrentYear))
{
Directory.CreateDirectory(CustomOrderFilePathTopFolder + CurrentYear);
}
This Does nothing for me so I tried this:
if (CustomOrderFilePathTopFolder == "")
{
MessageBox.Show("ERROR FILE PATH CANNOT BE EMPTY!");
}
else if (!Directory.Exists(CustomOrderFilePathTopFolder + "/" + CurrentYear))
{
Directory.CreateDirectory(CustomOrderFilePathTopFolder + "/" + CurrentYear);
}
Doesn't Work Either So I am At a loss Please Let me know how I would go about this please and thank you a ton!!
Try below steps
you need to first combine path to point proper file/folder
Check File exists or not
If not, then create folder with same name.
using System.IO;
...
var filePath = Path.Combine(CustomOrderFilePathTopFolder, CurrentYear))
if (!File.Exists(filePath))
{
Directory.CreateDirectory(filePath);
}

How to get the Full Path of a File?

I try to get the Full Path of a File. ie. calc
Input: calc
Expected output: C:\WINDOWS\system32\calc.exe
I could find out how to do it with PowerShell:
(Get-Command calc).Source
Or with CommandLine:
where.exe calc
But unfortunately I can not get it done with C#.
The documentation for Get-Command says:
Get-Command * gets all types of commands, including all of the non-PowerShell files in the Path environment variable ($env:Path), which it lists in the Application command type.
So we will need to get the Path environment variable and iterate over the directories it lists, looking for files with extensions that indicate the file is a program, for example "*.com" and "*.exe".
The problem with the Path environment variable is that it can become polluted with non-existent directories, so we will have to check for those.
The case of the filename and extension don't matter, so case-insensitive comparisons need to be made.
static void ShowPath(string progName)
{
var extensions = new List<string> { ".com", ".exe" };
string envPath = Environment.GetEnvironmentVariable("Path");
var dirs = envPath.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string d in dirs.Where(f => Directory.Exists(f)))
{
foreach (var f in (Directory.EnumerateFiles(d).
Where(thisFile => extensions.Any(h => Path.GetExtension(thisFile).Equals(h, StringComparison.InvariantCultureIgnoreCase)))))
{
if (Path.GetFileNameWithoutExtension(f).Equals(progName, StringComparison.InvariantCultureIgnoreCase))
{
Console.WriteLine(f);
return;
}
}
}
Console.WriteLine("Not found.");
}
static void Main(string[] args)
{
ShowPath("calc");
Console.ReadLine();
}
Output:
C:\WINDOWS\system32\calc.exe
There is always the possibility that the current user does not have permission to list the files from somewhere in the path, so checks should be added for that. Also, you might want to use StringComparison.CurrentCultureIgnoreCase for the comparison.
You can get the Pathenvironment variable, split it with ; as delimiter and loop over that result. Then, check if the file path + #"\" + name + ".exe" exists.
var findMe = "calc";
var pathes = Environment.GetEnvironmentVariable("Path").Split(';');
foreach (var path in pathes)
{
var testMe = $#"{path}\{findMe}.exe";
if (File.Exists(testMe))
{
Console.WriteLine(testMe);
}
}
This outputs :
C:\WINDOWS\system32\calc.exe
I do not know about any way of doing that exact thing from C# either. However the paths are usually well known and can be retreived via the SpecialFolders Enumeration:
using System;
using System.Diagnostics;
using System.IO;
namespace RunAsAdmin
{
class Program
{
static void Main(string[] args)
{
/*Note: Running a batch file (.bat) or similar script file as admin
Requires starting the interpreter as admin and handing it the file as Parameter
See documentation of Interpreting Programm for details */
//Just getting the Absolute Path for Notepad
string windir = Environment.GetFolderPath(Environment.SpecialFolder.Windows);
string FullPath = Path.Combine(windir, #"system32\notepad.exe");
//The real work part
//This is the programm to run
ProcessStartInfo startInfo = new ProcessStartInfo(FullPath);
//This tells it should run Elevated
startInfo.Verb = "runas";
//And that gives the order
//From here on it should be 100% identical to the Run Dialog (Windows+R), except for the part with the Elevation
System.Diagnostics.Process.Start(startInfo);
}
}
}
I did not just use System (37) back then, as I wrote it when x32/x86 Systems were still a thing. You would need to check how it resolves nowadays.
Note that most of those paths are duplicated in the PATH System Variable, so you could look it up: https://www.architectryan.com/2018/03/17/add-to-the-path-on-windows-10/
Path Variables in turn go back to the old DOS days. Basically if you gave the Commandline a command/filename it would try the build-in commands, then Executables in the current working Directory (.bat, .com, .exe), and then go look over the path directories to again look for executeables. And only if all that failed, would it complain.
I finally tried to combine all three answers and came up with this:
I post it here in case someone has the same problem.
public static string[] GetPathOf(string cmd)
{
var list = new List<string>();
list.AddRange(Environment.GetEnvironmentVariable("path", EnvironmentVariableTarget.Machine).Split(';'));
list.AddRange(Environment.GetEnvironmentVariable("path", EnvironmentVariableTarget.Process).Split(';'));
list.AddRange(Environment.GetEnvironmentVariable("path", EnvironmentVariableTarget.User).Split(';'));
list = list.Distinct().Where(e=>Directory.Exists(e)).SelectMany(e=> new DirectoryInfo(e).GetFiles()).Where(e=>Regex.IsMatch(e.Name,"(?i)^"+cmd+"\\.(?:exe|cmd|com)")).Select(e=>e.FullName).ToList();
return list.ToArray();
}

full path as the filename

Maybe someone knows a simple solution to my problem.
I do not know the entry of the file so it's not a static value.
It can be changed through the BizTalk gui and there we have a URI through the receiveport. But I do not believe it's accessible that easy. What I want to do is write out the full path as the filename. It works well with the messageID where the file is given a specific filepath name. But the Path-Name where the file was dropped is not working that well.
I keep getting this error :
Message:
Object reference not set to an instance of an object.
the message resource is present but the message is not found in the string/message table
-Does not say me much
Below you can see a snip from my code
internal static string UpdateMacroPathProperty(IBaseMessage baseMessage, string macroPathProperty, string macroDefsFile)
{
if (macroName == "MessageID")
{
contextPropertyValue = baseMessage.MessageID.ToString();
}
else if (macroName == "SourceFileName")
{
contextPropertyValue = Directory.GetCurrentDirectory();
}
}
This is an specific created pipeline. Has anyone encountered this problem or can point me in the right way.
I know that BizTalk has a built in function for this, BizTalk Server: List of Macros as the %SourceFileName% but I'm trying to save this as logs in a specific map structure so that it does not get processed.
It's adapter dependent; some adapters will use the FILE adapter's namespace even though they're not the file adapter, but this is the kind of logic that I've used in the past for this:
string adapterType = (string)pInMsg.Context.Read("InboundTransportType",
"http://schemas.microsoft.com/BizTalk/2003/system-properties");
string filePath = null;
if (adapterType != null)
{
if (adapterType == "FILE")
{
filePath = (string)pInMsg.Context.Read("ReceivedFileName",
"http://schemas.microsoft.com/BizTalk/2003/file-properties");
}
else if (adapterType.Contians("SFTP") && !adapterType.Contains("nsoftware"))
// nsoftware uses the FTP schema
{
filePath = (string)pInMsg.Context.Read("ReceivedFileName",
"http://schemas.microsoft.com/BizTalk/2012/Adapter/sftp-properties");
}
else if (adapterType.Contains("FTP"))
{
filePath = (string)pInMsg.Context.Read("ReceivedFileName",
"http://schemas.microsoft.com/BizTalk/2003/ftp-properties");
}
}
And then you can just fall back to the MessageID if you can't get the file path from any of these.

If a folder does not exist, create it

I use a FileUploader control in my application. I want to save a file to a specified folder. If this folder does not exist, I want to first create it, and then save my file to this folder. If the folder already exists, then just save the file in it.
How can I do this?
Use System.IO.Directory.CreateDirectory.
According to the official ".NET" docs, you don't need to check if it exists first.
System.io   >   Directory   >   Directory.CreateDirectory
Any and all directories specified in path are created, unless they already exist or unless some part of path is invalid. If the directory already exists, this method does not create a new directory, but it returns a DirectoryInfo object for the existing directory.
        — learn.microsoft.com/dotnet/api/
Use the below code as per How can I create a folder dynamically using the File upload server control?:
string subPath ="ImagesPath"; // Your code goes here
bool exists = System.IO.Directory.Exists(Server.MapPath(subPath));
if(!exists)
System.IO.Directory.CreateDirectory(Server.MapPath(subPath));
Just write this line:
System.IO.Directory.CreateDirectory("my folder");
If the folder does not exist yet, it will be created.
If the folder exists already, the line will be ignored.
Reference: Article about Directory.CreateDirectory at MSDN
Of course, you can also write using System.IO; at the top of the source file and then just write Directory.CreateDirectory("my folder"); every time you want to create a folder.
Directory.CreateDirectory explains how to try and to create the FilePath if it does not exist.
Directory.Exists explains how to check if a FilePath exists. However, you don't need this as CreateDirectory will check it for you.
You can create the path if it doesn't exist yet with a method like the following:
using System.IO;
private void CreateIfMissing(string path)
{
bool folderExists = Directory.Exists(Server.MapPath(path));
if (!folderExists)
Directory.CreateDirectory(Server.MapPath(path));
}
This method will create the folder if it does not exist and do nothing if it exists:
Directory.CreateDirectory(path);
You can use a try/catch clause and check to see if it exist:
try
{
if (!Directory.Exists(path))
{
// Try to create the directory.
DirectoryInfo di = Directory.CreateDirectory(path);
}
}
catch (IOException ioex)
{
Console.WriteLine(ioex.Message);
}
using System.IO
if (!Directory.Exists(yourDirectory))
Directory.CreateDirectory(yourDirectory);
if (!Directory.Exists(Path.GetDirectoryName(fileName)))
{
Directory.CreateDirectory(Path.GetDirectoryName(fileName));
}
The following code is the best line(s) of code I use that will create the directory if not present.
System.IO.Directory.CreateDirectory(HttpContext.Current.Server.MapPath("~/temp/"));
If the directory already exists, this method does not create a new directory, but it returns a DirectoryInfo object for the existing directory. >
Create a new folder, given a parent folder's path:
string pathToNewFolder = System.IO.Path.Combine(parentFolderPath, "NewSubFolder");
DirectoryInfo directory = Directory.CreateDirectory(pathToNewFolder);
// Will create if does not already exist (otherwise will ignore)
path to new folder given
directory information variable so you can continue to manipulate it as you please.
Use this code if the folder is not presented under the image folder or other folders
string subPath = HttpContext.Current.Server.MapPath(#"~/Images/RequisitionBarCode/");
bool exists = System.IO.Directory.Exists(subPath);
if(!exists)
System.IO.Directory.CreateDirectory(subPath);
string path = HttpContext.Current.Server.MapPath(#"~/Images/RequisitionBarCode/" + OrderId + ".png");
Use the below code. I use this code for file copy and creating a new folder.
string fileToCopy = "filelocation\\file_name.txt";
String server = Environment.UserName;
string newLocation = "C:\\Users\\" + server + "\\Pictures\\Tenders\\file_name.txt";
string folderLocation = "C:\\Users\\" + server + "\\Pictures\\Tenders\\";
bool exists = System.IO.Directory.Exists(folderLocation);
if (!exists)
{
System.IO.Directory.CreateDirectory(folderLocation);
if (System.IO.File.Exists(fileToCopy))
{
MessageBox.Show("file copied");
System.IO.File.Copy(fileToCopy, newLocation, true);
}
else
{
MessageBox.Show("no such files");
}
}
A fancy way is to extend the FileUpload with the method you want.
Add this:
public static class FileUploadExtension
{
public static void SaveAs(this FileUpload, string destination, bool autoCreateDirectory) {
if (autoCreateDirectory)
{
var destinationDirectory = new DirectoryInfo(Path.GetDirectoryName(destination));
if (!destinationDirectory.Exists)
destinationDirectory.Create();
}
file.SaveAs(destination);
}
}
Then use it:
FileUpload file;
...
file.SaveAs(path,true);
string root = #"C:\Temp";
string subdir = #"C:\Temp\Mahesh";
// If directory does not exist, create it.
if (!Directory.Exists(root))
{
Directory.CreateDirectory(root);
}
The CreateDirectory is also used to create a sub directory. All you have to do is to specify the path of the directory in which this subdirectory will be created in. The following code snippet creates a Mahesh subdirectory in C:\Temp directory.
// Create sub directory
if (!Directory.Exists(subdir))
{
Directory.CreateDirectory(subdir);
}
Derived/combined from multiple answers, implementing it for me was as easy as this:
public void Init()
{
String platypusDir = #"C:\platypus";
CreateDirectoryIfDoesNotExist(platypusDir);
}
private void CreateDirectoryIfDoesNotExist(string dirName)
{
System.IO.Directory.CreateDirectory(dirName);
}

how to read all the subdirectories in a given destination which contain Master File in it

I am having a problem .
My Problem is to read all the subdirectories in a given destination which contain Master file .
I can read subdirectories but i am creating a project which only read given directory which should contain Master file in the directory .
In the given directory a file called Master file should be there.
I want to write the code like if the given directory doesnot contain any Master file in it it should Jump to another Directory.
My source Directory is #"C:\test.
In #"C:\test" there are many folders and subfolders .
the test directory contains "C:\test\test1\test2\test3 . In this path test3 folder contains Master file test1 and test2 doesn't .
I want to write this code something like this,
MLMReader Reader = new MLMReader();
Reader.OpenDirectory(#"C:\test");
if (!File.Exists(test + "\\Master"))
{
//i want to loop the "C"\\" and if test1 does not contain
// Master File then jump to another directory test2, if
//test2 directory contain Master File then the work should
// continue after finishing go to test3
}
Is there any way to do .
Any suggestions for my problem.
I haven't tested, but I'm pretty sure the following will work:
string[] paths = Directory.GetFiles(dirPath, "MasterFile", SearchOption.AllDirectories);
Then you can just foreach over the resulting array, if you want to go through all MasterFiles. Or if you just care about the first result, then it's just paths[0] -- of course, means it does a lil bit extra work finding all matching paths. And you probably don't need a check for an empty array as an index out of bounds would indicate there's no MasterFile (unless you want to catch that and then rethrow as file not found exception or whatever).
Linq-to-FileSystem allows you to perform structured queries on your file system. See the following example:
var dir = new DirectoryInfo(#"C:\test");
// find all subdirectories of test that contains a file / folder called 'Master'
var dirs = dir.Elements()
.Where(d => d.Elements().Any(i => i.Name == "Master"))
this is my code where I program with directorys, hope it will help you.
using System;
using System.IO;
static void Print(string path, int? rec, int? tree, bool color, int? level = 0)
{
if ((rec != null && level > rec) || path == null) return;
if (rec == null) rec = 0;
string[] dir;
string[] fil;
try
{
dir = Directory.GetDirectories(path);
fil = Directory.GetFiles(path);
}
catch(Exception e)
{
Console.WriteLine(e.Message);
return;
}
foreach (string s in dir)
{
WriteSpace(level,tree);
Console.WriteLine(s);
Print(s, rec, tree, color, level + 1);
}
if (color)
{
ConsoleColor def = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Blue;
foreach (string s in fil) // vypis file
{
WriteSpace(level, tree);
Console.WriteLine(s);
}
Console.ForegroundColor = def;
}
else
{
foreach (string s in fil)
{
WriteSpace(level, tree);
Console.WriteLine(s);
}
}
}
private static void WriteSpace(int? level, int? tree)
{
for (int i = 0; i < level*tree; i++)
Console.Write(" ");
}
}
Here's a Recursive Example on how you can traverse a directory structure and look for a certain file, once it is found you can call the corresponding method.
static void Main()
{
TraverseDirectory(#"D:\TestDirectory");
}
static void DoSomethingWithMaster(string path)
{
Console.WriteLine("Found master at {0}", path);
}
static void TraverseDirectory(string directory)
{
var currentDirectory = new DirectoryInfo(directory);
foreach(var dir in currentDirectory.GetDirectories())
{
var currentPath = dir.FullName;
TraverseDirectory(currentPath);
var pathToMasterFile = Path.Combine(currentPath, "Master");
if (File.Exists(pathToMasterFile))
DoSomethingWithMaster(pathToMasterFile);
}
}
I have the following Folder Structure:
D:\TestDirectory\1
D:\TestDirectory\2
D:\TestDirectory\3
D:\TestDirectory\4
D:\TestDirectory\4\Master
D:\TestDirectory\5
And when running the above it prints: Found master at D:\TestDirectory\4
All you need for this is:
using System;
using System.IO;
You can also move TraverseDirectory(currentPath); to the end of the foreach-loop, where you put it depends on when you want to detect the file, do you want to go deep and then climb your way back and check for the Master-file on the way up, or do you want to check for the master file before you enter the next directory?
According to your question, you might want to swap them in my answer and if I understand you correctly, you might not even want to go to the next directory after finding one master-file?
foreach(var dir in currentDirectory.GetDirectories())
{
var currentPath = dir.FullName;
var pathToMasterFile = Path.Combine(currentPath, "Master");
if (File.Exists(pathToMasterFile))
DoSomethingWithMaster(pathToMasterFile);
TraverseDirectory(currentPath);
}
In this example, it does exactly what you are saying in your commented code inside your if. It will first check TestDirectory\1 for a Master file and then go further down the line. If you don't care about any other Master-files in one sub-directory once it is found, you can just nest TraverseDirectory(pathToMasterFile) inside an else-block.
Edit
You might want to use EnumerateDirectories, see MSDN for details.

Categories

Resources