I have a file I need to access at runtime, I've included it in my project and set it up as embedded resource (it's actually a source file, I changed the extension to .cs.txt to get around VS trying to compile it. That shouldn't matter, but I'm mentioning it anyway just in case).
When I try getting the file
var assembly = Assembly.GetExecutingAssembly();
Stream stream = assembly.GetManifestResourceStream(resourceName);
I get a null. I've made sure I'm using the Namespace.Folder.Filename notation, but that didn't help. It appears the file is actually not there, because when I call
assembly.GetManifestResourceNames();
I get an empty string array. Any idea what could be the case?
I appreciate this is an old thread but what I found this morning might be useful to others.
I had a resource where the filename had multiple dots in it...
example filename: data.txt.dat
var resources = asm.GetManifestResourceNames(); // None found (empty array)
renamed to data.txt (still just an embedded resource in the project configuration
var resources = asm.GetManifestResourceNames(); // Entry found ("Assembly.Namespace.data.txt")
So maybe there is some limitation around multiple . characters in the name
So I got around this by using the VS resource manager. Now I can access the file directly like this:
MyNamespace.Properties.Resources.MyFile
I'd recommend this approach to anyone, as it seems not only much cleaner, but safer as well. Thanks Hans Passant for the advice.
Based on this pull request (https://github.com/dotnet/msbuild/pull/5824) you can add WithCulture="false" in your csproj on your EmbeddedResource tag :
<EmbeddedResource Include="a.cs.b" WithCulture="false"/>
It is working for me
Related
I have an application where users can define custom elements by adding their own xaml files. These files are loaded by the application on startup. The idea is to be able to extend the application without having to recompile it. These elements will be shown on screen to the user, and the xaml files may contain resource keys which are not included in the resx files of the application itself. So I have a requirement to have separate resx files which the user can edit, that will also be loaded at runtime.
I've looked at the ResourceManager class, and I know that it can be set to access resources from various other assemblies. But from what I gather the resources must be part of an assembly, which is precisely what I don't want. What I want is to have a bunch of files like these:
%ProgramData%\MyApplication\Resources\strings.resx
%ProgramData%\MyApplication\Resources\strings.de-DE.resx
%ProgramData%\MyApplication\Resources\strings.zh-CN.resx
and I want my application to be able to load these files and access the strings in them.
This article https://msdn.microsoft.com/en-us/library/gg418542(v=vs.110).aspx shows two approaches using ResXResourceReader and ResXResourceSet. However, it appears that these classes take a path to a specific file (or a stream), and therefore won't be able to pick the correct file according to current culture and the naming convention. I know I can code this myself, and that's what I'll do if I don't find a better solution. But ideally I'd want something that handles this for me. For instance if it would be possible to point a ResourceManager to a folder instead of an assembly. Is something like this possible?
after a long long searching i found this:
If i understand you in the right way you want to create user defined forms in WPF at runtime using xaml.
I am not sure but, i think the resource files will not help you out, because all xaml forms precompiled in the assembly. I found something that maybe sounds like a solution for your problem. Its called Sattalite Assembly. In the first step you have to create a new resource file. Second step is to link it with the Assembly Linker (Al.exe). form .net Framework. MSDN Creating Satellite Assemblies
First step create a ResourceFile at Runtime (here a little help)
public static void CreateResourceFile()
{
string resourceFileName = "externeresource";
System.Xml.XmlDocument xmldoc = new XmlDocument();
XmlTextReader reader = new XmlTextReader("/runtimeWPForm.xml");
reader.WhitespaceHandling = WhitespaceHandling.None;
xmldoc.Load(reader);
ResourceWriter resourceWriter = new ResourceWriter(resourceFileName);
/*Add XmlDocument must be Serializable to store it in
resourceWriter.AddResource("xamlgrid", xmldoc.ToString());
the Resource, so i stored a String here. (not testet)*/
resourceWriter.Close();
MessageBox.Show("File " + resourceFileName + " created");
reader.Close();
}
Second step create a Sattlelite Assembly from resource file with Assembly Linker Al.exe
Last step is to load the xaml Forms from the Sattalite Assembly (here a little help)
Uri GridUri = new Uri(/*Note1*/, UriKind.Relative);
Windows.Resources.StreamResourceInfo sri = Application.GetResourceStream(GridUri);
System.Windows.Markup.XamlReader xrdr = new System.Windows.Markup.XamlReader();
Grid grd = (Grid)xrdr.LoadAsync(sri.Stream);
this.Content = grd;
Note1:
Resource file - referenced assembly Pack URIs in WPF
Uri uri = new Uri("/ReferencedAssembly;component/ResourceFile.xaml",UriKind.Relative);
Here some usefull Information as i think Construct XAML Forms at Runtime with Resource Files
This is all i found for you and no guarantee for functionallity.
Im interested in if this will work for you, so please send an answer on success or if you solved your issue.
PS.: if this works i think you only have to restart you main application to load the new sattalite assembly. Maybe you have to start an ohter application that do the job and after finish automaticly start your main app again.
Best reguards
GatewayToCode
I'm using the MVVM structure and I wish to read a csv file, which I've added in the same folder as the viewmodel. I've tried to use the second answer in this question, but my variable var is null, so it doesn't seem to find the file. Beneath is an image of the folders and what I've done so far.
Can anyone help me get the destination of the file so I can use it as a stream?
You need to provide a path relative to your package, thus it should work if done like this:
var dest = App.GetResourceStream(new Uri(#"StartUpViewModels/" + destination, UriKind.Relative));
Here is also reference to answer to similar question.
Remember also to check if your resource file added to package has Build Action set to Content, otherwise if it's set to None, your file won't be added.
What I am trying to do is:
I have a Asp Mvc website. In it I need to create a function that does the following:
converts a .dwg (AutoCad) file to a .pdf file
converts a .dwg file to a .dwf file
I started with the, what I tought at the time, easier task to have the .dwg to a .pdf. After some research I found out that a way to do that (without buying a 3rd party license) is to install TrueView on the server and using it (or actually a AcCtrl.dll) to convert the file. Well, I did so. I installed the True View program and added a reference to AcCtrl Component (ACCTRLLib). Then I added a reference to the Dll inside the class file I am working on:
using ACCTRLLib;
So far so good. After that I followed the instructions on this post: PDF conversion using dwg true viewer in VB6
First, this is my code:
public static void ConvertFile()
{
IAcCtrl contrl = new AcCtrl();
contrl.PutSourcePath(#"D:\MMA\Autocat\File1.dwg");
string[] pdfPath = new string[1] { #"D:\MMA\Autocat\File1.dwg" };
contrl.SilentPublish(pdfPath);
}
Then, according to the post, I went to see if there is a registry with the specified path. The path that I have as a registry is the following:
HKEY_CURRENT_USER\Software\Autodesk\DWG TrueView\R13\DWGVIEWR-E001:409\Profiles\<<\Unnamed Profile>>\Dialogs\AcPublishDlg
So, I created a 'String Value' in it with ValueName: Location and ValueData: D:\MMA\Autocat\Testing
Alright. So, thats it. After all that I ran the application and called the function. The debugger goes through the code and everything executes (or at least looks like so) but nothing happens. I don't get a file in the D:\MMA\Autocat\Testing folder. I get no exception, no warning nothing. It just executes and nothing happens.
So what else did I tried. Some of those things might be a little naive or silly to try but nevertheless I did as I happen to be a little desperate.
I tried everything in a console application. I wasnt completely sure that this method is suitable for ASP MVC so I tried the same code with a console application unfortunatelly to the same result.
I added a file name inside the location string value. I changed the Location ValueData from 'D:\MMA\Autocat\Testing' to 'D:\MMA\Autocat\Testing\testFile.pdf' as I noticed that nowhere in the whole process a file name is asked for the converted file.
Following my thought from the previous conclusion I tried to supply the path to the 'result' file to the SilentPublish function.
string[] pdfPath = new string[1] { #"D:\MMA\Autocat\Testing\testFile.pdf" };
contrl.SilentPublish(pdfPath);
Again to no avail. So, my question, or rather questions are:
Is it possible to do it this way and if it is what am I doing wrong?
If its not than can you suggest a way?
Also if a .dwg to .dwf conversion is possible (with the same or different method I am all ears)
Thank you very much
True View does not expose the Autodesk.AutoCAD.PlottingServices namespace. You're going to need either a licensed copy of AutoCAD, RealDWG, or another third party API.
I'm not sure if you are still having this issue, but you should be able to do this with the Autodesk Forge API. Calls can be made from any language with a simple HTTP call. You will have to first convert to SVF and then to DXF and PDF from there.
I am writing a C# application that uses a long "hard-coded" string.
For maintainability reasons I have decided to put this string in an external text file and load it. Is this a good idea? The extra I/O does not seem big in this case.
I realize that I also have an option to embed this file as a .resx resource. Is this a better idea? The file will never need to be localized.
If you intend to allow users/administrators to change the string, I agree with the other answers, and I'd suggest putting it in settings.
If you don't want it to be editable after deployment and it will only be modified by you and your developers, then I would put it in an embedded resource (note, this is not the same as a .resx file). You would read it at runtime like this:
Assembly assembly = Assembly.GetExecutingAssembly();
Stream stream = assembly.GetManifestResourceStream(“MyAssemblyNamespace.MyTextFile.txt”);
StreamReader reader = new StreamReader(stream);
string theText = streamReader.ReadToEnd();
Update: This is solution that is easy to maintain. The .txt file will just be another file in your solution explorer in Visual Studio and you can edit it just like any other file, keep it under source control like any other file, etc. To turn it into an embedded resource by changing the Build Action in the properties window to "Embedded Resource".
The end result is that your file(s) get embedded in your DLL so that you only have 1 DLL to distribute instead of a DLL and a folder of files that have to move around together.
Update 2: Regarding "production debugging", this is a very static solution, and so you won't be able to change the contents of the text file at runtime because the file is baked into the DLL at compile time. For reading the contents of the file, you can use tools like reflector to view the embedded resources of a DLL. You could also write a simple command line tool that dumps all the embedded .txt files from a DLL into individual files for you to look at.
For memory usage, there isn't a solution more efficient than "I load it from a file into memory only exactly when it is needed". You have to decide whether the improved maintainability and deployment is worth the cost of a little extra memory when your DLL is loaded into memory for your specific situation. That said, you haven't said how large these files are. If they are really huge (megabytes+), I would probably not use this solution and would go with loose files on the hard drive. If they are generally pretty small (hundreds of kilobytes), I wouldn't worry about the extra memory unless you are in some kind of embedded device situation where RAM is really tight.
Why not make it an appSetting in your web/app.config file?
<appSettings>
<add key="MyLongString" value="This is a really long string value that I don't want hardcoded" />
</appSettings>
Then, in code:
using System.Configuration; //To ease your typing pains
var myReallyLongString = ConfigurationManager.AppSettings["MyLongString"];
I would suggest to use Application Settings.
You can follow this MSDN link how to use Application and User Settings.
I would put this in an application configuration file.
Even better would be to add a Settings file to your project. You can then easily add configuration settings through Visual Studio.
See this link.
You could then access your string by using the following:
Settings.Default.MyString;
In addition, settings are strongly typed, so you don't need to do any conversions when you retrieve them.
To more directly answer your question, the "best practice" would be to use a resource file for any localizable (even if you're not going to localize it) string in your application. This allows you compile-time access to the string and keeps it from being externalized as a separate file to deploy with your application.
I suggest using this approach; settings are similar, but should not be used unless what you're storing there actually represents a setting. Constants are the other option, but in the case of a long string, I'd stay away from them, just for the sake of maintainability.
I googled and someone found the answer and linked but it was dead. How can i find a specific class in a specific file? The poster i found ask that question and found how to do it in a namespace but i would like to find one specific to a file. This question is to answer my other question but now that i thought of this i would like to know the answer.
Something like this?
string path = "INSERT PATH HERE";
var assembly = Assembly.LoadFile(path);
foreach (var type in assembly.GetTypes())
{
Debug.WriteLine(type.Name);
// do check for type here, depending on how you wish to query
}
I am not sure how the file name shall be stored as part of compiled assembly. Other option is that you can use the PDB file generated by the VS IDE to get the source file at some extension.
Here is some internals of pdb file.
http://www.informit.com/articles/article.aspx?p=22685
Once you can parse the file, you can use the symbol and look at the source definition.
I am glad to know other ways as well.
If you want to find the source code for a class, use the Go To Definition option in Visual Studio.
Once the code is compiled, it's not arranged in files, it's arranged in name spaces and assemblies. If it's at all possible to find out from which source file a class originated, you would have to loop through all classes and look for it.