Where is |DataDirectory| defined? - sql

This is a follow up question of Where is that file on my system?
Tons of questions and answers all over SO and the internet but I can't find any that gives an answer to this specific question.
All is default but I can't find the file itself,
IT'S NOT THERE.
Where/how gets |DataDirectory| defined?
Where is the file saved, does it even exist? If not, what is going on?
edit: The file isn't located at AppDomain.CurrentDomain.GetData("DataDirectory").ToString(); all (sqattered) answers tell me it should be. It must be somewhere as the debugger breaks nagging about the model unequals the table when I change the model. It's not there.

The |DataDirectory| isn't a file per se. A quote from a rather old MSDN article:
By default, the |DataDirectory| variable will be expanded as follow:
For applications placed in a directory on the user machine, this will be the app's (.exe) folder.
For apps running under ClickOnce, this will be a special data folder created by ClickOnce
For Web apps, this will be the App_Data folder
Under the hood, the value for |DataDirectory| simply comes from a property on the app domain. It is possible to change that value and override the default behavior by doing this:
AppDomain.CurrentDomain.SetData("DataDirectory", newpath)
A further quote regarding your schema inconsistencies:
One of the things to know when working with local database files is that they are treated as any other content files. For desktop projects, it means that by default, the database file will be copied to the output folder (aka bin) each time the project is built. After F5, here's what it would look like on disk
MyProject\Data.mdf
MyProject\MyApp.vb
MyProject\Bin\Debug\Data.mdf
MyProject\Bin\Debug\MyApp.exe
At design-time, MyProject\Data.mdf is used by the data tools. At run-time, the app will be using the database under the output folder. As a result of the copy, many people have the impression that the app did not save the data to the database file. In fact, this is simply because there are two copies of the data file involved. Same applies when looking at the schema/data through the database explorer. The tools are using the copy in the project, not the one in the bin folder.

The |datadirectory| algorithm is located in the System.Data.dll assembly, in the internal System.Data.Common.DbConnectionOptions class. Here it as displayed by ILSpy (note the source it's now available in the reference source repository: https://github.com/Microsoft/referencesource/blob/e458f8df6ded689323d4bd1a2a725ad32668aaec/System.Data.Entity/System/Data/EntityClient/DbConnectionOptions.cs):
internal static string ExpandDataDirectory(string keyword,
string value,
ref string datadir)
{
string text = null;
if (value != null &&
value.StartsWith("|datadirectory|", StringComparison.OrdinalIgnoreCase))
{
string text2 = datadir;
if (text2 == null)
{
// 1st step!
object data = AppDomain.CurrentDomain.GetData("DataDirectory");
text2 = (data as string);
if (data != null && text2 == null)
throw ADP.InvalidDataDirectory();
if (ADP.IsEmpty(text2))
{
// 2nd step!
text2 = AppDomain.CurrentDomain.BaseDirectory;
}
if (text2 == null)
{
text2 = "";
}
datadir = text2;
}
// 3rd step, checks and normalize
int length = "|datadirectory|".Length;
bool flag = 0 < text2.Length && text2[text2.Length - 1] == '\\';
bool flag2 = length < value.Length && value[length] == '\\';
if (!flag && !flag2)
{
text = text2 + '\\' + value.Substring(length);
}
else
{
if (flag && flag2)
{
text = text2 + value.Substring(length + 1);
}
else
{
text = text2 + value.Substring(length);
}
}
if (!ADP.GetFullPath(text).StartsWith(text2, StringComparison.Ordinal))
throw ADP.InvalidConnectionOptionValue(keyword);
}
return text;
}
So it looks in the current AppDomain data first (by default, there is no "DataDirectory" data defined I believe) and then gets to the current AppDomain base directory. The rest is mostly checks for path roots and paths normalization.

On the MSDN forum there is a similiar but simplified question about this, which says:
By default the |DataDirectory| points to your application folder (as you figured out yourself in the original question: to the App_Data).
Since is just a substitution path to your database, you can define the path yourself with the AppDomain.SetData.

Related

BIRT PDF render: fonts register time

We use BIRT since version 2 (currently using 4.2.2) and have always been plagued by the PDF (itext?) fonts register time.
org.eclipse.birt.report.engine.layout.pdf.font.FontMappingManagerFactory$2 run
INFO: register fonts in c:/windows/fonts cost:17803ms
This process only occurs the first time the render is used. Subsequent renders are not problematic.
The problem seems to be the time wasted when accessing ALL the system connected DRIVES.
Editing the fontsConfig.xml in org.eclipse.birt.report.engine.fonts plugin, reducing the search paths does not resolve the issue. ALL connected drives are accessed by BIRT.
<font-paths>
<path path="/windows/fonts" />
</font-paths>
Is there a simple solution for this without having to render a "dummy" report to initialize BIRT in the background??
This isn't necessarily a solution, but potentially another option as a workaround that I came up with after we noticed the same issue and did some investigating. It's also (IMO) better than generating a dummy report.
On startup (or at some other point depending on your needs), make the following call:
FontMappingManagerFactory.getInstance().getFontMappingManager(format, Locale.getDefault());
Why?
BIRT uses com.lowagie.text.FontFactory (iText) to register the fonts. Calls to that class are made from
org.eclipse.birt.report.engine.layout.pdf.font.FontMappingManagerFactory which also spits out the log entries given in the question.
Within FontMappingManagerFactory we can see where the log entries are coming from:
private static void registerFontPath( final String fontPath )
{
AccessController.doPrivileged( new PrivilegedAction<Object>( ) {
public Object run( )
{
long start = System.currentTimeMillis( );
File file = new File( fontPath );
if ( file.exists( ) )
{
if ( file.isDirectory( ) )
{
FontFactory.registerDirectory( fontPath );
}
else
{
FontFactory.register( fontPath );
}
}
long end = System.currentTimeMillis( );
logger.info( "register fonts in " + fontPath + " cost:"
+ ( end - start ) + "ms" ); // <-- Here!
return null;
}
} );
}
Working backwards, we see that registerFontPath(String) is called by loadFontMappingConfig(URL), etc etc resulting in the following call hierarchy:
getFontMappingManager(String, Locale)
`-- createFontMappingManager(String, Locale)
`-- loadFontMappingConfig(String)
`-- loadFontMappingConfig(URL)
`-- registerFontPath(String)
And getFontMappingManager(String, Locale) is the public method we can call. More importantly, however, is that the method also caches the FontMappingManager that gets created:
public synchronized FontMappingManager getFontMappingManager(
String format, Locale locale )
{
HashMap managers = (HashMap) cachedManagers.get( format );
if ( managers == null )
{
managers = new HashMap( );
cachedManagers.put( format, managers );
}
FontMappingManager manager = (FontMappingManager) managers.get( locale );
if ( manager == null )
{
manager = createFontMappingManager( format, locale );
managers.put( locale, manager );
}
return manager;
}
As a result, when you're ready to go generate your PDF, it will already be in the cache and BIRT won't have to go call down to the FontFactory and re-register the fonts.
But what about the format String?
This bit is some speculation, but I think the valid options are the OUTPUT_FORMAT_XXX Strings in IRenderOption. For our purposes I debugged to see that we want the String to be pdf. Considering that's also conveniently the desired output format, I assume IRenderOption.OUTPUT_FORMAT_PDF is the route to go.
If you're ultimately creating both PDFs and HTML files, it appears that you could make the call twice (once with IRenderOption.OUTPUT_FORMAT_PDF and once with IRenderOption.OUTPUT_FORMAT_HTML) and only the font config files which are different will be considered (ie. you won't be reading from c:/windows/fonts twice).
All that said, take this with a grain of salt. I believe this is completely safe, since the purpose of getFontMappingManager(String, Locale) is to get an object for accessing available fonts, etc., and it conveniently caches the result. However, if that were to change in the future you may end up with a tricky-to-find bug on your hands.
I would suggest that you can modify the fontsConfig.xml and remove the fonts that you no longer need. Also remove the drives that you dont want birt to check for fonts.

Check if a file exists in the project in WinRT

I have a WinRT Metro project which displays images based on a selected item. However, some of the images selected will not exist. What I want to be able to do is trap the case where they don't exist and display an alternative.
Here is my code so far:
internal string GetMyImage(string imageDescription)
{
string myImage = string.Format("Assets/MyImages/{0}.jpg", imageDescription.Replace(" ", ""));
// Need to check here if the above asset actually exists
return myImage;
}
Example calls:
GetMyImage("First Picture");
GetMyImage("Second Picture");
So Assets/MyImages/SecondPicture.jpg exists, but Assets/MyImages/FirstPicture.jpg does not.
At first I thought of using the WinRT equivalent of File.Exists(), but there doesn't appear to be one. Without having to go to the extent of trying to open the file and catching an error, can I simply check if either the file exists, or the file exists in the project?
You could use GetFilesAsync from here to enumerate the existing files. This seems to make sense considering you have multiple files which might not exist.
Gets a list of all files in the current folder and its sub-folders. Files are filtered and sorted based on the specified CommonFileQuery.
var folder = await StorageFolder.GetFolderFromPathAsync("Assets/MyImages/");
var files = await folder.GetFilesAsync(CommonFileQuery.OrderByName);
var file = files.FirstOrDefault(x => x.Name == "fileName");
if (file != null)
{
//do stuff
}
Edit:
As #Filip Skakun pointed out, the resource manager has a resource mapping on which you can call ContainsKey which has the benefit of checking for qualified resources as well (i.e. localized, scaled etc).
Edit 2:
Windows 8.1 introduced a new method for getting files and folders:
var result = await ApplicationData.Current.LocalFolder.TryGetItemAsync("fileName") as IStorageFile;
if (result != null)
//file exists
else
//file doesn't exist
There's two ways you can handle it.
1) Catch the FileNotFoundException when trying to get the file:
Windows.Storage.StorageFolder installedLocation =
Windows.ApplicationModel.Package.Current.InstalledLocation;
try
{
// Don't forget to decorate your method or event with async when using await
var file = await installedLocation.GetFileAsync(fileName);
// Exception wasn't raised, therefore the file exists
System.Diagnostics.Debug.WriteLine("We have the file!");
}
catch (System.IO.FileNotFoundException fileNotFoundEx)
{
System.Diagnostics.Debug.WriteLine("File doesn't exist. Use default.");
}
catch (Exception ex)
{
// Handle unknown error
}
2) as mydogisbox recommends, using LINQ. Although the method I tested is slightly different:
Windows.Storage.StorageFolder installedLocation =
Windows.ApplicationModel.Package.Current.InstalledLocation;
var files = await installedLocation.GetFilesAsync(CommonFileQuery.OrderByName);
var file = files.FirstOrDefault(x => x.Name == fileName);
if (file != null)
{
System.Diagnostics.Debug.WriteLine("We have the file!");
}
else
{
System.Diagnostics.Debug.WriteLine("No File. Use default.");
}
BitmapImage has an ImageFailed event that fires if the image can't be loaded. This would let you try to load the original image, and then react if it's not there.
Of course, this requires that you instantiate the BitmapImage yourself, rather than just build the Uri.
Sample checking for resource availability for c++ /cx (tested with Windows Phone 8.1):
std::wstring resPath = L"Img/my.bmp";
std::wstring resKey = L"Files/" + resPath;
bool exists = Windows::ApplicationModel::Resources::Core::ResourceManager::Current->MainResourceMap->HasKey(ref new Platform::String(resKey.c_str()));

How to get the name of a temporary file created by File.tmpfile in D2?

I need to generate a temporary file, fill it with some data and feed it to an external program. Based on description of D available here I'm using File.tmpfile() method:
auto f = File.tmpfile();
writeln(f.name());
which doesn't provide a way to get the generated file name. It's documented that name might be empty. In Python I would do that like this:
(o_fd, o_filename) = tempfile.mkstemp('.my.own.suffix')
Is there a simple, safe and cross-platform way to do that in D2?
Due to how tmpfile() works, if you need the name of the file you can't use it. However, I have already created a module to work with temporary files. It uses conditional compilation to decide on the method of finding the temporary directory. On windows, it uses the %TMP% environment variable. On Posix, it uses /tmp/.
This code is licensed under the WTFPL, so you can do whatever you want with it.
module TemporaryFiles;
import std.conv,
std.random,
std.stdio;
version(Windows) {
import std.process;
}
private static Random rand;
/// Returns a file with the specified filename and permissions
public File getTempFile(string filename, string permissions) {
string path;
version(Windows) {
path = getenv("TMP") ~ '\\';
} else version(Posix) {
path = "/tmp/";
// path = "/var/tmp/"; // Uncomment to survive reboots
}
return File(path~filename, permissions);
}
/// Returns a file opened for writing, which the specified filename
public File getTempFile(string filename) {
return getTempFile(filename, "w");
}
/// Returns a file opened for writing, with a randomly generated filename
public File getTempFile() {
string filename = to!string(uniform(1L, 1000000000L, rand)) ~ ".tmp";
return getTempFile(filename, "w");
}
To use this, simply call getTempFile() with whatever arguments you want. Defaults to write permission.
As a note, the "randomly generated filenames" aren't truely random, as the seed is set at compile time.

How to tell if a file is an EXE or a DLL?

If you've gotten the file extensions messed up, how can you tell an executable apart from a DLL?
They both seem to have entry points and everything...
if anyone interested here is the code in C#, tested for 32 bit PE files.
public static class PECheck
{
public static bool IsDll(Stream stream)
{
using (BinaryReader reader = new BinaryReader(stream))
{
byte[] header = reader.ReadBytes(2); //Read MZ
if (header[0] != (byte)'M' && header[1] != (byte)'Z')
throw new Exception("Invalid PE file");
stream.Seek(64 - 4, SeekOrigin.Begin);//read elf_new this is the offset where the IMAGE_NT_HEADER begins
int offset = reader.ReadInt32();
stream.Seek(offset, SeekOrigin.Begin);
header = reader.ReadBytes(2);
if (header[0] != (byte)'P' && header[1] != (byte)'E')
throw new Exception("Invalid PE file");
stream.Seek(20, SeekOrigin.Current); //point to last word of IMAGE_FILE_HEADER
short readInt16 = reader.ReadInt16();
return (readInt16 & 0x2000) == 0x2000;
}
}
}
This info is located in the PE header. To view it, you can open it with a PE explorer such as the NTCore CFF Explorer and open the Characterics field of the file header, where you can find whether it is a DLL or executable.
Look at this article for a good explanation of a portable executable on windows.
And then look at the section about the PE header. Also the code there-in shows in C the way to open and examine a PE file using Win32. This information you are looking for is stored in the IMAGE_FILE_HEADER. Specifically in the Characteristics field which would include the flag IMAGE_FILE_DLL 0x2000 if it is a dll.
That should give you enough information to create a small utility that makes the determination of a bunch of files if that is what you are looking for.
The most relevant bits of code for reference purposes, copied from the article above and edited to remove extraneous detail/error handling.
void DumpFile(LPWSTR filename)
{
HANDLE hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
HANDLE hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
LPVOID lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)lpFileBase;
PIMAGE_NT_HEADERS pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + (DWORD)pDosHeader->e_lfanew);
if ((pNTHeader->FileHeader.Characteristics & IMAGE_FILE_DLL))
printf("dll");
if ((pNTHeader->FileHeader.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE))
printf("exe");
else
printf("????");
UnmapViewOfFile(lpFileBase);
CloseHandle(hFileMapping);
CloseHandle(hFile);
}
dumpbin *.* | grep "File Type"
Works for me. I don't exactly remember what to use if you don't have grep installed, but I suggest you do.
Grab OllyDbg and open the EXE/DLL in it. Bring up the memory map by clicking the big M button at the top. Scroll down till you find the PE header of the module which corresponds to your program. Double click to open it in memory dump. Scroll down to where you see PE signature (probably 0xF8 from image base) and if it's a DLL then Characteristics will have the DLL flag on it. Characteristics should be a few entires down from PE signature.

How to access local files on server in JBoss application?

I am looking to access all files in a local directory in a JBoss application. I can put the directory anywhere in my war including WEB-INF if necessary. I then want to access each file in the directory sequentially. In a normal application if the directory was in the run location I could do something like:
File f = new File("myDir");
if(f.isDirectory && f.list().length != 0)
{
for(String fileName : f.list())
{
//do Read-Only stuff with fileName
}
}
I'm looking for a best-practices solution, so if I'm going about this wrong then please point me to the right way to access an unknown set of resources.
First thing to note: you're only going to get this to work if you have an exploded WAR, or possibly if the servlet container explodes the WAR for you.
With that caveat in mind, you could use ServletContext.getRealPath() as your starting point. You'd need to know the name of at least one file in the webapp's root directory, and go from there:
String knownFilePath = servletContext.getRealPath("knownFile");
File webAppRootDir = new File(knownFilePath).getParentFile();
// and then as per the question
File f = webAppRootDir ;
if(f.isDirectory && f.list().length != 0)
{
for(String fileName : f.list())
{
//do Read-Only stuff with fileName
}
}
Getting hold of ServletContext is left as an exercise for the reader.