Mini Kabibi Habibi
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Threading;
#if !REALTORWORLDDEMO
using System.Windows;
using System.Deployment.Application;
using DevExpress.Internal.DXWindow;
#endif
#if REALTORWORLDDEMO
namespace DevExpress.RealtorWorld.Xpf.Helpers {
#else
namespace DevExpress.DemoData.Helpers {
#endif
public sealed class ReusableStream : IDisposable {
Stream data;
AutoResetEvent mutex;
public ReusableStream() {
this.mutex = new AutoResetEvent(true);
}
public Stream Data {
get { return data; }
set {
data = value;
if(data != null && !data.CanSeek)
data = StreamHelper.CopyToMemoryStream(data);
}
}
public void Reset() {
this.mutex.WaitOne();
if(this.data != null)
this.data.Seek(0, SeekOrigin.Begin);
}
public void Dispose() {
this.mutex.Set();
}
}
public static class DataFilesHelper {
static object dataFilesLock = new object();
static Dictionary<string, ReusableStream> dataFiles = new Dictionary<string, ReusableStream>();
public static string DataDirectory {
get {
#if REALTORWORLDDEMO
return AppDomain.CurrentDomain.BaseDirectory;
#else
return EnvironmentHelper.IsClickOnce ? ApplicationDeployment.CurrentDeployment.DataDirectory : GetEntryAssemblyDirectory();
#endif
}
}
public static string DataPath { get { return "Data"; } }
public static string FindFile(string fileName, string directoryName) {
string appPath = DataDirectory;
if(appPath == null) return null;
string dirName = Path.GetFullPath(appPath);
for(int n = 0; n < 9; n++) {
string path = dirName + "\\" + directoryName + "\\" + fileName;
try {
if(File.Exists(path) || Directory.Exists(path))
return path;
} catch { }
dirName += @"\..";
}
throw new FileNotFoundException(fileName + " not found");
}
public static string FindDirectory(string directoryName) {
string appPath = DataDirectory;
if(appPath == null) return null;
string dirName = Path.GetFullPath(appPath);
for(int n = 0; n < 9; n++) {
string path = dirName + "\\" + directoryName;
try {
if(Directory.Exists(path))
return path;
} catch { }
dirName += @"\..";
}
throw new DirectoryNotFoundException(directoryName + " not found");
}
public static ReusableStream GetDataFile(string name) {
ReusableStream stream;
bool loadData = false;
lock(dataFilesLock) {
if(!dataFiles.TryGetValue(name, out stream)) {
stream = new ReusableStream();
loadData = true;
dataFiles.Add(name, stream);
}
}
stream.Reset();
if(loadData) {
stream.Data = GetDataFileCore(name);
}
return stream;
}
#if !REALTORWORLDDEMO
public static void UnpackData(params string[] archiveNames) {
if(!EnvironmentHelper.IsClickOnce) return;
string archivesDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Data");
string dataDirectory = Path.Combine(ApplicationDeployment.CurrentDeployment.DataDirectory, "Data");
string keyPath = Path.Combine(archivesDirectory, "Key");
FileStream keyStream = null;
int i = 60;
for(; --i >= 0; ) {
try {
keyStream = new FileStream(keyPath, FileMode.CreateNew, FileAccess.Write, FileShare.None);
break;
} catch {
try {
File.Delete(keyPath);
} catch {
Thread.Sleep(1000);
}
}
}
if(i < 0) {
MessageBox.Show("Unpack data error", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
try {
foreach(string archiveName in archiveNames) {
string archivePath = Path.Combine(archivesDirectory, archiveName);
if(!File.Exists(archivePath)) continue;
using(FileStream archiveStream = new FileStream(archivePath, FileMode.Open, FileAccess.Read)) {
InternalZipFileCollection archiveFiles = InternalZipArchive.Open(archiveStream);
foreach(InternalZipFile archiveFile in archiveFiles) {
string dataFilePath = Path.Combine(dataDirectory, archiveFile.FileName);
string dataFileDirectory = Path.GetDirectoryName(dataFilePath);
Directory.CreateDirectory(dataFileDirectory);
byte[] data = new byte[archiveFile.UncompressedSize];
archiveFile.FileDataStream.Read(data, 0, data.Length);
try {
File.WriteAllBytes(dataFilePath, data);
} catch { }
}
}
}
} finally {
try {
keyStream.Close();
File.Delete(keyPath);
} catch { }
}
}
#endif
static Stream GetDataFileCore(string name) {
string filePath = FindFile(name, DataPath);
FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
return fileStream;
}
static string GetEntryAssemblyDirectory() {
Assembly curr = Assembly.GetEntryAssembly();
if(curr == null) return null;
string appPath = curr.Location;
return Path.GetDirectoryName(appPath);
}
}
}