您的位置:首页 > 编程语言 > C#

【Csharp】侦测程序异常退出并恢复丢失数据的方法

2016-10-06 11:39 302 查看
我们会发现好多编辑工具类程序在遇到断电、死机等异常退出后,再次打开会提示用户是否恢复丢失的数据,那么怎么实现呢?

这几天在开发一款无纸化试题管理系统,需要实现这个功能,于是仔细想了一下,下面总结一下具体实现步骤。

首先建立一个新的.cs文件,用于管理程序数据的快速存取,代码如下:

using Microsoft.Win32;

//用于管理程序数据存取
namespace 数据管理
{
public static class 存储管理
{
//获取注册表软件数据一般存储区域
static RegistryKey 注册表软件数据区 = Registry.LocalMachine.OpenSubKey("SOFTWARE", true);
//此处填写开发者、工作室、公司或集团的名称
static string 软件制作组织;
//填写当前开发项目的名称
static string 产品名称;
//当前程序数据在注册表存储区域
static RegistryKey 数据存储区域;

//初始化数据存储配置
public static void 初始存储区(string 作者,string 产品)
{
软件制作组织 = 作者;
产品名称 = 产品;
数据存储区域 = 注册表软件数据区.OpenSubKey(作者, true).OpenSubKey(产品, true);
}

//在注册表位置查找名为“名字”的项是否存在
private static bool 注册表存在(string 名字,string[] 注册表位置)
{
foreach (string 值 in 注册表位置)
{
if (值 == 名字)
{
return true;
}
}
return false;
}

//查找是否存在“数据名”数据
private static bool 数据存在(string 数据名)
{
if (!注册表存在(软件制作组织, 注册表软件数据区.GetSubKeyNames())) return false;
if (!注册表存在(产品名称, 注册表软件数据区.OpenSubKey(软件制作组织, true).GetSubKeyNames())) return false;
string[] 数据组;
数据组 = 数据存储区域.GetValueNames();
foreach (string 值 in 数据组)
{
if (值 == 数据名)
{
return true;
}
}
return false;
}

//将一个数据值存入注册表
public static void 写入数据(string 数据名, string 数据值)
{
if (!注册表存在(软件制作组织, 注册表软件数据区.GetSubKeyNames())) 注册表软件数据区.CreateSubKey(软件制作组织);
if (!注册表存在(产品名称, 注册表软件数据区.OpenSubKey(软件制作组织, true).GetSubKeyNames())) 注册表软件数据区.OpenSubKey(软件制作组织, true).CreateSubKey(产品名称);
数据存储区域.SetValue(数据名, 数据值);
}

//读入一个注册表数据到字符串
public static string 读入数据(string 数据名)
{
if (!数据存在(数据名)) return null;
return 数据存储区域.GetValue(数据名).ToString();
}

//删除一个名为数据名的数据值
public static void 删除数据(string 数据名)
{
if(数据存在(数据名)) 数据存储区域.DeleteSubKeyTree(数据名);
}
}
}
接着打开主窗体的那个.cs文件

我们加一个程序初始化函数,代码如下:

public void 程序初始化()
{
存储管理.初始存储区("科技羊无纸化答题系统", "试题制作");
if (存储管理.读入数据("正常退出程序") != null && 存储管理.读入数据("正常退出程序") != "是") MessageBox.Show("系统侦测到您上次属于异常退出程序", "科技羊无纸化试题制作器");
存储管理.写入数据("正常退出程序", "否");
}接着,我们给程序的退出函数做一下修改,代码如下:
private void 退出按钮事件(object sender, EventArgs e)
{
DialogResult 询问对话框 = MessageBox.Show("确定要退出科技羊无纸化试题制作器吗?", "科技羊无纸化试题制作器", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
if(询问对话框 == DialogResult.Cancel)
{
return;
}
else if (询问对话框 == DialogResult.OK)
{
存储管理.写入数据("正常退出程序", "是");
Environment.Exit(0);
}
}

还有Form里的退出按钮
private void 程序退出事件(object sender, FormClosingEventArgs e)
{
DialogResult 询问对话框 = MessageBox.Show("确定要退出科技羊无纸化试题制作器吗?", "科技羊无纸化试题制作器", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
if (询问对话框 == DialogResult.Cancel)
{
e.Cancel = true;
return;
}
else if (询问对话框 == DialogResult.OK)
{
存储管理.写入数据("正常退出程序", "是");
Environment.Exit(0);
}
}

很显然,这样在程序正常退出时,程序在注册表存储的“正常退出程序“的值为"是",非正常退出时则为"否",初次打开程序为null
因此在不为null且不为"是"时为异常退出程序!

好了,这样检测程序是否异常退出的功能就实现了,效果如图:



那么如何实现恢复上次数据呢?其实很简单,下面就简单的讲一下思路吧:

首先我们在我们程序代码里所有会改变程序内定义的变量的值的地方,都加上上面存储管理系统里的存储函数,把每次的数据更新至注册表里存储,并且定义一个 

public void 读入全部临时数据 () 

{

            XXX = 存储管理.读入数据("XXX");

            YYY = 存储管理.读入数据("YYY");

            ZZZ = 存储管理.读入数据("ZZZ");

            ......

}

其次要做的是在声明一个bool 修改保存 = true用于表示修改是否已经保存

用户每在上次保存前发生一次修改,执行一次这两行代码: 

修改保存 = false;
存储管理.写入数据("修改保存", "否");

用户每次保存执行以下两行代码:

修改保存 = true;
存储管理.写入数据("修改保存", "是");
然后我们在之前的程序退出的函数里加入以下代码:
DialogResult 询问对话框 = MessageBox.Show("文件尚未保存,是否立即保存?", "保存文件", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (询问对话框 == DialogResult.Nol)
{
存储管理.写入数据("修改保存", "是");
保存文件();
}
else if (询问对话框 == DialogResult.OK)
{
存储管理.写入数据("修改保存", "是");

}
这样得程序退出前会先询问用户是否保存,无论用户选择是还是否,都说明用户想要保留的数据已保留,因此都要将注册表里的"修改保存"的值改为"是"

最后我们再找到我们之前加的 public void 程序初始化(),改为如下代码:

public void 程序初始化()
{
存储管理.初始存储区("科技羊无纸化答题系统", "试题制作");
if (存储管理.读入数据("正常退出程序") != null && 存储管理.读入数据("正常退出程序") != "是")
{
DialogResult 恢复对话框 = MessageBox.Show("系统侦测到您上次属于异常退出程序,是否立即恢复丢失数据?", "科技羊无纸化试题制作器",MessageBoxButtons.YesNo,MessageBoxIcon.Question);
if(恢复对话框 == DialogResult.Yes)
{
读入全部临时数据();
//文件流等需要手动重新打开
编辑试卷文件 = new FileStream(存储管理.读入数据("当前试卷文件名称"), FileMode.Create, FileAccess.Write);
}

}
存储管理.写入数据("正常退出程序", "否");
}
效果如图所示:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息