Skip to content
Permalink
231 lines (194 sloc) 7.6 KB
using ModernizedAlice.ArtOfWords.BizCommon;
using ModernizedAlice.ArtOfWords.BizCommon.Model.SaveAndLoad;
using ModernizedAlice.ArtOfWords.BizCommon.Util;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Xml.Serialization;
namespace ModernizedAlice.ArtOfWords.Services.Manager
{
/// <summary>
/// 保存の結果
/// </summary>
public enum SaveResult
{
/// <summary>
/// 成功
/// </summary>
Succeed,
/// <summary>
/// 失敗したがテキストだけは一時保存できた
/// </summary>
FailedButTextFile,
/// <summary>
/// 全部失敗 T(;_;)Tオテアゲェー
/// </summary>
CompletelyFailed,
}
/// <summary>
/// 緊急保存モード
/// </summary>
/// <remarks>
/// 保存に失敗したとき、とりあえず保存できそうなところに向かって保存をかける
/// ProgramData -> ドキュメント -> デスクトップ
/// </remarks>
public enum SaveEmergencyMode
{
/// <summary>
/// ProgramDataに保存
/// </summary>
AssemblyTemp,
/// <summary>
/// ドキュメントフォルダーに保存
/// </summary>
DocumentTemp,
/// <summary>
/// デスクトップに保存
/// </summary>
FinalTemp,
}
/// <summary>
/// セーブを司るクラス
/// </summary>
public class SaveManager
{
/// <summary>
/// 一時ファイルの名前を取得する
/// </summary>
/// <param name="path">本保存用ファイルのパス</param>
/// <returns>一時ファイルの名前</returns>
private String GetTempFileName(String path)
{
String fileName = Path.GetFileName(path);
DateTime now = DateTime.Now;
return "TMP" + fileName + now.Year + now.Month + now.Day + now.Hour + now.Minute + now.Second + now.Millisecond + ".tmp";
}
private String GetBackupFilePath(String path)
{
var dirPath = SaveUtil.GetBackupDirectoryPath();
if (!Directory.Exists(dirPath))
{
Directory.CreateDirectory(dirPath);
}
return dirPath + "\\" + Path.GetFileName(path) + DateTime.Now.ToString("yyyyMMddHHmmss");
}
private String GetTempFolderPath(SaveEmergencyMode mode)
{
switch (mode)
{
case SaveEmergencyMode.AssemblyTemp:
{
string assemblyLocation = CommonDirectoryUtil.GetCommonProgramDataAppliPath();
String dirPath = Path.GetDirectoryName(assemblyLocation);
return dirPath + "\\temp";
}
case SaveEmergencyMode.DocumentTemp:
{
return System.Environment.GetFolderPath(Environment.SpecialFolder.Personal);
}
case SaveEmergencyMode.FinalTemp:
default:
{
return System.Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
}
}
}
private SaveResult SaveTempText(String path, SaveEmergencyMode mode)
{
String dirPath = GetTempFolderPath(mode);
String destPath = dirPath + "\\" + GetTempFileName(path);
try
{
if (!Directory.Exists(dirPath))
{
Directory.CreateDirectory(dirPath);
}
StreamWriter stream = new StreamWriter(new FileStream(destPath, FileMode.CreateNew), Encoding.GetEncoding("Shift-jis"));
stream.Write(ModelsComposite.DocumentModel.Text);
stream.Close();
}
catch (Exception)
{
return SaveResult.CompletelyFailed;
}
return SaveResult.Succeed;
}
public SaveResult SaveHeader(string folderPath)
{
// ちゃんとしたファイルを書き出す。
XmlSerializer serializer = new XmlSerializer(typeof(LoadFileInfo));
var outstream = new System.IO.FileStream(folderPath + "\\" + "version.xml", System.IO.FileMode.Create);
var saveInfo = new LoadFileInfo() { version = FileVersion.Ver4_0_0 };
serializer.Serialize(outstream, saveInfo);
outstream.Close();
return SaveResult.Succeed;
}
public SaveResult SaveDocumentFile(String folderPath)
{
// ちゃんとしたファイルを書き出す。
XmlSerializer serializer = new XmlSerializer(typeof(XmlSaveObjectVer4_0_0));
// Tempフォルダーに書き出し隔離
FileStream outstream = new System.IO.FileStream(folderPath + "\\" + "document.xml", System.IO.FileMode.Create);
var saveObj = new XmlSaveObjectVer4_0_0();
saveObj.SetSavableObject();
serializer.Serialize(outstream, saveObj);
outstream.Close();
return SaveResult.Succeed;
}
public SaveResult Save(String path)
{
/*
// 何が何でもテキストだけは保存する
// 1. exeの直下にぶっ込む
if (SaveTempText(path, SaveEmergencyMode.AssemblyTemp) == SaveResult.CompletelyFailed)
{
// 2. それも無理ならドキュメント直下にぶっ込む
if (SaveTempText(path, SaveEmergencyMode.DocumentTemp) == SaveResult.CompletelyFailed)
{
// 2. それも無理ならデスクトップ直下にぶっ込む
if (SaveTempText(path, SaveEmergencyMode.FinalTemp) == SaveResult.CompletelyFailed)
{
return SaveResult.CompletelyFailed;
}
}
}*/
try
{
string tempFolder = Path.GetTempPath() + Path.GetRandomFileName();
Directory.CreateDirectory(tempFolder);
SaveHeader(tempFolder);
SaveDocumentFile(tempFolder);
CreateZip(path, tempFolder);
File.Copy(path, GetBackupFilePath(path), true);
Directory.Delete(tempFolder, true);
}
catch (Exception )
{
return SaveResult.FailedButTextFile;
}
return SaveResult.Succeed;
}
private void CreateZip(string destPath, string srcZipPath)
{
//ZipFileを作成する
using (Ionic.Zip.ZipFile zip = new Ionic.Zip.ZipFile())
{
zip.AlternateEncoding =
System.Text.Encoding.GetEncoding("shift_jis");
zip.CompressionLevel = Ionic.Zlib.CompressionLevel.BestCompression;
zip.UseZip64WhenSaving = Ionic.Zip.Zip64Option.AsNecessary;
//エラーが出てもスキップする。デフォルトはThrow。
zip.ZipErrorAction = Ionic.Zip.ZipErrorAction.Throw;
zip.Comment = "donotopen";
zip.Password = "ohaDNelson";
zip.Encryption = Ionic.Zip.EncryptionAlgorithm.WinZipAes256;
//フォルダを追加する
zip.AddDirectory(srcZipPath);
zip.Save(destPath);
}
}
}
}