C# code not creating directory or saving file - c#

I'm making an Outlook plugin which will automatically save messages to a file server when received. This part of the code simply doesn't do what it's asked to do!
//RelevantDirectory[0] is the root folder where I want to save stuff, and sits on a mapped network drive where I have full admin permissions.
System.IO.Directory.CreateDirectory(RelevantDirectory[0] + "\\Email Correspondence\\");
System.IO.Directory.CreateDirectory(RelevantDirectory[0] + "\\Email Correspondence\\Outgoing");
mail.SaveAs(RelevantDirectory[0] + "\\Email Correspondence\\Outgoing\\" + mail.SenderName + " - " + string.Format("text-{0:yyyy-MM-dd_hh-mm-ss-tt}", mail.ReceivedTime) + ".msg");
System.Windows.Forms.MessageBox.Show(System.IO.File.Exists(RelevantDirectory[0] + "\\Email Correspondence\\Outgoing\\" + mail.SenderName + " - " + string.Format("text-{0:yyyy-MM-dd_hh-mm-ss-tt}", mail.ReceivedTime) + ".msg").ToString()); //returns True!
The MessageBox returns True, yet the file isn't actually there! The CreateDirectory code also doesn't create the directory - and I'm sure that the filepath in the program is correct. I understand from this link that this could have something to do with filesystem virtualisation. If so, how do I get around the problem?
One more point is that if I point mail.SaveAs to the Desktop folder, it saves it.
EDIT For some bizarre reason, using Path.Combine() worked. Credit to Sinatr. Thanks for your hints everyone.

The problem is in the line:
string.Format("text-{0:yyyy-MM-dd_hh-mm-ss-tt}", mail.ReceivedTime)
When converted to string it becomes somthing like : 1/1/2014 12:35:35 PM
when creating files a '/' and ':' are illegal characters , so for the minimal amount change I suggest you append a couple Replace functions at the end of your string.Format like this:
string.Format("text-{0:yyyy-MM-dd_hh-mm-ss-tt}", mail.ReceivedTime).Replace('/','-').Replace(':',' ')

Related

How to read and write csv file when it is opened with Excel by the user in parallel with C#?

This is the first question I asked on stackoverflow, very exciting. So sorry about my grammar and other type mistakes, I would appreciate if you correct them. I want to write a program that reads a csv file if it exists in the specific folder first, stores it in List variable, add some new lines and writes it to the same file. This process will be repeated continuously in a while block.
While the file is being read and written by the program, if it is opened with Notepad, it doesn't give an error and the program could access the file in parallel. But if it is opened with Office Excel, program gives error that says "file access is denied because it is used by another process..". I want to ask you that:
1) Is it possible to give priority to the program, so program can still access the file but user cannot? Or is it possible both program and user can access the file?
2) If the solution is opening the file with Notepad, is there a way to set default program for this file as Notepad? Or how can I change default program for csv files as Notepad from C#?
Reading and writing parts of the code is as bellows:
List<string> csvLines = new List<string>();
string address = folderpath + #"\PLC_LOGLARI";
if (!Directory.Exists(address))
Directory.CreateDirectory(address);
string fileAddress = address + #"\" + fileName + "_" + machineNo + "_1.csv";
if (Directory.EnumerateFiles(address).Any(f => f.Contains(fileName + "_" + machineNo)))
{
string[] addressArray = Directory.GetFiles(address, fileName + "_" + machineNo + "*.*");
FileInfo fileInformation = new FileInfo(addressArray[addressArray.Length - 1]);
long fileSize = fileInformation.Length;
if (fileSize > 5000000)
{
int fileNo = int.Parse(addressArray[addressArray.Length - 1].Substring(addressArray[addressArray.Length - 1].LastIndexOf('_') + 1, 1)) + 1;
fileAddress = addressArray[addressArray.Length - 1].Substring(0, addressArray[addressArray.Length - 1].LastIndexOf('_') + 1) + fileNo.ToString() + ".csv";
}
else
{
fileAddress = addressArray[addressArray.Length - 1];
csvLines = File.ReadAllLines(address).ToList();
}
}
else
{
string[] headings = makeHeadings();
csvLines.Add(headings[0]);
csvLines.Add(headings[1]);
}
string newLine = "";
// some operations and calculations for newLine
// some operations and calculations for newLine
// some operations and calculations for newLine
newLine = newLine.Substring(1, newLine.Length-1);
csvLines.Add(newLine);
File.WriteAllLines(fileAddress, csvLines.ToArray());
Thanks for your help.
For question 2: In order to change the default program, if you are using Windows, you could click start and find/type 'Default Programs'. Depending on the version of windows, basically find 'Associate a file type of protocol with a program' or 'choose a default application by file type' and adjust the csv file to use a new default program.
I would be very careful if both program and notepad are able accessing the file in the same time. The reason why it was blocked in the first place was to prevent overridding the content of the file, thus probably test it first if you open it in the program and notepad. Then the program make some update - and you also make a different update with the notepad. Would both changes be recorded? As I suspect the 'last save' win in which you may lost some of your changes.
For question 1: I was guessing that whoever open the file first got the lock of that file. As such, if Excel was opening the file - then the program would have that error. Vice versa, if the program had opened the file - then the Excel may have problem opening that file. I'm not sure how to give priority to the program.

Unity3D: Finding folder path when Building the project

I am extracting some information from several text files in different folders. For that purpose I created an application with several Input Fields to write the folders' name that I want to go. Everything went well in Editor Mode.
However when I build the project and run the ".exe" file created, it can't find the text files I want. I show below the code I am using to extract the files. The first data.path is the one I used on my Editor and worked well while the second (commented) data.path is one trial that I tried by placing my folder on the ".exe" Data folder. But it didn't work...
data.motion = input_text;
data.subjectName = input_text2;
data.path = "C:/Users/Matias/Desktop/Acquisition_Data/Kinect1/" + data.subjectName + "/" + data.motion + ".txt";
/*data.path = Application.dataPath + "/Acquisition_Data/Kinect1/" + data.subjectName + "/" + data.motion + ".txt";*/
data.lines = System.IO.File.ReadAllLines(data.path);
I can't get any explanation why any of these methods work when I build the application.
I am using C# and running on Windows10.
You really can't do that because Unity encodes the files into binary form and renames them too. You have to move the txt file after building then you can access it directly. I answered similar question like this yesterday so I will post the link to the answer. Do do things I mentioned in this answer below.
Unity3D loading resources after build
Then remove the Texture2D stuff and replace File.ReadAllBytes(imagePath); with System.IO.File.ReadAllLines(data.path); and that should work.
This is the problem of using Relative path or using absolute path.
If absolute path doesn't work try relative path.
eg.
../name.txt
put your name.txt in asset or somewhere you can point with.
If your texts are static (never more, never less) then you could simply use TextAsset : http://docs.unity3d.com/ScriptReference/TextAsset.html
Make prefabs from text assets;
Put the prefabs into your scene;
Let the user what prefab(s) to load text(s) from.

Deleted file still exists?

I am trying to save a backup of some data. If the backup exists then I want to delete it, give the most recent file the name of the backup file, and then save the new file as the most recent file.
The problem I am running into is that when I delete an existing file I still cannot save another file under the same name. The system still thinks that the file exists, and indeed the file isn't deleted at the point where the program throws the exception even though the two lines are right after each other. The only thing I can think of is that that the "delete" operation hasn't had time to complete by the time the move operation wants to execute. But I do not know how to fix it.
The code looks something like this.
File.Delete(filePath.Substring(filePath.Length - 4) + ".bak");
File.Move(filePath, filePath.Substring(0, filePath.Length - 4) + ".bak");
I thought of setting a timer in order to execute the move function later, but it seems to me that this would probably be a very sloppy and dangerous way of handling the problem. In addition, the amount of time that one needs to wait might have to vary from system to system. So I am thinking that there must be a better way.
The problem has probably to do with the fact that you use two different .Substring methods: String#Substring(int) and String#Substring(int,int). Indeed:
File.Delete(filePath.Substring(filePath.Length - 4) + ".bak");
// ^ with one int
File.Move(filePath, filePath.Substring(0, filePath.Length - 4) + ".bak");
// ^ with two ints
And unfortunately, the two are not semantically equivalent. The one with one int is the start index. So given that filePath is equal to test.txt, the file you aim to remove is .txt.bak and next you aim to move a file to test.bak. Or running this with Mono's C# emulator:
csharp> String filePath = "test.txt";
csharp> filePath.Substring(filePath.Length - 4) + ".bak"
".txt.bak"
csharp> filePath.Substring(0, filePath.Length - 4) + ".bak"
"test.bak"
Please update it with:
File.Delete(filePath.Substring(0,filePath.Length - 4) + ".bak");
// ^ added zero
File.Move(filePath, filePath.Substring(0, filePath.Length - 4) + ".bak");
Another more elegant and less error prone way is evidently to use a variable in between such that you are sure, you are talking about the same file:
String backupfile = filePath.Substring(0, filePath.Length - 4) + ".bak";
File.Delete(backupfile);
File.Move(filePath,backupfile);
Finally it's not recommended to do path processing yourself: use dedicated methods to join and manipulate file paths.
I tried your code with a little change and it worked fine. I only changed how you defined the backup file name, because the file extension can be more or less than 3 chars:
string backupPath = Path.GetFileNameWithoutExtension(filePath) + ".bak";
File.Delete(backupPath);
File.Move(filePath, backupPath);
But if it does not work for you, try to rename the backup to lets say "*.bak2" and then delete that one.
Hope that helps...

C# - Check if unix folder exists

I need to verify that a unix folder exists, from my C# application using SharpSsh.
I thought of trying this:
SshExec.RunCommand("-d " + folder)
But the result is always '2' regardless if the folder is there or not. I could implement something using:
Sftp.GetFileList(folder)
But prefer not to because this folder may contain numerous files and It causes a delay while all of them are retrieved which is not elegant.
Any ideas?
Edit:
I tried this:
string folder = "/foldername";
string result = sshExec.RunCommand("[ -d " + folder + "] && echo 'true' || echo 'false'");
if (result == "false")
throw new Exception("Directory " + foldername+ " + is not found.");
String 'result' is set as "false\n" even though the directory exists. If I skip the check I can work with the directory without problems.
Use
SshExec.RunCommand("ls -la " + folder)
or
SshExec.RunCommand("ls " + folder)
if your folder is not hidden and you dont need size information
Cheap command that will fill your output string with permissions and folder info if exists

moving a files from one folder to another

I am taking a file with a name of sfile
In my method I am doing like this way
File.Copy(sSFile, Failure + "\\" + Path.GetFileName(sSFile)) ''''''''''FAILURE FOLDER"""""
fileCounter += 1
File.move(sSFile, BACKup + "\\" + Path.GetFileName(sSFile)) ''''''''''BACKup FOLDER"""""
fileCounter += 1
where failure and backup are different folders
But it iss throwing an error : This process is using by some other process
Look at MSDN example. Hope it'll help.
Get the Path First, and then Copy the File, and then do the Same then Move the File.
I am guessing your trying to get the Filename when your already holding on to it to Copy and or Move It.
Use
File.Copy(sSFile, Path.Combine(Failure, Path.GetFileName(sSFile)), bool_overrideflag);

Categories