How to get the path of the uploaded file within the AppBundle? - c#

We are using Autodesk Forge's Design Automation API. We have an AppBundle ready and we put an .rfa file into the same folder which contains the .dll file. When the AppBundle is unzipped on the Forge servers, which path can lead to our .rfa file? (how can we access it?) Our goal is to place the attached Family file's contents into the input file which is being uploaded with the API, and the result should be a new file which contains the additions from the file which we uploaded within the AppBundle. The process works when testing with Revit locally, but it doesn't work with the API. In the report we are retrieving it's obviously pointing out that the attached file cannot be found:
Autodesk.Revit.Exceptions.FileNotFoundException: T:\Aces\Jobs\ced628d35ecf4412b68c024e2cec098b\something.rfa
On the code side, we are trying to access the .rfa file via this path:
static string currentDir = Environment.CurrentDirectory;
static string path_input = currentDir+#"\something.rfa";
This seemed as a logical path, but as it turned out, it's not..
Is there a way to access the .rfa file inside the uploaded AppBundle?
I took a look at the Restrictions but reading the file from the AppBundle is not mentioned as restricted or not approachable. Am I missing something?

A .NET assembly knows its own path. You can call System.Reflection.Assembly.GetExecutingAssembly().Location within it to find the current path of the dll. You can then compute the path of the .rfa file relative to the folder of the dll and use it / open it. Thus you should be able to open any file you package along with your addin in your appbundle.
You can simply modify your code to:
static string assemblyLocation = Assembly.GetExecutingAssembly().Location;
static string assemblyDirectory = Path.GetDirectoryName(assemblyLocation);
static string path_input = assemblyDirectory+#"\something.rfa";
One thing to note however, is that you only have readonly access to files in appbundle. If your code relies on modifying these during execution, then you may simply copy the source rfa file to the current working folder and then work with the copied file instead.
Also see more details in blog for similar ideas.

We have a blog post on how you can either pass in the app bundle path in the commandLine parameter or find the path via the location of the add-in dll:
https://forge.autodesk.com/blog/store-template-documents-appbundle

Related

Finding a specific file path when two files have the same name in different locations in C#

I'm trying to load and save an xml file called Modules.xml in my code. I have currently got the file path hardcoded as shown below. I am trying to get the file path within my code without it being hardcoded.
I have tried using Path.GetDirectoryName and new FileInfo("Modules.xml").Directory.FullName. However, both of these target the file in my debug folder, when the file I need is in the main solution folder.
Is there a way to target the file in my main solution folder instead of my debug folder? (both files are called Modules.xml)
doc.Save("C:\\Users\\Matthew\\Desktop\\Year4\\Object Oriented\\Project1\\Project1\\Modules.xml");
Both file locations are shown below:
C:\Users\Matthew\Desktop\Year4\Object Oriented\Project1\Project1\Modules.xml
^^^this is the file path I need for my code^^^
C:\Users\Matthew\Desktop\Year4\Object Oriented\Project1\Project1\bin\Debug\Modules.xml
The best approach here would be to use a configuration file, e.g. app.config, for storing such a string. Then you can change file path without recompiling the code, and your file can be stored in any location accessible by application.
If you really want to access your file the way you explained, AppDomain.CurrentDomain.BaseDirectory will provide you with the bin/Debug location in runtime. Then you can find a relative path from there like:
Path.Combine(AppDomain.CurrentDomain.BaseDirectory, #"..\..\", fileName);
where fileName is "Modules.xml" for example.
I have tried using Path.GetDirectoryName and new
FileInfo("Modules.xml").Directory.FullName. However, both of these
target the file in my debug folder, when the file I need is in the
main solution folder.
That's because bin\Debug is your working directory when you start and run the project. To change that, you can set the working directory environment variable to point to your solution directory (instead of bin\debug|release) which I wouldn't recommend that. Because when you finally endup with development, and release the application, there wouldn't be any solution directory that holds your XML file. What I can suggest is to copy your XML file to the output folder. Either you are in development (debug) or production (release) mode, the XML always going to be copied to final directory. And you can access the working directory with something like AppDomain.CurrentDomain.BaseDirectory. To enabling copy XML to output directory, right-click on it, choose Properties, set Build Action to None, and set Copy to Output Directory to Copy Always or Copy if newer. You're good to go now.

C#.NET - Error Logging and Relative File Paths

I have a class in C# that saves an error message in a log file in case of an exception. Now I want to save the log file in the same folder containing the application's (in my case, a website) files. I tried using Environment.CurrentDirectory however it is not retrieving the path to my website. What can I do please to make use of a relative file path which points inside the website's directory?
Here is the class' code. As you can see, the path is absolute. I want to change it to a relative file path pointing to a folder in my website's directory.
Usually Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) returns the path where the current assembly resides. You could use
string logName = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "MyLogFile.log");
to create the log file name.
Question is really whether logging to the application's folder is permitted by the OS. Also, for Web-applications, the log file would be publically visible and accessible through the web browser.
For a website use:
HttpContext.Current.Server.MapPath("~/");
You might also could try this solution:
string path = AppDomain.CurrentDomain.BaseDirectory + "anotherFolder";
This would put the base dir of the app and a folder inside of the project!

File path for project files?

I am working on a media player in C# but when I want to make my test I have a problem.
I have to create a new object song with the following path:
#"C:\Users\Jesus Antonio\Desktop\JukeboxV2.0\JukeboxV2.0\Datos\ich will.mp3"
It works but when I change the computer I have to rewrite the entire path,
My project is called JukeboxV2.0
In java I remember you can just write the path for example
#"JukeboxV2.0\JukeboxV2.0\Datos\ich will.mp3"
This will save a lot of time because I can take my project to different computers and it works, but here I don't known how to do that, anyone know?
You would do something like this to get the path "Data\ich_will.mp3" inside your application environments folder.
string fileName = "ich_will.mp3";
string path = Path.Combine(Environment.CurrentDirectory, #"Data\", fileName);
In my case it would return the following:
C:\MyProjects\Music\MusicApp\bin\Debug\Data\ich_will.mp3
I use Path.Combine and Environment.CurrentDirectory in my example. These are very useful and allows you to build a path based on the current location of your application. Path.Combine combines two or more strings to create a location, and Environment.CurrentDirectory provides you with the working directory of your application.
The working directory is not necessarily the same path as where your executable is located, but in most cases it should be, unless specified otherwise.
Path.Combine(AppDomain.CurrentDomain.BaseDirectory, #"JukeboxV2.0\JukeboxV2.0\Datos\ich will.mp3")
base directory + your filename
I was facing a similar issue, I had a file on my project, and wanted to test a class which had to deal with loading files from the FS and process them some way. What I did was:
added the file test.txt to my test project
on the solution explorer hit alt-enter (file properties)
there I set BuildAction to Content and Copy to Output Directory to Copy if newer, I guess Copy always would have done it as well
then on my tests I just had to Path.Combine(Environment.CurrentDirectory, "test.txt") and that's it. Whenever the project is compiled it will copy the file (and all it's parent path, in case it was in, say, a folder) to the bin\Debug (or whatever configuration you are using) folder.
Hopes this helps someone

How to get a path from a directory in a C# console application?

Say I have this file structure
Soultion-> Folder1 -> FileIwant.html
So this could be something like C:\Soultion\Folder1\FilterIwant.html
Now I need to read this file into my application. I can't just hardcode it since when I give it to someone else they might put it on F: drive or something.
Or when I create a msi file the path might be completely different. So how can I say maybe take
"Folder1\FilterIwant.html"
and use that to get the folder path regardless of where they put it?
Edit
I tried Path.GetFullPath but I land up in the bin/debug directory. But my file is not in that directory. I think it is a couple directories before. Also if I make a msi file will I have bin/debug directory?
Why is a file which is used as part of your application not in the same folder as the application? It sounds to me like you should set the properties on that file to copy to the output folder when you do a build.
Doing that will make sure your file is in the bin\debug folder.
EDIT:
either that or you should be placing your files in one of the special folders, app data or my documents spring to mind.
When Visual Studio compiles your project, it will be putting the output into the bin\debug directory. Any content files that you want to reference must also be copied to those locations, in order for your app residing in that directory to be able to read that file.
You have two choices:
either you set the Copy to Output Directory property on your FilterIwant.html to Copy if newer; in that case, if the file has changed, it will be copied to the output directory, and you should be able to reference it and load it there
or
you just define a path in your app.config, something like DataPath, and set it to your folder where the file resides. From your app, you then create the full path name for that file as Path.Combine(AppSettings["DataPath"], "FilterIwant.html") - with this approach, you become totally independant of where the file really is and you don't need to move around anything. Also: this gives you the opportunity to create an admin/config utility for your users later on, so that they can pick any directory they like, and your app will find those files there.
In my console app, I started with the debug directory until i found the closest parent folder I wanted.
static void Main(string[] args)
{
Console.WriteLine("Start");
var debugDir = Environment.CurrentDirectory;
DirectoryInfo di = new DirectoryInfo(debugDir);
var searchDir = "";
while (!di.FullName.ToLower().EndsWith("Folder1"))
{
if(di.FullName.ToLower().EndsWith(":")) //if you went too far up as in "D:" then
break;
di = di.Parent;
}
Console.WriteLine(di.FullName);
}
You need the help of System.Io.Path class:
GetFullPath: Returns the absolute path for the specified path string.
Edit:
You might also need the application directory - this is where your application will be installed:
string appPath = Path.GetDirectoryName(Application.ExecutablePath);
Path.GetFullPath
Edit
The bin/Debug path will not be present when you run your installed application (unless you specifically tell the installer to use that subdirectory, of course).
You probably want to pass the full path as a command line argument. You can then get the argument using the args parameter of the Main method. To convert a relative path to an absolute one you can use Path.GetFullPath:
using System;
using System.IO;
public class CommandLine
{
public static void Main(string[] args)
{
// The path is passed as the first argument
string fileName = arg[0];
// get absolute path
fileName = Path.GetFullPath(fileName);
// TODO: do whatever needs to done with the passed file name
}
}

Read from output file in installed WCF service

I included a text file as output in a WCF set up project.
The text file is correctly located in the same folder with the dll, exe, and config file after the project is installed (C:\Program Files\KLTesting\KLTestApp).
However when the program tries to read it, it looks under "C:\Windows\system32", what's the correct way to find & read it?
I have
string a = Directory.GetCurrentDirectory();
a += "/R0303.txt";
string content = File.ReadAllText(a);
Thanks.
You should use AppDomain.CurrentDomain.BaseDirectory or AppDomain.CurrentDomain.SetupInformation.ApplicationBase instead, to get the Directory of your .exe file.
First you should not call Directory.GetCurrentDirectory() and concatenate with the file name. The service is running within a web server like IIS or some other type of container, so GetCurrentDirectory will not give you what you are thinking as you found out. (On a quick tangent, as a recommendation in the future if you want to do path combining you should use Path.Combine method as it will handle all the corner cases and be cross platform.)
There are a few ways to do this:
Assembly myAssembly = Assembly.GetAssembly(SomeTypeInAssm.GetType());
string fullFileName = Path.Combine(myAssembly.Location, "MyFile.txt");
The fullFileName should be what you are looking for. Make sure you use a type that is actually in an assembly located and referenced from the directory in question. However be aware because this file in your question in the Program Files area this is a secure area on Vista and higher OS's and you may not have access to do anything but read the file.
Also you could have the installer of the application place in the registry the install path. Then your service if on the same box can pull this information.
Also you could make sure the file you want to load is within the web server environment that is accessable to the WCF service in question.

Categories

Resources