Open file by URL from WPF - c#

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\"";

Related

open winmerge with two documents side by side c#

I am developing a Windows Forms app in c# that will make changes to a document and I want to include a button that will open the before and after in winmerge.
If it is possible, how do I do it?
More Detail:
I want to click a button Show Result with the starting file in the textbox.
It should open winmerge and open this dialog with the original file on the left and updated file on the right.
So far I have:
Process notePad = new Process();
notePad.StartInfo.FileName = "WinMerge.exe";
notePad.StartInfo.Arguments = txtIn.Text;
notePad.Start();
The updated file is in the same directory as the input file one level down in a folder called "UPDATED"
String leftFilePath = "...";
String rightFilePath = "...";
string exe = "winmergeu.exe";
String args = $#"""{leftFilePath}"" ""{rightFilePath}""";
Process.Start(exe, args);

Download File by starting a Chrome Process

I want to download a file by just starting a new Process of Chrome. I've found the parameter "--download", so the solution should be "CHROMEPATH --download URI". ( http://peter.sh/experiments/chromium-command-line-switches/#download )
I wrote the code to start the process in C#, and yes, I know there are other options to do this like webclient, but I don't want to implement the download per se in my code.
string FILEURI = "example.org/file.png";
System.Diagnostics.Process prozess = new System.Diagnostics.Process();
prozess.StartInfo.FileName = #"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe";
prozess.StartInfo.Arguments = "--download " + FILEURI;
prozess.Start();
This works without any problem, but just opening the link "file://FILEURI". So I can't download it without any user interaction.
Chrome always downloads to the download folder. You could try to just get the latest download file, like this:
new DirectoryInfo(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),"Downloads"))
.GetFiles()
.OrderByDescending(f => f.CreationTime)
.First()
This has risks (as outlined by DavidG) as well as the fact the user might download another file, etc. So this is not necessarily the best way.

Access is denied exception when using Process.Start() to open folder

I have a winforms application in C# where I have to open a certain Folder.
I use
System.Diagnostics.Process.Start(pathToFolder);
This results in the following exception:
System.ComponentModel.Win32Exception (0x80004005): Access is denied
at System.Diagnostics.Process.StartWithShellExecuteEx(ProcessStartInfo
startInfo)
at System.Diagnostics.Process.Start()
at System.Diagnostics.Process.Start(ProcessStartInfo startInfo)
at MyApp.openLogFolderToolStripMenuItem_Click(Object sender, EventArgs e)
I have already checked the following things:
The folder exists
The user has rights to the folder (can open it in Explorer)
Another thing is that if I use Process.Start() to open a file inside this folder, it works.
Can anyone give me a hint?Cheers
Edit
My goal is to open the folder in Explorer.
The pathToFolder is something like H:\Something\App.Name\Log
According to Microsoft Doc's the System.Diagnostics.Process.Start(string) runs the file or process (and therefore does not open the folder). For opening a folder, this doc page sugests that you might do this with System.Diagnostics.Process.Start(string, string) where first should be a way to explorer, Total commander or something similar, and second should be a argument telling the used explorer what to do (open the folder pathToFolder).
I suppose that some system variable stores the value for "default folder viewer" but I do not know where. I will try to go for it and return later with the answer.
Hope that it helps.
EDIT: I did some quick digging around and to open the folder the following should do the trick:
System.Diagnostics.Process.Start(Environment.GetEnvironmentVariable("WINDIR") +
#"\explorer.exe", pathToFolder);
Where first argument is a path to classical windows explorer and second is the actual path to the folder itself.
It seem that widows does not by itself hold path to other "folder viewer" (such as Total Commander etc.), so this way is probably off the table.
Try this:
var psi = new System.Diagnostics.ProcessStartInfo() { FileName = pathToFolder, UseShellExecute = true };
System.Diagnostics.Process.Start(psi);
I usually use this to open file/directory:
public static void OpenFile(string path, bool isDirectory = false)
{
if (string.IsNullOrEmpty(path)) return;
if ((isDirectory && Directory.Exists(path)) || (!isDirectory && File.Exists(path)))
{
ProcessStartInfo pi = new ProcessStartInfo(path);
pi.Arguments = Path.GetFileName(path);
pi.UseShellExecute = true;
pi.WindowStyle = ProcessWindowStyle.Normal;
pi.Verb = "OPEN";
Process proc = new Process();
proc.StartInfo = pi;
proc.Start();
}
}
or
Process.Start("explorer.exe",path);
If this doesn't work it may be a permission issue after all.
You can set the working directory like this but you can't run the directory itself only files or exe
var startInfo = new ProcessStartInfo();
startInfo.WorkingDirectory = //working directory
Process proc = Process.Start(startInfo);
This error actually happens when there is a difference between the default behaviour of opening the file and the relative behaviour of opening the file.
For example, if you have selected the default application to open .pdf files as Internet Explorer, and you are trying to open the same file using Process.Start() method. You will receive an exception because as per the default operations it should open that file in Internet Explorer and your application is trying to open it using Adobe reader.
To rectify this set the default application for the .pdf file as Adobe Reader and you won't receive this error any more.
You can do this by, right-clicking on the file and then select, Default program or App. Further, select the default Program or App from the list of available programs and then select the Always use the selected program/App to open files of this type.

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 can I get filename when user close Word?

I have one button and one textbox on form. When I click on the button, Microsoft Word is started. When the user closes Word, I want to get the file name that the user saved his work under to show up in the text box.
I am using the following code for button_click:
System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo(#"C:\Program Files\Microsoft Office\Office12\winword.exe");
psi.RedirectStandardOutput = true;
psi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
psi.UseShellExecute = false;
System.Diagnostics.Process listFiles;
listFiles = System.Diagnostics.Process.Start(psi);
System.IO.StreamReader myOutput = listFiles.StandardOutput;
listFiles.WaitForExit();
if (listFiles.HasExited)
{
System.IO.FileInfo ff = new System.IO.FileInfo(myOutput.ToString());
string output = myOutput.ReadToEnd();
this.processResults.Text = output;
}
I don't believe this is possible via the command line. Also, realize that, if the user opens another document, your code will not finish, since it'll wait until all of the docs are closed (the process won't end until that point).
That being said, you should be able to use the Word/Office Interop libraries, and listen to the DocumentBeforeSave and/or DocumentBeforeClose events. This should let you pull the information from the Document itself, right as it's being saved/closed.
I don't think you can do this with the current code you have. ProcessStartInfo is very generic and has no knowledge of word.
I think you will want to use Visual Studio Tools for Office (VSTO) to start word. This way you have a reference to the word application and document and can get the document name.
this article should get you started http://www.c-sharpcorner.com/UploadFile/mgold/WordFromDotNet11082005235506PM/WordFromDotNet.aspx the sample code has a object called aDoc. Then after the save you can check aDoc.FullName to get the path.
I'm not sure whether it's possible or not because name of the saved file is an internal information that's not public for other applications.
Instead in your particular case since you are using MS Word you can use Word interop to start the Word application in your application and then handle its events
Create a blank Word document in the desired location, and then get Word to load that?

Categories