Skip to content

Instantly share code, notes, and snippets.

@jogibear9988
Created July 14, 2013 16:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jogibear9988/5994727 to your computer and use it in GitHub Desktop.
Save jogibear9988/5994727 to your computer and use it in GitHub Desktop.
public class PageUriLocator
{
public static string GetUri<T>() where T : Page
{
var typeName = typeof(T).Name;
var allXamlFiles = ReadAssemblyResource(typeof(T).Assembly);
var fileName = new Regex(@"/" + typeName.ToLower() + @"\.xaml");
var uri = (allXamlFiles.Where(xamlFile => fileName.IsMatch(xamlFile.ToLower()))
.Select(xamlFile => xamlFile))
.FirstOrDefault();
if (uri == null)
{
fileName = new Regex(@"[[\w]*/?]?" + typeName.ToLower() + @"\.xaml");
uri = (allXamlFiles.Where(xamlFile => fileName.IsMatch(xamlFile.ToLower()))
.Select(xamlFile => xamlFile))
.FirstOrDefault();
}
if (uri != null)
return uri.Substring(0, uri.Length - 5);
return uri;
}
private static Dictionary<Assembly, List<string>> assemblyFilenames=new Dictionary<Assembly, List<string>>();
private static List<string> ReadAssemblyResource(Assembly a)
{
//Warning: The Assembly needs to contain a app.xaml for this to work!!!!
List<string> fn;
if (assemblyFilenames.TryGetValue(a, out fn))
return fn;
byte[] binaryData = GetResourceInByteArray(a);
var fileNames = new List<string>();
// the first x bytes of the resource stream we are not interested in
bool start = false;
var appXamlName = Encoding.Unicode.GetBytes("app.xaml");
for (int i = 0; i < binaryData.Length; i++)
{
if (i < binaryData.Length - 255 && i > 0)
{
// 6100700070002E00780061006D006C00
if (!start)
{
int x = 0;
start = appXamlName.All(b => binaryData[i + x++] == b);
// wenn der name "app.xaml" geunden wurde, einfach nochmal 3 byte zurück, damit man normal von vorne die Länge auslesen kann
if (start)
i = i - 3;
}
if (start)
{
int length = binaryData[i + 1];
if (length == 0)
{
length = binaryData[i + 2];
}
if (length > 255)
return fileNames; // name cannot be longer then 255 characters
// wenn der name mit 01 anfängt, muss man um 1 verschieben
if (binaryData[i + 3] == 1)
i = i + 1;
// assemble the filename
string fileName = "";
for (int j = 0; j < length; j += 2)
{
fileName += Convert.ToChar(binaryData[j + i + 3]);
}
fileNames.Add(fileName);
i += length + 4;
}
}
}
assemblyFilenames.Add(a, fileNames);
return fileNames;
}
private static byte[] GetResourceInByteArray(Assembly a)
{
// get the assembly name
var assemblyName = a.FullName.Split(',')[0];
// a list of resources is saved in an embedded resource file called [AssemblyName].g.resources
var resourceName = assemblyName + ".g.resources";
// read binary data from the stream
var resourceStream = a.GetManifestResourceStream(resourceName);
var streamReader = new BinaryReader(resourceStream);
return streamReader.ReadBytes((int)resourceStream.Length);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment