Trouble using TemplateGroupDirectory - c#

I want to put several template files on a directory named "Templates", relative to the executable of my application, and use them. One template file, for instance, is named "Globals.st".
That way, I created a TemplateGroupDirectory and loaded the template:
var group = new TemplateGroupDirectory("Templates");
var tmpl = group.GetInstanceOf("Globals");
On trying to get the instance of the template I've got a message saying that occurs a NullReferenceException.
What am I missing?

might be a syntax thing
heres an example:
string fullpath = Path.GetFullPath("templates/");
TemplateGroupDirectory tgd = new TemplateGroupDirectory(fullpath ,'<','>');
Template t = tgd.GetInstanceOf("helloworld");
t.Add("world", "shitty world");
i have a folder to named templates, with the file helloworld.st that contains
helloworld(world) ::= <<
hello, <world>
>>
My best guess is that it cannot find the .st file you need, remember to put copy on newer or always coby, on the .st files' properties, when you use relative paths, or else template will be nothing.

Related

Using relative paths and globbing patterns (all files in folder/subfolders) in bundleconfig.json with BundlerMinifier

I have an ASP.NET Core web project. I am trying to bundle a bunch of static .js files using the BundlerMinifier package on the bundleconfig.json file at the root of my project. The issue I have is that the .js files I want to bundle are in another project in the solution (which I'll call MainProject), so I have to use relative paths to specify them, like so:
"outputFileName": "../MainProject/bundles/libraryscripts.js",
"inputFiles": [
"../MainProject/Scripts/Libraries/Angular/**/*.js",
// more input files
],
"minify": {
"enabled": true
}
When I build my project, the bundler does not give any errors and the file libraryscripts.js is created at the specified folder. The problem is the file is empty, which I believe is due to the globbing pattern (**/*.js). When I enumerate all the files instead of using this pattern, it works fine. What makes this more complicated is that when I don't use relative paths (no ../ at the start), it seems to work fine when using the globbing pattern.
This leads me to believe it's a problem with using relative paths in conjunction with globbing patterns. Can anyone confirm this and does anyone know a way around this? I do not want to enumerate hundreds of .js files (neither elegant nor sustainable).
Note: the following is a hacky workaround that I implemented -- it is not an official solution to this problem, though it may still be helpful.
I cloned the BundlerMinifier project so I could debug how it was bundling the files specified in bundleconfig.json and see what the problem was. The issue was in Bundle.cs, in particular in the GetAbsoluteInputFiles method. This line gets the path of the folder in which bundleconfig.json is stored:
string folder = new DirectoryInfo(Path.GetDirectoryName(FileName)).FullName;
The issue is that this same folder variable is used later when trimming the start of the paths of the files that are found:
var allFiles = Directory.EnumerateFiles(searchDir, "*" + ext, SearchOption.AllDirectories).Select(f => f.Replace(folder + FileHelpers.PathSeparatorChar, ""));
Since the files were in another directory, the .Select(f => f.Replace()); part didn't remove the start of the paths of the files, which meant the comparisons later failed when being matched. Thus, no files with both ../ and a globbing pattern were found.
I came up with a hacky solution for myself, but I don't think it's robust and I will therefore not contribute to the Git project. Nonetheless, I'll put it here in case anyone else has the same issue. I created a copy of folder:
string folder = new DirectoryInfo(Path.GetDirectoryName(FileName)).FullName;
string alternateFolder = folder;
bool folderModified = false;
Then I created a copy of inputFile and checked if it starts with ../. If so, remove it and at the same time remove the last folder name from alternateFolder:
string searchDir = new FileInfo(Path.Combine(folder, relative).NormalizePath()).FullName;
string newInput = inputFile;
while (newInput.StartsWith("../"))
{
// I'm sure there's a better way to do this using some class/library.
newInput = newInput.Substring(3);
if (!folderModified)
{
int lastSlash = alternateFolder.LastIndexOf('\\');
alternateFolder = alternateFolder.Substring(0, lastSlash);
folderModified = true;
}
}
Then I use alternateFolder and newInput only in the following lines:
var allFiles = Directory.EnumerateFiles(searchDir, "*" + ext, SearchOption.AllDirectories).Select(f => f.Replace(alternateFolder + FileHelpers.PathSeparatorChar, ""));
var matches = Minimatcher.Filter(allFiles, newInput, options).Select(f => Path.Combine(alternateFolder, f));
Everywhere else still uses folder and inputFile. Also note the use of the folderModified boolean. It is important to only remove the last folder on alternateFolder once since it is in a foreach loop.

Accessing a text file in a WPF project

I feel like I'm missing something obvious here...
I've got a text file in my WPF application which is located in a subfolder, so apologies for advance for the terrible ASCII.
+Project
+--+Subfolder
| +--TextFile.txt
|
+--App.config
+--App.xaml
+--etc.
The build action on this text file is Resource and I'm trying access the content as a string in my program, but I have absolutely no idea what I'm doing.
Trying to access the file through Properties.Settings.Default doesn't work, apparently there's only a ConnectionString resource in my program.
I can't do it in XAML because for whatever reason there's no Source property
<!-- somewhere up the top of App.xaml... -->
xmlns:clr="clr-namespace:System;assembly=mscorlib"
<clr:String Source="pack://application:,,,/Subfolder/Textfile.txt"/>
The FindResource method can't find it either.
FindResource("Usage.txt"); //ResourceReferenceKeyNotFoundException
All I'm trying to do is reference the text file, read it as a string and use that string. Otherwise I have to embed a 50 line verbatim string in the method call. Because that's totally a good idea. /s
In WinForms it was as simple as: Properties.Settings.Default.TextFile.ToString(); but nothing seems to work here.
I should point as well that this file shouldn't be included in the output directory, it needs to be embedded in the application or whatever the term is.
How should I be doing this?
This should work:
var uri = new Uri("pack://application:,,,/Subfolder/TextFile.txt");
var resourceStream = Application.GetResourceStream(uri);
using (var reader = new StreamReader(resourceStream.Stream))
{
var text = reader.ReadToEnd();
...
}
Try that:
using (StreamReader sr = new StreamReader(System.AppDomain.CurrentDomain.BaseDirectory + "/Subfolder/TextFile.txt"))
{
String line = sr.ReadToEnd();
Console.WriteLine(line);
}
You can do like this:
string file = #"pack://application:,,,/" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Name + ";component/Subfolder/TextFile.txt";
using (var sr = new StreamReader(System.Windows.Application.GetResourceStream(new Uri(file)).Stream))
{
var data= sr.ReadToEnd();
}
For example, this is your project structure
+ProjectName
+--+imagesFolder
| +--amogus.png
|
+--App.xaml
+--MainWindow.xaml
+--etc.
and you want to access the to amogus.png in your xaml window,
You have two ways:
note this way the imagesFolder will be visible in the release build to users
to set amogus.png Build Action to Content and
Copy to Output Directory to Copy always more info,
then rebuild from the build menu, then add this to the window xaml
<Image Source="pack://siteoforigin:,,/imagesFolder/amogus.png" ></Image>
note this way the imagesFolder will be not visible in the release build to users
to set amogus.png Build Action to Resource and
Copy to Output Directory to Do not copy or blank more info,
then rebuild from the build menu, then add this to the window xaml
<Image Source="/imagesFolder/amogus.png" ></Image>
more detail

How does use XamlReader to load from a Xaml file from within the assembly?

I've found several posts across stackoverflow and the rest of the internet regarding how to load Xaml from a static file: they recommend creating a XmlReader or StreamReader pointing to a file found on the file system, but the .xaml document I would like to read from is going to be compiled with the rest of the assembly, so it won't have a meaningful file Uri. I do not want to copy this document around wherever the assembly goes. Is there a way to read from a .xaml document that has been compiled into the assembly?
I also know that I can simply read from a very long string literal inside the code itself, but I'd rather not do that - the UIElement produced from the Xaml should be easily edited, and I gain this by editing it in a Xaml file.
To illustrate what I'm hoping for, here's an example:
private void LoadUIElementFromCompiledXaml()
{
XmlReader xmlReader = new XmlReader("*Uri for .xaml document within my assembly*");
UIElement elementLoaded = (UIElement)XamlReader.Load(xmlReader);
}
I apologize in advance if the answer is blatantly obvious.
Before you can load Xaml from an assembly as an embedded resource, there is a bit of setup you must do. I'll walk you through an example, then from there you can customize it to suite your needs.
Create folder in your project. Name it XAML.
Add a XAML file to the XAML folder. Lets call it Sample.xaml.
Right-click on Sample.Xaml and choose properties. Set the value for Build Action to "Embedded Resource".
Right-click on the project and choose properties. Take note of the Default namespace value. We will use this as part of the path. For this example lets assume it is "MyNamespace.
Your code to load the Xaml resource would look something like this:
string defaultNamespace = "MyNamespace";
string folderName = "XAML";
string fileName = "Sample.xaml";
string path = String.Format("{0}.{1}.{2}", defaultNamespace, folderName, fileName);
using (Stream stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(path))
{
object root = XamlReader.Load(stream);
}
As you can see the path to the resource is made up of the default namespace of the project, the folder path to the file, and the file name. If the folder path has multiple levels use dots as folder separator in place of back slashes. For example Xaml\Subfolder would be Xaml.Subfolder.

How get file from a directory using relative path?

I am pretty new in C# and I am finding some difficulties trying to retrieve a jpg file that is into a directory of my project.
I have the following situation:
I have a Solution that is named MySolution, inside this solution there are some projects including a project named PdfReport. Inside this project there is a folder named Shared and inside this folder there is an header.jpg file.
Now if I want to obtain the list of all files that are inside the Shared directory (that as explained is a directory inside my project) I can do something like this:
string[] filePaths = Directory.GetFiles(#"C:\Develop\EarlyWarning\public\Implementazione\Ver2\PdfReport\Shared\");
and this work fine but I don't want use absolute path but I'd rather use a relative path relative to the PdfReport project.
I am searching a solution to do that but, untill now, I can't found it. Can you help me to do that?
Provided your application's Executable Path is "C:\Develop\EarlyWarning\public\Implementazione\Ver2", you can access the PdfReport\Shared folder as
string exePath = System.IO.Path.GetDirectoryName(Application.ExecutablePath);
string sharedPath = Path.Combine(exePath, "PdfReport\\Shared\\");
string[] filePaths = Directory.GetFiles(sharedPath);
Try to get the current folder by using this
Server.MapPath(".");
In a non ASP.NET application but WinForms or Console or WPF application you should use
AppDomain.CurrentDomain.BaseDirectory
If you want root relative, you can do this (assuming C:\Develop\EarlyWarning is site root)
string[] filePaths = Directory.GetFiles(Server.MapPath("~/public/Implementazione/Ver2/PdfReport/Shared"));
Or if you want plain relative,
//assuming you're in the public folder
string[] filePathes = Directory.GetFiles(Server.MapPath("/Implementazione/Ver2/PdfReport/Shared"));
Root relative is usually best in my experience, in case you move the code around.
You can right click on your file header.jpg, choose Properties, and select for example the option Copy always on the property "Copy to Output Directory".
Then a method like this, in any class that belongs to project PdfReport:
public string[] ReadFiles()
{
return Directory.GetFiles("Shared");
}
will work well.
Alternatively, if you have files that never change at runtime and you want to have access to them inside the assembly you also can embed: http://support.microsoft.com/kb/319292/en-us

Load local HTML file in a C# WebBrowser

In my app I have a WebBrowser element.
I would like to load a local file in it.
I have some questions:
Where to place the HTML file (so that it will also be installed if a user executes the setup)
how to reference the file? (e.g. my guess is the user's installation folder would not always be the same)
EDIT
I've added the HTML file to my project.
And I have set it up so that it gets copied to output folder.
When I check it it is present when run: \bin\Debug\Documentation\index.html
However when I do the following I get a 'Page cannot be displayed' error in the webbrowser element.
I use the following code to try to display the HTML file in the Webbrowser.
webBrowser1.Navigate(#".\Documentation\index.html");
Do a right click->properties on the file in Visual Studio.
Set the Copy to Output Directory to Copy always.
Then you will be able to reference your files by using a path such as #".\my_html.html"
Copy to Output Directory will put the file in the same folder as your binary dlls when the project is built. This works with any content file, even if its in a sub folder.
If you use a sub folder, that too will be copied in to the bin folder so your path would then be #".\my_subfolder\my_html.html"
In order to create a URI you can use locally (instead of served via the web), you'll need to use the file protocol, using the base directory of your binary - note: this will only work if you set the Copy to Ouptut Directory as above or the path will not be correct.
This is what you need:
string curDir = Directory.GetCurrentDirectory();
this.webBrowser1.Url = new Uri(String.Format("file:///{0}/my_html.html", curDir));
You'll have to change the variables and names of course.
quite late but it's the first hit i found from google
Instead of using the current directory or getting the assembly, just use the Application.ExecutablePath property:
//using System.IO;
string applicationDirectory = Path.GetDirectoryName(Application.ExecutablePath);
string myFile = Path.Combine(applicationDirectory, "Sample.html");
webMain.Url = new Uri("file:///" + myFile);
Note that the file:/// scheme does not work on the compact framework, at least it doesn't with 5.0.
You will need to use the following:
string appDir = Path.GetDirectoryName(
Assembly.GetExecutingAssembly().GetName().CodeBase);
webBrowser1.Url = new Uri(Path.Combine(appDir, #"Documentation\index.html"));
Place it in the Applications setup folder or in a separte folder beneath
Reference it relative to the current directory when your app runs.
Somewhere, nearby the assembly you're going to run.
Use reflection to get path to your executing assembly, then do some magic to locate your HTML file.
Like this:
var myAssembly = System.Reflection.Assembly.GetEntryAssembly();
var myAssemblyLocation = System.IO.Path.GetDirectoryName(a.Location);
var myHtmlPath = Path.Combine(myAssemblyLocation, "my.html");
What worked for me was
<WebBrowser Source="pack://siteoforigin:,,,/StartPage.html" />
from here. I copied StartPage.html to the same output directory as the xaml-file and it loaded it from that relative path.
Windows 10 uwp application.
Try this:
webview.Navigate(new Uri("ms-appx-web:///index.html"));
Update on #ghostJago answer above
for me it worked as the following lines in VS2017
string curDir = Directory.GetCurrentDirectory();
this.webBrowser1.Navigate(new Uri(String.Format("file:///{0}/my_html.html", curDir)));
I have been trying different answers from here, but managed to derive something working, here it is:
1- Added the page in a folder i created at project level named WebPagesHelper
2- To have the page printed by webBrowser Control,
string curDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase);
var uri = new Uri(curDirectory);
string myFile = Path.Combine(uri.AbsolutePath, #"WebPagesHelper\index.html");
Uri new_uri = new Uri(myFile);
i had to get the assembly path, create a first uri to get an absolute path without the 'file://' attached, next i combined this absolute path with a relative path to the page in its folder, then made another URI from the result.
Then pass this to webBrowser URL property webBrowser.URL = new_uri;

Categories