C# program open Word Application but not specific Word Document - c#

The code below is supposed to open a .docx file in my windows directory but instead of opening the file it opens only the Word Application. There is no active word document inside, not even a new document. I notice that under the file tab options like "save, save as, print, Share, Export, and Close" are all grayed out and inactive.
using Microsoft.Office;
using Word = Microsoft.Office.Interop.Word;
class Program
{
static void openFile()
{
string myText = #"‪C:\CSharp\WordDocs\MyDoc.docx";
var wordApp = new Word.Application();
wordApp.Visible = true;
wordApp.Activate();
Word.Documents book = wordApp.Documents;
Word.Document docOpens = book.Open(myText);
}
static void Main(string[] args)
{
//Console.WriteLine("Hello World\n");
openFile();
}
}

Running your code but with a path that doesn't exist does indeed opens Word Application with no document inside. But it does throw a very informative exception as follows:
System.Runtime.InteropServices.COMException: 'Sorry, we couldn't find
your file. Was it moved, renamed, or deleted?
(C:\Users\nonexistantuser...\Test.docx)'
You failed to mention this in your question, but you must get an exception.
So my guess is your path is incorrect.
If the path is correct, i.e. the file exists, another possible scenario is not having appropriate read permissions. In that case again it would open an empty Word Application, but that too should throw an exception albeit a different one:
System.Runtime.InteropServices.COMException: 'Word cannot open the document: user does not have access privileges
(C:\Users\NS799\Desktop\Test.docx)'
So please check if the path exists and if it does, if you have appropriate permissions.

Related

MS Excel Interop - Prevent Sign In Modal When Opening a Restricted Access Workbook

I am using MS Excel Interop to parse information from a collection of Excel files. If one of these Excel files has restricted access, a Windows sign-in modal opens and pauses my program. I would like to skip over these files so that this modal does not appear.
My current code, with various settings to block any Excel warnings:
var application = new Microsoft.Office.Interop.Excel.Application();
application.DisplayAlerts = false;
application.AutomationSecurity = Microsoft.Office.Core.MsoAutomationSecurity.msoAutomationSecurityForceDisable;
var workbook = application.Workbooks.Open(filePath, UpdateLinks: 0, ReadOnly: true, IgnoreReadOnlyRecommended: true, Password: "fakePassword");
I encountered a similar issue with password protected Excel documents, but was able to prevent the enter password modal by setting a fake password in the .Open code above. This causes an exception to be thrown when a file is password protected, which I then catch and the program continues on to the next Excel file.
I was hoping the WriteResPassword option for the Open method would work similarly, but even if I specify this, the Windows sign in still appears.
Any help greatly appreciated!
I'm not particularly happy with this solution, but I have found a workaround for avoiding MS sign-in modals (and many other modals) prior to opening an Excel document.
Before opening the Excel document with MS Excel Interop, I conduct a "zip test" where I zip up the file into a temporary directory, attempt to extract it, and then immediately delete that directory.
private void ZipTest(string xlsxFilePath, string tempDirectoryPath)
{
try
{
Directory.CreateDirectory(tempDirectoryPath);
string zipPath = ZipFile(xlsxFilePath, tempDirectoryPath);
using (ZipArchive zip = System.IO.Compression.ZipFile.Open(zipPath, ZipArchiveMode.Update))
{
zip.ExtractToDirectory(tempDirectoryPath);
}
Directory.Delete(tempDirectoryPath, true);
}
catch (Exception ex)
{
if (Directory.Exists(tempDirectoryPath))
{
Directory.Delete(tempDirectoryPath, true);
}
throw ex; // Do whatever you want
}
}
private string ZipFile(string filePath, string destinationDirectory)
{
string fileName = Path.GetFileName(filePath);
string zipFileName = Path.ChangeExtension(fileName, ".zip");
string destinationPath = $"{destinationDirectory}\\{zipFileName}";
File.Copy(filePath, destinationPath, false);
return destinationPath;
}
Zipping and extracting the file will fail if the workbook has restricted access, is password protected, or otherwise can't be written to. This prevents the MS sign-in modal because the excel doc is never opened.
Note that this only works on xlsx files. Any xls files need to be converted to xlsx first.

This command is not available because no document is open while getting Active document

try
{
Microsoft.Office.Interop.Word.Application WordObj = System.Runtime.InteropServices.Marshal.GetActiveObject("Word.Application") as Microsoft.Office.Interop.Word.Application;
Office.CustomXMLParts currClassification = WordObj.ActiveDocument.CustomXMLParts;
}
catch(Exception ex)
{
//I am getting, This command is not available because no document is open. this error here.
}
When I am using above code, I am getting this error:
This command is not available because no document is open.
Regards
Actually you are trying to access active document when there is no document open in word application so you are getting an error.
Your word application is open but no document is opened in it i.e. you are at home screen of word application as shown in image.
Try to use following code to check whether there are any open documents in your application and then access ActiveDocument
if(WordObj.Documents.Count >= 1)

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 set the active (i.e. foreground) Word document using C#

I have looked and failed to find a solution to my problem. I have developed an Add-in ribbon for Word 2007 which provides an additional set of load and save functions, to allow users to load and save documents from a bespoke system.
I have most of it working - when a user requests a file to be opened, it is downloaded and saved to the AppData folder, and then opened. However, the problem I am having is that if the user for example opens Word and uses this new 'load' function, the blank Word document remains, and Word opens the new document quite happily, but it does not get the focus.
(I'm on Windows 7 and it creates a second 'W' icon in the task bar for the new document, but it doesn't switch to it in the same way that Word would if I'd used the normal 'Open' route.)
I have tried (as a result of suggestions found elsewhere on here) either setting the 'visible' attribute to true, and calling doc.Activate() but neither does what I need. What am I missing? The code I'm using to open the file is below:
private void OK_Click(object sender, EventArgs e)
{
this.Close();
FES.FESServices wService = new FES.FESServices();
int request_id = wService.SubmitRequestFromAddIn(username, password, "RETR", "", textBox1.Text, "", "");
FES.FileRequestResponse response = wService.GetFileMembersFromAddIn(username, password, request_id);
if (response.ResponseType == "RETR")
{
byte[] data = wService.GetBytesForFilename(response.ResponseValue);
//MessageBox.Show("Loaded data for file...");
//MessageBox.Show(Application.UserAppDataPath);
FileStream fs = new FileStream(Application.UserAppDataPath + "\\" + response.ResponseValue.Substring(6).Split('~')[0], FileMode.Create, FileAccess.Write);
fs.Write(data, 0, (int)data.Length);
fs.Close();
object oMissing = System.Reflection.Missing.Value;
Microsoft.Office.Interop.Word.Document doc = Globals.ThisAddIn.Application.Documents.Open(
Application.UserAppDataPath + "\\" + response.ResponseValue.Substring(6).Split('~')[0], Visible:true
);
doc.Activate();
}
}
(I have included this.Close() as the function loading the document is held within a modal dialog box, and without closing it first, Word throws an exception about switching documents with a dialog box open).
Any help gratefully received!
Running this code whilst the modal dialog is showing is interfering with window activation.
I'm not sure exactly what the mechanism is for this interference, but the fix is simple enough. Move the code outside the dialog. Execute this code immediately after the call to ShowDialog returns.

Open file by URL from WPF

I would like to programmatically open a document from a SharePoint URL.
I have the following code:
Process wordProcess = new Process();
wordProcess.StartInfo.FileName
= "http://sharepoint/blank_site_1/document library 1/word document.docx";
wordProcess.StartInfo.UseShellExecute = true;
wordProcess.Start();
This opens a webbrowser window and downloads the file, which is not what I want. If I append
wordProcess.StartInfo.Verb = "OpenAsReadOnly"
as per (the documentation) I get a Win32 Exception "The parameter is incorrect" at wordProcess.Start(), despite the verb being present in wordProcess.StartInfo.Verbs when examining in the debugger.
I have a POC which does this by extracting the default program from the registry, building a command and starting the program with the filename, but I'd rather not go down that route if this can be easily solved, as all I want to do is open a file (the path of which just happens to look like a URL) with the default program.
Just a guess, try this:
wordProcess.StartInfo.FileName = "winword.exe";
wordProcess.StartInfo.Arguments = "\"http://sharepoint/blank_site_1/document_library_1/word document file.docx\"";

Categories