I'm using WinForms. I have a form that has a button.
Goal: On button click: Open up a word document. Where the file path is hard coded into the program. I don't want the users to have to locate the word document.
Problem: I receive this error message. When I wrote my code, I get a red error line under 'Application'.
private void button1_Click(object sender, EventArgs e)
{
this.Application.Documents.Open(#"C:\Test\NewDocument.docx", ReadOnly:true)
}
Instead of adding interop in your reference, you may also consider to use this:
System.Diagnostics.Process.Start(#"C:\Test\NewDocument.docx");
first add the dll of Microsoft.Office.Interop.Word to your references then add this:
using Microsoft.Office.Interop.Word;
and use the following code:
Application ap = new Application();
Document document = ap.Documents.Open(#"C:\Test\NewDocument.docx");
This Application is not this.Application it's Microsoft.Office.Interop.Word.Application.
So you can use this code:
using System;
using Microsoft.Office.Interop.Word;
class Program
{
static void Main()
{
// Open a doc file.
Application application = new Application();
Document document = application.Documents.Open("C:\\word.doc");
//Do whatever you want
// Close word.
application.Quit();
}
}
There is a good answer above which is:
System.Diagnostics.Process.Start(#"C:\Test\NewDocument.docx");
This should be modified for .Net Core 2 and above to be:
var p = new Process();
p.StartInfo = new ProcessStartInfo(filename)
{
UseShellExecute = true
};
p.Start();
Related
Should we have something with the External application to properly register the event?
I also tried putting two breakpoints one inside the start module and other inside the Export module.
the first responded and waited for me to continue and the next didn't respond(hope did not run the line)
Also,I had manually tried coping the addin file to the addin location to avoid any post build event error but still doesnt seem to work.
could you tell me what I am I doing wrong here.
Here is the code :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.UI.Events;
using Autodesk.Revit.DB.Events;
using System.IO;
namespace UserDataSheet
{
[Transaction(TransactionMode.Manual)]
[Regeneration(RegenerationOption.Manual)]
public class UserDataSheetclass : IExternalApplication
{
public Result OnShutdown(UIControlledApplication application)
{
return Result.Succeeded;
}
public Result OnStartup(UIControlledApplication application)
{
try
{
// Register event.
application.ControlledApplication.DocumentOpened += new EventHandler<Autodesk.Revit.DB.Events.DocumentOpenedEventArgs>(ExportLog);
return Result.Succeeded;
}
catch (Exception)
{
return Result.Failed;
}
}
public void ExportLog(object sender, DocumentOpenedEventArgs args)
{
var doc = sender as Document;
var isFamilyDoc = doc.IsFamilyDocument;
// variables to use
string RevitUserName = "";
DateTime OpenTime = new DateTime();
string localUserName = "";
string filename = "";
string filepath = "";
string content = "";
if (isFamilyDoc == false)
{
var IsloggedIn = Autodesk.Revit.ApplicationServices.Application.IsLoggedIn;
if (IsloggedIn == true )//&& doc.IsModelInCloud == true)
{
// use variables
filepath = doc.PathName;
filename = doc.Title;
RevitUserName = doc.Application.Username;
OpenTime = DateTime.Now;
localUserName = System.Environment.MachineName;
}
content = string.Format("Date and time : {0} \n Revit UserName : {1} \n Local PC UserName : {2} \n FileName : {3} \n FilePath : {4} "
, OpenTime.ToString(), RevitUserName, localUserName, filename, filepath);
TaskDialog.Show("Model Open Writer info", "user and file details : \n " + content);
}
var writefilepath = Path.GetTempPath();
var Writefile = writefilepath + "//records.txt";
FileStream fs = new FileStream(Writefile, FileMode.Append);
StreamWriter writer = new StreamWriter(fs);
writer.Write(content);
writer.Close();
File.OpenRead(Writefile);
}
}
}
First of all, you can completely remove the TransactionMode and RegenerationOption. The latter is completely obsolete and does nothing at all anywhere whatsoever. The former is only useful when declaring an external command. It is useless and ignored in the context of an external application.
Secondly, to address your question: you can set a breakpoint in the beginning of OnStartup. If the breakpoint is not hit, your add-in is not being loaded at all. Probably something is wrong with your add-in registration, e.g., in the add-in manifest *.addin file.
Go back to square one, i.e., work through the getting started material and the developer guide instructions on registering and loading a Revit add-in.
If the breakpoint in OnStartup is hit, then your add-in is loading correctly, which means that the add-in manifest *addin file is OK. So, you do not need to worry about that. The VisibilityMode tag is not used for external applications, by the way.
Thanks, Jeremy It worked
Firstly I apologies for adding this as answer( I don't know how to add codes in comment)
It worked when I deleted my Addin file and recreated it may be I had made some mistake in it.
meanwhile I have copied the following code from examples and used it,honestly I did't understand this line of the code.
"public void ExportLog(object sender, DocumentOpenedEventArgs args)"
can you point to a right source that explains this part. I have three questions here :
what object type is sender and args are they of type application?
How do I add a 3rd parameter to this method say I want the user to input a string to name the file the data is copied to.
Can I do this
var newEvent = new EventHandler<Autodesk.Revit.DB.Events.DocumentOpenedEventArgs>(ExportLog);
instead of
application.ControlledApplication.DocumentOpened += new EventHandler<Autodesk.Revit.DB.Events.DocumentOpenedEventArgs>(ExportLog);
why does all example use += is this to register the event every time a new instance of Revit is opened?
Thanks for your help.
You can see the class of sender yourself by setting a breakpoint at the beginning of ExportLog and looking in the debugger.
No, you cannot modify the signature of the event handler. It is predetermined by the Revit API.
Yes.
It sounds to me as if you might save some time and effort for yourself by learning a bit more about the basics of C# and .NET programming in general before continuing to tackle this task.
I try to load a pdf document using PdfLoadedDocument method from Syncfusion.Pdf.WinForms NuGet package.
The code is pretty simple and look like this:
PdfLoadedDocument loadedDocument = new PdfLoadedDocument(#"\\server\folder\sample.pdf");
But it raises file not found error.
You may:
Test manually if the file is here: open your file explorer and enter the path, does the file open ?
Test programmatically if the file is here: Put File.Exists(#"\\server\folder\sample.pdf") in your code. This may raise other issues (like access denied that the PdfLoadedDocument may have swallowed).
Edit:
If you take a look to de-compiled code of PdfLoadedDocument (from Syncfusion.Pdf.WinForms v17.4.0.46 NuGet package) it is:
public PdfLoadedDocument(string filename)
: this(PdfLoadedDocument.CreateStream(filename))
{
this.isDispose = true;
this.m_bCloseStream = true;
this.m_fileName = filename;
}
The PdfLoadedDocument.CreateStream code is:
if (filename == null)
throw new ArgumentNullException(nameof (filename));
if (!File.Exists(filename))
throw new ArgumentException("File doesn't exist", nameof (filename));
...
So the "File doesn't exist" exception occurs when File.Exists return false.
If you take a look to File.Exists documentation:
The Exists method returns false if any error occurs while trying to determine if the specified file exists. This can occur in situations that raise exceptions such as passing a file name with invalid characters or too many characters, a failing or missing disk, or if the caller does not have permission to read the file.
The file may be there but your program may not have the right to access it.
Anyway, I tested PdfLoadedDocument(#"\\server\users\Orace\test.pdf"); where I have full access to \\server\users\Orace, and it works fine.
https://help.syncfusion.com/cr/file-formats/Syncfusion.Pdf.Parsing.PdfLoadedField.html
using Syncfusion.Pdf;
using Syncfusion.Pdf.Graphics;
using Syncfusion.Pdf.Parsing; //<================
namespace Text_Extraction
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
using (PdfDocument document = new PdfDocument())
{
// Load an existing PDF document.
PdfLoadedDocument loadedDocument = new
PdfLoadedDocument(#"C:\Users\grayg\Documents\Text To Speech
Stuff\NationalTreeClimbingGuide2015April.pdf");
// Loading page collections
I have to refactorate very old Code (older than 2005). The Software should open Word Documents and fill variables in the header with data. The Doc will open, but the variables are empty.
I use following codesnipped to show the amount of var´s in a Word Document to do some tests.
It always say´s there are 0... Can I use the WordInterop with Office 365 ?
using Microsoft.Office.Interop.Word;
namespace CheckForVariablesInWord
{
class Program
{
static void Main(string[] args)
{
Microsoft.Office.Interop.Word.Application ap = new Microsoft.Office.Interop.Word.Application();
Document document = ap.Documents.Open(#"C:\temp\TestDocument.docx");
ap.Visible = true;
System.Console.WriteLine(document.Variables.Count);
System.Console.ReadLine();
}
}
}
this is the TestWordDocument:
Here is the Variable named „myTest”
{ DOCVARIABLE myTest * MERGEFORMAT}
thx if anyone can help me out before i get mindsick ;.)
I want to track the files which are opened by the user, and select them by one particular extension. If the opened file has that extension, then I want to assign it's file path to a variable for further processing. Example applications are very cpu demanding. Is there an easy, efficient way to do that?
System wide monitoring of file-->open events (including network drives, thumb drives, etc) would require you to write a FS filter driver.
Since you have access to the machine, and you definitely need system wide access, you could simply write a simple app that will be associated with the Powerpoint extensions, perform the copy, then open Powerpoint using the filepath as a command line argument. It would look similar to the following:
using System;
using System.Windows;
using System.Diagnostics;
using System.IO;
namespace WpfApplication1
{
internal class MainWindow : Window
{
public MainWindow()
{ }
[STAThread()]
static void Main(string[] args)
{
if (args.Length == 0)
{
// [ show error or print usage ]
return;
}
if (!File.Exists(args[0]))
{
// [ show error or print usage ]
return;
}
// Perform the copy
FileInfo target = new FileInfo(args[0]);
string destinationFilename = string.Format("X:\\ExistingFolder\\{0}", target.Name);
File.Copy(target.FullName, destinationFilename);
// You may need to place the filename in quotes if it contains spaces
string targetPath = string.Format("\"{0}\"", target.FullName);
string powerpointPath = "[FullPathToPowerpointExecutable]";
Process powerpointInstance = Process.Start(powerpointPath, targetPath);
// This solution is using a wpf windows app to avoid
// the flash of the console window. However if you did
// wish to display an accumulated list then you may choose
// to uncomment the following block to display your UI.
/*
Application app = new Application();
app.MainWindow = new MainWindow();
app.MainWindow.ShowDialog();
app.Shutdown(0);
*/
Environment.Exit(0);
}
}
}
Hope this helps.
I am trying to produce a Windows Application Form via Codedom. I found a great example showing me how to do this for a Console Application but I can't seem to make this work for a Windows Form.
Here is what I have so far:
CodeDomProvider codeProvider = CodeDomProvider.CreateProvider("CSharp");
string Output = "Out.exe";
Button ButtonObject = (Button)sender;
textBox2.Text = "";
System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters();
//Make sure we generate an EXE, not a DLL
parameters.GenerateExecutable = true;
parameters.OutputAssembly = Output;
CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters, textBox1.Text);
Textbox1.text Contains the following:
Public Class Form1: Form
{
}
I'm really not sure what else to put... I am very new to this stuff and I can't seem to understand the articles I came across.
If you're new to CodeDom I strongly suggest you to use Linq2CodeDom which allows you to write your code in expressions which later will be translated through CodeDom into VB or C# code. With this library you can write something like this:
public void Generate()
{
var c = new CodeDomGenerator();
c.AddNamespace("Samples")
.AddClass("Form1")
.AddMethod(MemberAttributes.Public | MemberAttributes.Static, ()=>"YourMethodName", Emit.stmt(() => MessageBox.Show("Method Body")));
}
Assuming that you are actually able to create the EXE at the moment (as you are missing some using statements in your Form1 declaration) I would start by adding the entry point, the static Main method that creates and displays a new Form1 instance:
using System;
using System.Windows.Forms;
public class Form1 : Form
{
public static void Main(string[] args)
{
var form1 = new Form1();
Application.Run(form1);
}
}
That should at least get a window appearing when you run your generated EXE. #soandos also has a good point, you should be able to copy and paste from the source created when you create a form in Visual Studio, althought you should remember that VS2008+ uses partial classes so you need to combine the contents of Form1.cs and Form1.Designer.cs.