System.Runtime.InteropServices.COMException when using Interop Word document.SaveAs method - c#

Essentially I need to create a PDF archiver that saves the content of a MailItem into a PDF file.
The code is below:
mailItem.BodyFormat = Outlook.OlBodyFormat.olFormatHTML;
string pdfPath = Path.Combine(fullPath + fileName + ".pdf");
Microsoft.Office.Interop.Word.Document doc = mailItem.GetInspector.WordEditor;
doc.SaveAs(pdfPath, Microsoft.Office.Interop.Word.WdSaveFormat.wdFormatPDF);
The exception happens on the .SaveAs method. What I've essentially boiled it down to, is that it has something to do with the file path, as I tried changing the file path to be shorter, to which the exception did not occur. The problem is, that it has to be in the longer file path structure. I did also consider that maybe it reached the max length of a file path (255), but from what I could tell by running pdfPath.Length, the length came out to be 81.
Does anyone have any ideas?

I looked into this a bit more, turns out that when working with file paths, you can easily use a single / for navigating the path, say for example: C:/User/Desktop.
This is the case, UNTIL you work with Word documents. Word doesn't appreciate single /, but prefers double \\. So, C:/User/Desktop becomes C:\\User\\Desktop.
Reason why I'm saying this, is because, while there is a File path Max length, I did not reach it.
The problem seemed to happen because there was a space in a folder name, like: C:/User/Desktop/Folder Name.
I then used the double backslash instead, and it worked perfectly.

Related

Use Path.GetFileNameWithoutExtension method in C# to get the file name but the display is not complete

This is the simple C# code I wrote :
string file = #"D:\test(2021/02/10).docx";
var fileName = Path.GetFileNameWithoutExtension(file);
Console.WriteLine(fileName);
I thought I would get the string "test(2021/02/10)" , but I got this result "10)".
How can I solve such a problem?
I just wonder why would you want such behavior. On windows slashes are treated as separator between directory and subdirectory (or file).
So, basically you are not able to create such file name.
And since slashes are treated as described, it is very natural that method implementation just checks what's after last slash and extracts just filename.
If you are interested on how the method is implemented take a look at source code

String has a line break at the end (for no reason) in C#

I'm currently writing an application in .NET which reads from a file - in that file, there is a path to another file written. The application then prints the content of that file.
This is an example:
File 1:
D:\Path\To\My\File.txt
SOME OTHER STUFF
File 2:
Hello, world!
When I run my application, it throws an error saying the syntax of the path is invalid. I tried seeing the actual string it takes from File 1, so I did this:
string testString = File.ReadAllText(file); // file is a variable that's already created, which is just a string with the path of File 1.
File.WriteAllText("test.txt", $"'{testString}'");
I looked into the newly created test.txt and saw this.
'D:\Path\To\My\File.txt
'
Why is there a line break before the second quote? I tried googling this with no success. Please help me with this, I am new to C#.
Edit 1:
I tried using File.ReadAllBytes(), but the results were the same.
This is the outcome:
'D:\Georges\Desktop\G\test2.g
'
And this is my code:
byte[] testString = File.ReadAllBytes(file);
File.WriteAllBytes("test.txt", testString);
Edit 2:
When I deleted everything from the file EXCEPT that one line, it worked. That's good, but I do want to be able to add more lines to my file without it not working.
maybe you should use File.ReadLines instead of File.ReadAllText. something like this:
string testString = File.ReadLines(file).ToList()[0]; // file is a variable that's already created, which is just a string with the path of File 1.
File.WriteAllText("test.txt", $"'{testString}'");
You don't show your code, so I cannot be sure this is your problem, but from experience, it looks like it is..
Your filename probably has an unseen character inside at the end of it, so when you copy-paste the filename into the text-file you also copied it with that special character.
As some special characters are unseen the counter-intuitive thing that happens here is that you don't expect your file-name that looks to you like 'test2.g' to actually contain 'test2.g'+chr(13) - where char-13 is i.e. a linefeed character.

How to avoid path or directories manipulation in the file upload function?

In the file upload function that I am working on it, one important issue is to have the path where I can save the image user uploaded. In the following code, I already specified the folder within the web-based application folder for saving the uploaded files. My instructor told me that I still have a security hole with these following lines in the code-behind of asp.net UploadFile control and I don't know why!!!
string path = #"~\Images\";
string comPath = Server.MapPath(path + "\\" + FileUpload1.FileName);
Could you please tell me how to prevent this kind of security hole?
UPDATE:
Could anyone tell me how to avoid this kind of security hole? I am still trying to find something to make these two lines secure.
My instructor told me that I still have a security hole with these following lines in the code-behind of asp.net UploadFile control and I don't know why!!!
Imagine what would happen if the client send something like ..\..\foo.jpg as file name.
A fairly simple fix is to make sure the file name has no \ or / characters in it, by stripping away everything up to the first such character. (This is a good idea anyway, since browsers vary in their treatment of upload file names: some will send the full path, some just the plain file name and some may even send a fake path instead.)
The easy way to do this is with a Regex:
string fileName = Regex.Replace( FileUpload1.FileName, #"(?s)^.*[\\/]", "" );
Note that, depending on your OS and file system, there are other characters that could potentially cause problems as well. The safest option, in general, is to strip away all characters except those you know are safe, something like this:
string safeFileName = Regex.Replace( fileName, #"[^A-Za-z0-9\-._() ]", "" );
You may also want to further ensure that the file name has an extension that matches the type you expect the file to have.

Validating File Path w/Spaces in C#

I'm something of a n00b at C# and I'm having trouble finding an answer to this, so if it's already been answered somewhere feel free to laugh at me (provided you also share the solution). :)
I'm reading an XML file into a GUI form, where certain elements are paths to files that are entered into TextBox objects. I'm looping through the controls on the form, and for each file path in each TextBox (lol there's like 20 of them on this form), I want to use File.Exists() to ensure it's a valid file.
The problem with this is that the file path can potentially contain spaces, and can potentially be valid; however File.Exists() is telling me it's invalid, based entirely on the spaces. Obviously I can't hard-code them and do something like
if (File.Exists(#"c:\Path To Stuff"))
and I tried surrounding the path with ", like
if (File.Exists("\"" + contentsOfTextBox + "\""))
but that didn't make a difference. Is there some way to do this? Can I escape the spaces somehow?
Thank you for your time. :)
File.Exists works just fine with spaces. There is something else giving you a problem I'll wager.
Make sure your XML reader isn't failing to read the filename (parts of XML do not allow spaces and some readers will throw an exception if they encounter one).
#"c:\Path To Stuff"
The above could be a directory not a file!
Hence you would want to use Directory.Exists!
#"c:\Path To Stuff\file.txt"
If you did have a file on the end of the path then you would use File.Exists!
As the answer said, File.Exists works with spaces, if you are checking for existence of a Directory however, you should be using Directory.Exists
What is the exact error that you get when File.Exists says it is invalid?
I suspect that you are passing a path to a directory and not a file, which will return false. If so, to check the presence of a directory, use Directory.Exists.
To echo Ron Warholic: make sure the process has permissions over the target folder. I just ran into the same "bug" and it turned out to be a permissions issue.
Did you remember to replace \ with \\ ?
You need to use youtStringValue.Trim() to remove spaces leading/trailing, and Replace to remove spaces in the string you do not want.
Also, rather use System.IO.Path.Combine rather to combine these strings.
You can use # on string variables:
string aPath = "c:\Path To Stuff\text.txt";
File.Exists(#aPath);
That should solve any escape character problems because I don't think this really looks like the spaces being the problem.
hi this is not difficult if you can convert the name of the path to a string array then go through one by one and remove the spaces
once that is done just write() to the screen where you have the files, if it is xml then your xmlmapper will suffice
file.exists() should only be used in certain circumstances if you know that it does exist but not when there can be space chars or any other possible user input

File paths with non-ascii characters and FileInfo in C#

I get a string that more or less looks like this:
"C:\\bláh\\bleh"
I make a FileInfo with it, but when I check for its existence it returns false:
var file = new FileInfo(path);
file.Exists;
If I manually rename the path to
"C:\\blah\\bleh"
at debug time and ensure that blah exists with a bleh inside it, then file.Exists starts returning true. So I believe the problem is the non-ascii character.
The actual string is built by my program. One part comes from the AppDomain of the application, which is the part that contains the "á", the other part comes, in a way, from the user. Both parts are put together by Path.Combine. I confirmed the validity of the resulting string in two ways: copying it from the error my program generates, which includes the path, into explorer opens the file just fine. Looking at that string at the debugger, it looks correctly escaped, in that \ are written as \. The "á" is printed literarily by the debugger.
How should I process a string so that even if it has non-ascii characters it turns out to be a valid path?
Here is a method that will handle diacritics in filenames. The success of the File.Exists method depends on how your system stores the filename.
public bool FileExists(string sPath)
{
//Checking for composed and decomposed is to handle diacritics in filenames.
var pathComposed = sPath.Normalize(NormalizationForm.FormC);
if (File.Exists(pathComposed))
return true;
//We really need to check both possibilities.
var pathDecomposed = sPath.Normalize(NormalizationForm.FormD);
if (File.Exists(pathDecomposed))
return true;
return false;
}
try this
string sourceFile = #"C:\bláh\bleh";
if (File.Exists(sourceFile))
{
Console.WriteLine("file exist.");
}
else
{
Console.WriteLine("file does not exist.");
}
Note : The Exists method should not be used for path validation, this method merely checks if the file specified in path exists. Passing an invalid path to Exists returns false.
For path validation you can use Directory.Exists.
I have just manuall created a bláh folder containing a bleh file, and with that in place, this code prints True as expected:
using System;
using System.IO;
namespace ConsoleApplication72
{
class Program
{
static void Main(string[] args)
{
string filename = "c:\\bláh\\bleh";
FileInfo fi = new FileInfo(filename);
Console.WriteLine(fi.Exists);
Console.ReadLine();
}
}
}
I would suggest checking the source of your string - in particular, although your 3k rep speaks against this being the problem, remember that expressing a backslash as \\ is an artifact of C# syntax, and you want to make sure your string actually contains only single \s.
Referring to #adatapost's reply, the list of invalid file name characters (gleaned from System.IO.Path.GetInvalidFileNameChars() in fact doesn't contain normal characters with diacritics.
It looks like the question you're really asking is, "How do I remove diacritics from a string (or in this case, file path)?".
Or maybe you aren't asking this question, and you genuinely want to find a file with name:
c:\blòh\bleh
(or something similar). In that case, you then need to try to open a file with the same name, and not c:\bloh\bleh.
Look like the "bleh" in the path is a directory, not a file. To check if the folder exist use Directory.Exists method.
The problem was: the program didn't have enough permissions to access that file. Fixing the permissions fixed the problem. It seems that when I didn't my experiment I somehow managed to reproduce the permission problem, possibly by creating the folder without the non-ascii character by hand and copying the other one.
Oh... so embarrassing.

Categories

Resources