注意:
運行代碼需要添加System.configuration.install.dll的引用。
安裝配置類在System.Configuration.Install命名空間內。
TransactedInstaller就像資料庫中的Transaction(事務),整個過程要麼全部執行,要麼一點也不執行,這需要執行過程中一旦有不可修正的錯誤發生,要進行復原(還原)操作。而.NET中的安裝程式類:Installer類(System.Configuration.Install命名空間內)並沒有內建這樣的功能。如果在Install方法中出現了異常,RollBack方法是不會被調用的。
比如定義一個安裝程式類,在Install方法中拋出異常!
class MyInstaller : Installer
{
public override void Install(IDictionary stateSaver)
{
base.Install(stateSaver);
throw new Exception();
}
public override void Rollback(IDictionary savedState)
{
base.Rollback(savedState);
Console.WriteLine("還原");
}
public override void Uninstall(IDictionary savedState)
{
base.Uninstall(savedState);
Console.WriteLine("卸載");
}
}
然後運行:
new MyInstaller().Install(new Hashtable());
結果就是普通的未處理異常,進程結束。
當然,你可以自己寫一個類似的方法來完成相應功能,比如下面這個類:
/// <summary>
/// 代碼,稍作修改自:
/// https://groups.google.com/group/microsoft.public.dotnet.languages.csharp/browse_thread/thread/4d45e9ea5471cba4/4519371a77ed4a74?hl=en
/// </summary>
class InstallHelper
{
public static void Install(bool uninstall, Installer inst)
{
try
{
Console.WriteLine(uninstall ? "uninstalling" : "installing");
using (inst)
{
IDictionary state = new Hashtable();
try
{
if (uninstall)
{
inst.Uninstall(state);
}
else
{
inst.Install(state);
inst.Commit(state);
}
}
catch
{
try
{
inst.Rollback(state);
}
catch { }
throw;
}
}
}
catch (Exception ex)
{
Console.Error.WriteLine(ex.Message);
}
}
}
最後,使用TransactedInstaller也可以(抱歉……文章的主題這麼晚才出現),只需要把安裝程式添加到子安裝程式中(通過Installer類的Installers屬性)。
代碼:
var transactedIns = new TransactedInstaller();
transactedIns.Installers.Add(new MyInstaller());
transactedIns.Install(new Hashtable());
輸出:
Running a transacted installation.
Beginning the Install phase of the installation.
An exception occurred during the Install phase.
System.Exception: Exception of type 'System.Exception' was thrown.
The Rollback phase of the installation is beginning.
還原
The Rollback phase completed successfully.
Unhandled Exception: System.InvalidOperationException: The installation failed,
and the rollback has been performed. ---> System.Exception: Exception of type 'S
ystem.Exception' was thrown.
可以看到,還原作業已經被執行,Install方法內的異常被封裝成InvalidOperationException然後再次拋出。