Find and replace text in .docx file without opening the file - c#

I have a template .docx file where I have to replace the placeholder. I've used the code from c# word interop find and replace everything to replace the name in my word file. That works just fine.
object fileName = GetFilePath();
Microsoft.Office.Interop.Word.Application wordApp = new Microsoft.Office.Interop.Word.Application { Visible = true };
Microsoft.Office.Interop.Word.Document aDoc = wordApp.Documents.Open(fileName, ReadOnly: false, Visible: true);
aDoc.Activate();
FindAndReplace(wordApp, "firstname", "Max");
aDoc.Save();
This implementation does open the word file.
My question is, if there is any way to replace the text without opening the file?

To partially change any file you do need to open it first, there is no other way except completely rewriting it every time with contents stored elsewhere like in your application's memory for example.

If you just want to hide the fact that it is open for the user, simply change this parameter:
Visible: false
The file will still be opened, but it will not display a window.
Note that this will still affect the file in the same way as when it is opened normally (other users may not be able to edit it etc).

Related

MSProject Add-In to convert .mpp in .pdf with given name and date

I am developing an Add-In for MSProject 2013 and higher.
I want to safe/convert the opened .mpp file into an .pdf file without having an additional dialog for the user. He just presses the button an gets an notification when everything is done.
I need to save it in a spacific path and user a defined start and end date.
I tried the SaveAs-methode, but since it takes an MSProject.PjFileType as input and the is no option for pdf, I can't use this. PjFileFormat Enumeration
An other approche was using the DocumentExport-methode.
app.DocumentExport(#"D:/doc_exportqwre.pdf", MSProject.PjDocExportType.pjPDF, true, true, false, System.DateTime.Now, System.DateTime.Now.AddDays(42));
But in this case i only see 3 weeks at once. It is zoomed in and haven't found a way to change this. Changing the View in MSProject, before exporting does not help.
A third way is using the Windows10 pdf-printer:
// generate a file name as the current date/time in unix timestamp format
string file = (string)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds.ToString();
// the directory to store the output.
string directory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
// initialize PrintDocument object
PrintDocument doc = new PrintDocument()
{
PrinterSettings = new PrinterSettings()
{
// set the printer to 'Microsoft Print to PDF'
PrinterName = "Microsoft Print to PDF",
// tell the object this document will print to file
PrintToFile = true,
// set the filename to whatever you like (full path)
PrintFileName = Path.Combine(directory, file + ".pdf"),
}
};
doc.Print();
but this way I can not give the starting and end date. This results in having way to many pages I do not need.
Is there any chance to achieve my goal with changing one of my solutions or is there any other option?
After not finding a proper solution, i used the windows 10 Printer and simulated keyboard events to insert the path in the dialog, which opens. With Enter i start the printing.
I know it is not a nice solution, but it is the onlyway i got it to work

How to remove the 'Read only recommended' option in a Word document using c#?

I'm working in an application that interact with Word. We import documents in our database then allow the user to modify those documents using Microsoft Word via NetOffice.WordApi.
We are having some issues when the document is marked as read-only, everytime is opened, we get a 'Save As' word dialog that gives you the option of creating a temporal copy of the document to allow you to make changes in the document.
My question is as follow: How can remove the read-only word mark of the document and re-save the document without the mark? I can remove the option manually from word following the instructions in the link below, but I want to automatise that process by code.
The author would like you to open this as read-only
** PLEASE BEFORE ANSWER NOTICE THE FOLLOWING: It's not the read-only property in the file at windows level, it's not an issue with the windows permision attibute. The file attributes are NOT Read-only the property is inside the word document. So changing the windows file permision attributes by code doesn't work, actually the files are not read-only when you check the file properties in windows, it's a word attribute which means the author marked the document as read-only when he saved it and will stop you to modify the file using word (file can be changed using a different software, it just read-only for word). Please don't sent me links about how to change permissions in windows at that's not the case, check the link for more info. **
Many thanks for your time.
The option you want to set is the Document.ReadOnlyRecommended property of the Word document.
When you open a Word document, you can actually set the ReadOnly property with the third argument in the Document.Open method. That argument won't, however, override the read-only recommended setting on a saved document. So if your document is saved with read-only recommended option, it will be opened as read-only when calling Document.Open.
So I think that you have two option:
Option 1
Set the Document.ReadOnlyRecommended to false before the Document is saved for the first time, similar to this
objDoc.ReadOnlyRecommended = false;
Option 2
If the document already is set to read-only recommended, you need to save the document as a new file with the Document.ReadOnlyRecommended property set to false using the Document.SaveAs2 method.
Your code might look like this:
object missing = System.Reflection.Missing.Value;
object readOnly = false;
object fileName = #"C:\User\MyFile.docx";
object newFileName = #"C:\User\MyNewFile.docx";
var objApp = new Application();
var objDoc = objApp.Documents.Open(ref fileName, ref missing, ref readOnly);
if (objDoc.ReadOnlyRecommended)
{
objDoc.SaveAs2(ref newFileName, ref missing, ref missing, ref missing, ref missing, ref missing, ref readOnly);
}
objDoc.Close();
objApp.Quit();

Delete .doc duplication during PDF conversion c#

I currently have a program that merges a folder consisting of word docs into one combined file via user input with a FileBrowserDialog. Once files are selected, a 'combine' button applies the code shown below which sources the folder containing the documents, output location and name of the file created.
string fileDate = DateTime.Now.ToString("dd-MM-yy");
string fileTime = DateTime.Now.ToString("HH.mm.ss");
string outcomeFolder = outputFolder;
string outputFileType = ".docx";
string outputFile = "Combined Folder " + fileDate + " # " + fileTime + outputFileType;
string outputFileName = Path.Combine(outcomeFolder, outputFile);
// Combines the file name, output path selected and the yes / no for pagebreaks.
MsWord.Merge(sourceFiles, outputFileName, pageBreaker);
// Message displaying how many files are combined.
MessageBox.Show("A total of " + sourceFiles.Length.ToString() + " documents have been merged", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);}
The MsWord referenced calls a separate .CS file which combines the folder components, output name and a boolean to enable page-breaks. The MsWord also automatically saves the word .doc to the user specified location once the contents of the folder are successfully combined. MsWord.Merge(sourceFiles, outputFileName, pageBreaker);
The issue i'm wanting to address is, when I enable this check box:
if (convert2PDFBox.Checked)
Microsoft.Office.Interop.Word.Application officeApp = new Microsoft.Office.Interop.Word.Application();
officeApp.Documents.Open(outputFileName);
outputFileType = ".pdf";
officeApp.ActiveDocument.SaveAs(outputFileName + outputFileType, WdSaveFormat.wdFormatPDF);
officeApp.Quit();
I want the program to solely create a PDF of the combined folder and not 2 seperate .doc and .PDF files, which it currently does. Since the MsWord.save function is called separately and is essential to the overall function of my program, I was wondering is there a possibility of deleting the initially combined file once conversion of the PDF takes place? e.g. "combinedDocument".Delete - Essentially allowing the copy to take place however not presenting the user with the initial .doc - only the .PDF
Though the issue is small, I would love to get it addressed and welcome any suggestions or advice with this manner. I can also provide any additional information if needed, thank you.
tl;dr - merging program creates an amalgamated Word .doc, which i want to change solely to a PDF when a checkbox is enabled instead of creating a .doc and PDF.
I finally resolved my issue - What I decided to do was manipulate my existing MsWord.cs and create a separate PDF.cs call for my main form:
Rather than save the Word .doc when being merged, I instead used: wordApplication.ActiveDocument.SaveAs(outputFile, Word.WdSaveFormat.wdFormatPDF);
which saved the merged content thus far as a .pdf
This however presented errors with Microsoft Word as I was then prompted to 'Save File As' due to the merged file never actually being saved in a .Doc / .Docx format
I then altered the closing statement of the call,
// Close Word application
wordApplication.Quit(
false, // save changes
By setting the 'Save Changes' setting to False, it removed the 'Save As' prompt which allowed the Word doc. to be dismissed without needing to be saved, thus leaving only the initial PDF created. I then applied the two separate File type calls to each checkbox presented, which allowed the user to enable the outcome format of the merged files.
Thank you for the suggestions regarding the issue.

Converting doc to pdf using Interop.Word C#

I'm using C# to convert the .doc to .pdf. The .doc is on the vendor's site. To get the .doc, we have to click on a button which presents us with option to Open, Save, or Cancel. When the user clicks on Save button, it prompts for the location. The user chooses the location in mapped drive, say, S:\Some Folder\abc.doc, and the actual folder location is \\server\\folder\Some Folder. This is where my program comes in to play. I'm using FileSystemWatcher class in c# with Filter set for .doc files. I can see in debug that the file is found. The folder location is hardcoded and saved as the actual folder location mentioned above. The user and the application has full permission to the folder. However, I'm getting FileNotFoundException when I run the program.
This is what I have
WriteToFile("Starting Word application");
Application word = new Application();
object missing = Type.Missing;
var sourcefile = new FileInfo(path);
// check if the created file ends with .doc.
System.Diagnostics.Debug.WriteLine(path);
if (!path.ToLower().EndsWith(".doc"))
{
return "";
}
word.Visible = false;
WriteToFile("Opening doc as read only");
// open readonly
System.Diagnostics.Debug.WriteLine(sourcefile.FullName);
var doc = word.Documents.Open(FileName: sourcefile.FullName, ReadOnly: true);
The strange thing is sourcefile.FullName doesn't show the hard coded server address that path is set to. It shows the file path as S:\Some Folder\abc.doc, which makes no sense to me. What's going on here, and why can't it find the file?
The OnCreate event can fire when the underlying file is still in use/being written to which can cause problems if you immediately try to access it.
The simple solution is to introduce either an arbitrary delay to allow for the file to be closed by the process creating it, or better a loop with a short delay that attempts to access the file, catches the relevant exception should it occur and retries.
My guess is that you use the wrong FileInfo object. Try to generate an new one or use
System.IO.Path.Combine(#"\\server\folder\Some Folder", "sourcefile.Name")
which you could also use to generate your new FileInfo Object. The object which you are using is probably the one of the user dialogue box which is using the mapped drive. You do also have a typo in your location. \\SERVERNAME\\ isn't an UNC path. There should be only two backslashes on the beginning of the string. It should be
#"\\server\folder\Some Folder"
WriteToFile("Starting Word application");
Application word = new Word.Application();
object missing = Type.Missing;
var sourcefile = new System.IO.FileInfo(path);
string SomeShare = #"\\SomeServer\Someshare\Somepath";
System.IO.FileInfo WorkFile = new System.IO.FileInfo(System.IO.Path.Combine(SomeShare, sourcefile.Name));
// check if the created file ends with .doc.
System.Diagnostics.Debug.WriteLine(path);
if (!path.ToLower().EndsWith(".doc"))
{
return "";
}
word.Visible = false;
WriteToFile("Opening doc as read only");
// open readonly
System.Diagnostics.Debug.WriteLine(sourcefile.FullName);
var doc = word.Documents.Open(FileName: WorkFile.FullName, ReadOnly: true);
}
This works just fine for me, it updates the path to the correct UNC pattern. If the file still isn't accesible you should check if you can open it on the workstation using the UNC path you have generated.

How to open Excel file with Read Only protection?

I have opened Excel file in my C# WinForm Application adding reference to Microsoft.Office.Interop.Excel.dll and using DSO FRAMER CONTROL. But i want to open my excel file with read only protection.I have successfully done this for WORD Application like this
Word.Document wordDoc = (Word.Document)axFramerControl1.ActiveDocument;
Word.Application wordApp = wordDoc.Application;
wordDoc.Protect(Word.WdProtectionType.wdAllowOnlyReading);
In the same i want to do this work for Excel.But i couldn't able to protect Excel file on that way.
string path = "C:\\test-wb.xlsx";
axFramerControl1.Open(path, true,"excel.sheet", "", "");
Excel._Workbook excelDoc =(Microsoft.Office.Interop.Excel._Workbook)axFramerControl1.ActiveDocument;
Excel.Application excelApp =excelDoc.Application;
//What code should i write to protect Excel Workbook with read - only.
excelDoc.Protect(misval, true, misval);//It is not working.
Call theOpen method with third parameter (ReadOnly) = true.
See MSDN documentation :
ReadOnly
Optional Object. True to open the workbook in read-only mode.
The WorkBook class has a Protect method, similar (but not identical) to the one supported by Word. I can't find the COM/interop documentation, but the VSTO documentation covers the same ground, and the method signatures are the same:
Protect
Protects a workbook so that it cannot be modified.
public virtual void Protect (
[OptionalAttribute] Object Password,
[OptionalAttribute] Object Structure,
[OptionalAttribute] Object Windows
)
(This all assumes that what you wanted to achieve was to protect the document, since that's what the Word code does, as opposed to opening the document read only, which is what your narrative seems to be saying, in which case, #gdoron's answer is more suitable

Categories