How to access a text file within a module

How to access a text file within a module

Anonymous
Not applicable
2,215 Views
12 Replies
Message 1 of 13

How to access a text file within a module

Anonymous
Not applicable

Hello everybody,


This may look very primitive.

In Revit API, I am trying to go through a text file line by line and showing each line to the user within a window, one by one.
I thought the best place for keeping this text file and accessing it would be within the module itself. I created the text file.

 

Now the problem is how to access this file should I give the full path to the file or there is an easier way to call a simple text file that right in the folder of the module? Look at the picture. It is right there!

 

Thanks,

0 Likes
2,216 Views
12 Replies
Replies (12)
Message 2 of 13

jeremytammik
Autodesk
Autodesk

Dear Hmoosavi,

 

Your question has nothing whatsoever to do with the Revit API, so this is not the optimal place to expect an answer.

 

You might have better luck in a generic .NET forum.

 

I generally would not include the file in the project settings at all, just save it as a TXT in the same location as the DDLL.

 

Then you can access and read it as a normal file.

 

Here is a code snippet showing how to write a file:

 

  using( TextWriter tw = new StreamWriter(
    "C:/tmp/RevisionTest.txt" ) )
  {
    tw.WriteLine( ". . ." );
    tw.Close();
  }

 

You can easily adapt that to read a file instead.

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 3 of 13

BenoitE&A
Collaborator
Collaborator

Hey,

As Jeremy said, you can use the very usefull StreamWriter object of C#.

See there : 

https://msdn.microsoft.com/en-us/library/system.io.streamwriter(v=vs.110).aspx

I use it everyday to debug (much easier to use than printing stuff on screen using TaskDialog).

Benoit


Benoit FAVRE
CEO of etudes & automates
www.etudesetautomates.com/
0 Likes
Message 4 of 13

Anonymous
Not applicable

As Mr. Tammik wrote, you probably do not want to include the file somehow bound up within the executing assembly. The answer as to where this file should be depends a lot on its purpose and how you deploy your application. The same applies to how you show it. For example the file could be in the same folder as your add-in, in which case it is thought as being at the executing assembly location. The following shows an example of this where a fullpathname for a file is built and then passed into a special object that is then hiked into a windows WPF object designed to display the file contents.

 

private void LoadUpHelpFile()
        {
            string ExecutingAssemblyPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
            string fn = Helpers.CombineIntoPath(ExecutingAssemblyPath, InfoFileName);
            RTFFile rtfhelp = new RTFFile() { File = fn };
            Dispatcher.BeginInvoke((Action)(() => RichTextFileHelp.DataContext = rtfhelp));
        }

The idea to get from the above is that the code makes string fn the full path name for a file name that the variable InfoFileName holds. That file is expected to be in the same folder where the add-in is running. The problem you can have with an add-in's executingassembly location is that copies of your add-in might be at every user's computer. That could be a problem if that text file is something that needs to be changed. A different approach that points to a single networked location might be in order.

 

aks

 

Message 5 of 13

Anonymous
Not applicable

Thank you, Jeremy for the reply.

The reason I want this text file (and later some tables maybe) be part of the assembly is that those file will act sources (data) for running the program.

I want to prepare a Revit API for so that the user goes over some forms and finally the result would general notes in the current sheet. 

 

Now I have this master general notes (text file) that usually an engineer goes through them and marks them up and gives it to the drafter to put in the sheet. I am trying to make the process so that engineers can do by themselves. This might sound redundant but it saves a lot of going back & forth between. A drafter and the engineer.

 

back to my question, I thought that the best place for this master general notes should be the API it self and should not be separate from it. I thought there should be someway other than specifying the absolute current path. Because we want to use this on any computer and referring to the file should be relative. 

 

Please let me know what you think. Thanks. 

0 Likes
Message 6 of 13

Anonymous
Not applicable

Aha! Your task is actually something I've cooked up a few different ways in years gone by. Generally there are a set of commonly used notes to choose from. Perhaps the company requires certain topics to be covered using a standard note that might be used as is or tweaked a bit to suit something unusual about the project at hand. Perhaps the project will have separate specification documents and therefore some notes are not needed because the specifications handle that topic or perhaps there are not separate specification documents and so the notes have to be verbose. Maybe the project has demolition involved. Maybe the project is all new construction. Someone wants to pick from a menu and then make some a la carte changes.

 

The issue is that you need to work backwards through the workflow starting with the final Revit element that carries the data. It could be text in a family (That is what I use personally. Mainly because of its flexibility.) or in a group or in some other device. The easiest workflow in my mind is one chunk of text, say in a family, that you paste in from the windows paste buffer. Therefore your outside application needs to fill the windows paste buffer as its final or almost final task. There are lots of ways to get to that last point. I'll let it brew in your mind at this point.

 

aks 

Message 7 of 13

jeremytammik
Autodesk
Autodesk

If you really want to embed a static copy of the text data in each compiled DLL, then of course you should do so.

 

If you wish to access a company-wide standard that may change in the next year, decade, century or millennium, I would suggest placing one single global copy of it somewhere on the Internet or intranet and reading the text from there.

 

I fully support all the sound advice provided by aks... that sounds good to me, and based on experience.

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes
Message 8 of 13

RPTHOMAS108
Mentor
Mentor

The problem I get with these general notes tasks is units and formatting.

 

e.g. When you extract from plain text there is a Unicode character for superscript '2' but not one for superscript '3', so you have to use formatting . There is a way of doing formatted text in the API but it depends on text pointers rather than supplying an RTF file and applying the supported formatting such as underline, subscript etc.

 

Indenting, bullet lists etc. also hard not to loose track of the level.

 

 

 

 

Message 9 of 13

jeremytammik
Autodesk
Autodesk

My StringSearch plugin of the month implements a form that displays an RTF formatted help text:

 

https://github.com/jeremytammik/StringSearch

 

https://github.com/jeremytammik/StringSearch/blob/master/StringSearch/HelpDlg.cs

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes
Message 10 of 13

RPTHOMAS108
Mentor
Mentor

Hello Jeremy

 

Perhaps I’m missing something but how do you get Formatted text into a TextNote object from an rft source? You would have to parse the rft and then build the FormattedText object in code by using methods such as:

SetBoldStatus(Range, True)

SetListType(Range, ListType.Bullet)

 

These involve trying to understand which text ranges in the original rtf have the applied settings, and it gets complicated because multiple settings can be applied or have overlaps where they aren’t.

 

What I was kind of looking for (being lazy) was FormattedText.Create(RtfFilePath as string) and FormattedText.Export(RtfFilePath as string). I understand there are features in rft that would not be supported (font colours/fonts) but you just ignore those. Not sure you can even serialise the FormattedText class to store it. You can get plain text from it as a string (.GetPlainText) but not formatted text as a string? If there is a Revit version of rft exported as a string then you could perhaps use xslt or similar technologies to convert to rft and back.

 

Regards

 

Richard

0 Likes
Message 11 of 13

jeremytammik
Autodesk
Autodesk

Look at the code I pointed to.

 

  Assembly exe = AboutBox.ExecutingAssembly;

  Stream s = exe.GetManifestResourceStream(
     _namespace_prefix + "help_text.rtf" );

  richTextBox1.LoadFile( s, RichTextBoxStreamType.RichText );

I embed the RTF file as an embedded resource in the project DLL, just like the TXT file discussed above.

 

The .NET Windows.Forms library includes an RTF widget.

 

I load the RTF file contents into the widget.

 

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes
Message 12 of 13

Anonymous
Not applicable

Thank you aksaks & Jeremy,

 

I agree with having the master file in the company netework and use it from there. I will start working on this. 

 

Very useful conversation.

But if in case, we need to have a embedded text or piece of data in dll file, could you please refer to the methods.

 

Thanks

0 Likes
Message 13 of 13

Anonymous
Not applicable

If it may be of use, the technique I am using "binds" the file to a WPF object as described here:

 

https://www.rhyous.com/2011/08/01/loading-a-richtextbox-from-an-rtf-file-using-binding-or-a-richtext...

 

For relatively small data, or even for providing continuity between one session and the next, like remembering what was worked on last or what the user entered or selected the last time, then I use Properties.Settings.Default. You can even save lists here.

 

Properties.Settings.Default. is particualry useful in workflow tools because you want the tool to be universal but you also want the tool to behave in tailored bursts where the tool remembers how it was recently used.

 

aks

0 Likes