I am trying to set the uploadpaths for all of the RadEditor File Managers to the same absolute file path, and also share the same path across a couple of Solutions on the same machine.
So, I wrote a method to get the path from the Web.Config and set all the Properties on the FileManagerDialogConfiguration objects (UploadPaths, ViewPaths, etc). The problem is these properties are looking for Virtual Paths, and full paths don't work.
How can I supply the properties with the Virtual Path of a folder that may/may not be in the same Solution?
This didn't work:
private static FileManagerDialogConfiguration fixPaths(FileManagerDialogConfiguration f, String[] path)
{
if (path[0][0] != '~')
{
Uri basePath = new Uri(ConfigurationManager.AppSettings["veMainPath"]);
Uri absPath = new Uri(path[0]);
Uri relPath = basePath.MakeRelativeUri(absPath);
path[0] = relPath.LocalPath;
}
f.ViewPaths = path;
f.UploadPaths = path;
f.DeletePaths = path;
f.MaxUploadFileSize = 10485760;
return f;
}
Related
I have some xml files, which are used in my application. They are stored in the same folder with application , in subfolder DATA: "C:\MyProject\DATA\".
To get the DATA folder path i use this code :
static public string GetDataFolderPath()
{
string s = System.IO.Directory.GetCurrentDirectory().Replace(#"\bin\Debug", "");
int i = s.LastIndexOf(#"\");
s = s.Substring(0, i);
i = s.LastIndexOf(#"\");
s= s.Substring(0, i);
return s + #"\Data\";
}
So when i want to deploy my application, i create a setup project, and add the DATA folder to Application folder. But after i install the program f.e. "C:\Project"(DATA folder- "C:\Project\DATA" i got the error: "folder C:\DATA is not found".
What i need to change to make things working after deployment. Why it looks for the DATA folder on 1 level higher?
Try this, it might work better:
public static string GetDataFolderPath()
{
#if DEBUG
// This will be executed in Debug build
string path = Directory.GetCurrentDirectory().Replace(#"\bin\Debug", "");
#else
// This will be executed in Release build
string path = Directory.GetCurrentDirectory();
#endif
return Path.Combine(path, "Data");
}
Or just this if you want one for both Debug and Release builds:
public static string GetDataFolderPath()
{
string path = Directory.GetCurrentDirectory().Replace(#"\bin\Debug", "");
return Path.Combine(path, "Data");
}
You have to add using System.IO; for this to work.
Maybe current directory (during launching your program) is not the same one that assemblies lie?
try:
//get the full location of the assembly
string fullPath = System.Reflection.Assembly.GetAssembly(typeof(<your class name>)).Location;
//get the folder that's in
string theDirectory = Path.GetDirectoryName( fullPath );
or
string codeBase = Assembly.GetExecutingAssembly().CodeBase;
UriBuilder uri = new UriBuilder(codeBase);
string path = Uri.UnescapeDataString(uri.Path);
return Path.GetDirectoryName(path);
How do I convert an absolute or relative URI path (e.g. /foo/bar.txt) to a (segmentwise) corresponding relative file system path (e.g. foo\bar.txt) in .NET?
My program is not an ASP.NET application.
Have you already tried Server.MapPath?
or Uri.LocalPath property? Something like following :
string uriString = "file://server/filename.ext";
// Lesson learnt - always check for a valid URI
if(Uri.IsWellFormedUriString(uriString))
{
Uri uri = new Uri(uriString);
Console.WriteLine(uri.LocalPath);
}
I figured out this way to produce a full absolute file system path from a relative or absolute URI and a base path.
With:
Uri basePathUri = new Uri(#"C:\abc\");
From a relative URI:
string filePath = new Uri(basePathUri, relativeUri).AbsolutePath;
From an absolute URI:
// baseUri is a URI used to derive a relative URI
Uri relativeUri = baseUri.MakeRelativeUri(absoluteUri);
string filePath = new Uri(basePathUri, relativeUri).AbsolutePath;
You can do this:
var localPath = Server.MapPath("/foo/bar.txt");
See MSDN for details
Not all have access to server.MapPath due to backend or framework changes, and there are lot's of way one of them is could be like this
public enum FileLocation
{
NotSet,
Disk,
Resource,
}
private static readonly string[] FileExtenstions = new[] {
".js"
,".ts"
,".vue"
,".css"
,".jpg"
,".png"
,".gif"
,".ico"
,".svg"
,".ttf"
,".eot"
,".ttf"
,".woff"
,".woff2"
,".mp4"
,".mp3"
,".emf"
};
public FileLocation IsMappedTo(Uri uri)
{
if (uri is null)
{
throw new ArgumentNullException(nameof(uri));
}
//make sure we support .net default URI contract
if (uri.IsFile)
return FileLocation.Disk;
//now assume you are looking in a web application
var path = uri.AbsolutePath;
if (path.Length == 0 || path.Equals("/",StringComparison.Ordinal) || path.Length< FileExtenstions.Min(s=>s.Length))
return FileLocation.NotSet;
//get the directory normally one would use IWebHostEnvironment.ContentRootPath different versions .net will have other methods
var dir = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot");
//get all resources names from the assembly hosting this class out side if the loop from this assembly you can also use
//you can also use GetManifestResourceNames() to use the web application's assembly
var resourceNames = new HashSet<string>(this.GetType().Assembly.GetManifestResourceNames());
var entryAssembly = Assembly.GetEntryAssembly();
if (entryAssembly != null && entryAssembly != this.GetType().Assembly)
{
foreach (var entry in entryAssembly.GetManifestResourceNames())
{
if (string.IsNullOrEmpty(entry))
resourceNames.Add(entry);
}
}
for (var i = 0; i < FileExtenstions.Length; i++)
{
if (FileExtenstions[i].Equals(path[FileExtenstions[i].Length..], StringComparison.OrdinalIgnoreCase) || path.Contains(FileExtenstions[i], StringComparison.OrdinalIgnoreCase))
{
//exists on disk
if (File.Exists(Path.Combine(dir, path.Replace("/", #"\", StringComparison.Ordinal))))
return FileLocation.Disk;
//has a file as an embedded resource with the same name (ignores the path) so you might have duplicates names
if (resourceNames.Any(a => a.EndsWith(path.Split('/')[^1], StringComparison.OrdinalIgnoreCase)))
return FileLocation.Resource;
}
}
return FileLocation.NotSet;
}
after this you just do:
switch (IsMappedTo(url))
{
case FileLocation.NotSet:
break;
case FileLocation.Disk:
break;
case FileLocation.Resource:
break;
}
How do I convert a relative path to an absolute path in a Windows application?
I know we can use server.MapPath() in ASP.NET. But what can we do in a Windows application?
I mean, if there is a .NET built-in function that can handle that...
Have you tried:
string absolute = Path.GetFullPath(relative);
? Note that that will use the current working directory of the process, not the directory containing the executable. If that doesn't help, please clarify your question.
If you want to get the path relative to your .exe then use
string absolute = Path.Combine(Application.ExecutablePath, relative);
This one works for paths on different drives, for drive-relative paths and for actual relative paths. Heck, it even works if the basePath isn't actually absolute; it always uses the current working directory as final fallback.
public static String GetAbsolutePath(String path)
{
return GetAbsolutePath(null, path);
}
public static String GetAbsolutePath(String basePath, String path)
{
if (path == null)
return null;
if (basePath == null)
basePath = Path.GetFullPath("."); // quick way of getting current working directory
else
basePath = GetAbsolutePath(null, basePath); // to be REALLY sure ;)
String finalPath;
// specific for windows paths starting on \ - they need the drive added to them.
// I constructed this piece like this for possible Mono support.
if (!Path.IsPathRooted(path) || "\\".Equals(Path.GetPathRoot(path)))
{
if (path.StartsWith(Path.DirectorySeparatorChar.ToString()))
finalPath = Path.Combine(Path.GetPathRoot(basePath), path.TrimStart(Path.DirectorySeparatorChar));
else
finalPath = Path.Combine(basePath, path);
}
else
finalPath = path;
// resolves any internal "..\" to get the true full path.
return Path.GetFullPath(finalPath);
}
It's a bit older topic, but it might be useful for someone.
I have solved a similar problem, but in my case, the path was not at the beginning of the text.
So here is my solution:
public static class StringExtension
{
private const string parentSymbol = "..\\";
private const string absoluteSymbol = ".\\";
public static String AbsolutePath(this string relativePath)
{
string replacePath = AppDomain.CurrentDomain.BaseDirectory;
int parentStart = relativePath.IndexOf(parentSymbol);
int absoluteStart = relativePath.IndexOf(absoluteSymbol);
if (parentStart >= 0)
{
int parentLength = 0;
while (relativePath.Substring(parentStart + parentLength).Contains(parentSymbol))
{
replacePath = new DirectoryInfo(replacePath).Parent.FullName;
parentLength = parentLength + parentSymbol.Length;
};
relativePath = relativePath.Replace(relativePath.Substring(parentStart, parentLength), string.Format("{0}\\", replacePath));
}
else if (absoluteStart >= 0)
{
relativePath = relativePath.Replace(".\\", replacePath);
}
return relativePath;
}
}
Example:
Data Source=.\Data\Data.sdf;Persist Security Info=False;
Data Source=..\..\bin\Debug\Data\Data.sdf;Persist Security Info=False;
I want to convert a virtual file path to a physical file path in a windows service.
I know what the physical path is for the virtual directory, so I have the following function that works, but feels like a fudge:
public static string GetPhysicalPathFromVirtual(string rootPath, string virtualPath)
{
int trailingSlash = virtualPath.IndexOf('/', 1) + 1;
int length = virtualPath.Length - trailingSlash;
string stripped = virtualPath.Substring(trailingSlash, length);
stripped = stripped.Replace(#"/", #"\");
return Path.Combine(rootPath, stripped);
}
The following example:
string test = FileHelper.GetPhysicalPathFromVirtual(#"T:\generateddocuments\output\", #"/virtualroot/folder/myfile.pdf");
Returns: T:\generateddocuments\output\folder\myfile.pdf
Is there a more elegant way to do this?
Uri class may be of help for your task.
Please note that using relative paths in services can expose a huge security hole so you should be very defensive when you code them.
Here's what I came up with:
public static string GetPhysicalPathFromVirtual(string rootPath, string virtualPath)
{
const string mandatoryVirtualPrefix = "/virtualroot/";
if (!virtualPath.StartsWith(mandatoryVirtualPrefix))
throw new ArgumentOutOfRangeException(virtualPath, string.Format("Virtual '{0}' path must start with mandatory prefix '{1}'", virtualPath, mandatoryVirtualPrefix));
var relativePath = virtualPath.Substring(mandatoryVirtualPrefix.Length);
var rootUri = new Uri(rootPath, UriKind.Absolute);
var relativeUri = new Uri(relativePath, UriKind.Relative);
var absoluteUri = new Uri(rootUri, relativeUri);
if (!rootUri.IsBaseOf(absoluteUri))
throw new ArgumentOutOfRangeException(virtualPath, string.Format("Virtual path '{0}' can't be outside of root '{1}'", virtualPath, rootPath));
return absoluteUri.LocalPath;
}
I'm trying to join a Windows path with a relative path using Path.Combine.
However, Path.Combine(#"C:\blah",#"..\bling") returns C:\blah\..\bling instead of C:\bling\.
Does anyone know how to accomplish this without writing my own relative path resolver (which shouldn't be too hard)?
What Works:
string relativePath = "..\\bling.txt";
string baseDirectory = "C:\\blah\\";
string absolutePath = Path.GetFullPath(baseDirectory + relativePath);
(result: absolutePath="C:\bling.txt")
What doesn't work
string relativePath = "..\\bling.txt";
Uri baseAbsoluteUri = new Uri("C:\\blah\\");
string absolutePath = new Uri(baseAbsoluteUri, relativePath).AbsolutePath;
(result: absolutePath="C:/blah/bling.txt")
Call Path.GetFullPath on the combined path http://msdn.microsoft.com/en-us/library/system.io.path.getfullpath.aspx
> Path.GetFullPath(Path.Combine(#"C:\blah\",#"..\bling"))
C:\bling
(I agree Path.Combine ought to do this by itself)
Path.GetFullPath(#"c:\windows\temp\..\system32")?
For windows universal apps Path.GetFullPath() is not available, you can use the System.Uri class instead:
Uri uri = new Uri(Path.Combine(#"C:\blah\",#"..\bling"));
Console.WriteLine(uri.LocalPath);
This will give you exactly what you need (path does NOT have to exist for this to work)
DirectoryInfo di = new DirectoryInfo(#"C:\blah\..\bling");
string cleanPath = di.FullName;
Path.GetFullPath() does not work with relative paths.
Here's the solution that works with both relative + absolute paths. It works on both Linux + Windows and it keeps the .. as expected in the beginning of the text (at rest they will be normalized). The solution still relies on Path.GetFullPath to do the fix with a small workaround.
It's an extension method so use it like text.Canonicalize()
/// <summary>
/// Fixes "../.." etc
/// </summary>
public static string Canonicalize(this string path)
{
if (path.IsAbsolutePath())
return Path.GetFullPath(path);
var fakeRoot = Environment.CurrentDirectory; // Gives us a cross platform full path
var combined = Path.Combine(fakeRoot, path);
combined = Path.GetFullPath(combined);
return combined.RelativeTo(fakeRoot);
}
private static bool IsAbsolutePath(this string path)
{
if (path == null) throw new ArgumentNullException(nameof(path));
return
Path.IsPathRooted(path)
&& !Path.GetPathRoot(path).Equals(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal)
&& !Path.GetPathRoot(path).Equals(Path.AltDirectorySeparatorChar.ToString(), StringComparison.Ordinal);
}
private static string RelativeTo(this string filespec, string folder)
{
var pathUri = new Uri(filespec);
// Folders must end in a slash
if (!folder.EndsWith(Path.DirectorySeparatorChar.ToString())) folder += Path.DirectorySeparatorChar;
var folderUri = new Uri(folder);
return Uri.UnescapeDataString(folderUri.MakeRelativeUri(pathUri).ToString()
.Replace('/', Path.DirectorySeparatorChar));
}
Be careful with Backslashes, don't forget them (neither use twice:)
string relativePath = "..\\bling.txt";
string baseDirectory = "C:\\blah\\";
//OR:
//string relativePath = "\\..\\bling.txt";
//string baseDirectory = "C:\\blah";
//THEN
string absolutePath = Path.GetFullPath(baseDirectory + relativePath);