我有一个用 DTF 编写的延迟自定义操作 DLL,它将一组 .RDL 文件发布到 SQL Server 报告 Web 服务。一切运行良好,我可以捕获各种 Try Catch 块中的大部分错误情况。
我唯一遇到的问题是,如果用户在发布时按下安装程序中的取消按钮。它会立即弹出一条消息,询问我是否要取消安装,但如果我回答是,则会抛出一条消息:
引发了 Microsoft.Deployment.WindowsInstaller.InstallCanceledException 类型的异常
和一个确定按钮。
我尝试添加一个特殊的异常处理程序
catch (InstallCanceledException ex)
{
}
在其他异常之前,但它似乎没有捕获这个特定的异常。
在取消长时间运行的延迟自定义操作期间如何处理 InstallCanceledException 的任何建议?
产品团队考虑使用其中一个应用程序,但普通用户运行这些应用程序,他们不一定知道 Web 服务 URL 或有权将报告发布到 Web 服务。我放入的安装程序通常用于运行 SQL 脚本,我正在向安装程序添加第二个功能以发布报告。它实际上工作得很好,现在放弃它。产品已经看到了我已经完成的工作并且他们喜欢它。MSI 进度条会在每个报告发布时更新它们的名称。MSI 提示输入 URI 和用户凭据,并且它已经知道 .RDL 文件所在的文件夹。当他们单击下一步按钮时,我在 URI 上运行验证,所以当我在执行序列中运行延迟操作时,它具有良好的 URI 和凭据。我' 甚至在发布过程中,我与 VPN 断开连接,但它因适当的错误而失败。从字面上看,只有当用户按下取消时,我似乎无法捕捉到那个,但它也不是这项工作走出去的阻碍。
隐藏“取消”按钮不是一个合适的选项,因为他们可以随时取消。
public static ActionResult PublishSSRSReports(Session session)
{
session.Log("Begin PublishSSRSReports");
bool bFolderExists = false;
string sCustomActionData;
sCustomActionData = session["CustomActionData"];
string INSTALLDIR = Convert.ToString(MsiGetCustomActionDataAttribute(sCustomActionData, "/InstallDir="));
string SSRSURL = Convert.ToString(MsiGetCustomActionDataAttribute(sCustomActionData, "/SsrsUrl="));
string USERCREDENTIALS = Convert.ToString(MsiGetCustomActionDataAttribute(sCustomActionData, "/Credentials="));
string USERNAME = Convert.ToString(MsiGetCustomActionDataAttribute(sCustomActionData, "/Username="));
string PASSWORD = Convert.ToString(MsiGetCustomActionDataAttribute(sCustomActionData, "/Password="));
string ReportsFolderPath = INSTALLDIR + "SSRSReports";
DirectoryInfo directory = new DirectoryInfo(ReportsFolderPath);
FileInfo[] reports = directory.GetFiles("*.rdl"); //Getting all RDL files
ResetProgressBar(session, reports.Length);
CatalogItem[] catalogitem = null;
using (ReportingService2010 rsc = new ReportingService2010())
{
rsc.Url = SSRSURL;
if (USERCREDENTIALS == "0")
{
rsc.Credentials = System.Net.CredentialCache.DefaultCredentials; //User credential for Reporting Service
//the current logged system user
}
if (USERCREDENTIALS == "1")
{
string[] userdomain = USERNAME.Split(Convert.ToChar("\\"));
rsc.Credentials = new System.Net.NetworkCredential(userdomain[1], PASSWORD, userdomain[0]);
}
catalogitem = rsc.ListChildren(@"/", false);
foreach (CatalogItem catalog in catalogitem)
{
if (catalog.Name == (DP))
{
EventLog.WriteEntry(AppDomain.CurrentDomain.FriendlyName, DP + " folder already exists");
bFolderExists = true;
}
}
if (bFolderExists == false)
{
rsc.CreateFolder(DP, @"/", null);
}
Warning[] Warnings = null;
foreach (FileInfo ReportFile in reports)
{
Byte[] definition = null;
Warning[] warnings = null;
try
{
FileStream stream = ReportFile.OpenRead();
definition = new Byte[stream.Length];
stream.Read(definition, 0, (int)stream.Length);
stream.Close();
}
catch (InstallCanceledException ex)
{
//session.Message(InstallMessage.Error, new Record { FormatString = ex.Message });
EventLog.WriteEntry(AppDomain.CurrentDomain.FriendlyName, ex.Message);
return ActionResult.UserExit;
}
catch (IOException ex)
{
session.Message(InstallMessage.Error, new Record { FormatString = ex.Message });
EventLog.WriteEntry(AppDomain.CurrentDomain.FriendlyName, ex.Message);
return ActionResult.Failure;
}
catch (Exception ex)
{
session.Message(InstallMessage.Error, new Record { FormatString = ex.Message });
EventLog.WriteEntry(AppDomain.CurrentDomain.FriendlyName, ex.Message);
return ActionResult.Failure;
}
try
{
CatalogItem report = rsc.CreateCatalogItem("Report", ReportFile.Name, @"/" + DP, true, definition, null, out Warnings);
DisplayActionData(session, ReportFile.Name);
IncrementProgressBar(session, 1);
if (report != null)
{
EventLog.WriteEntry(AppDomain.CurrentDomain.FriendlyName, ReportFile.Name + " Published Successfully ");
}
if (warnings != null)
{
foreach (Warning warning in warnings)
{
EventLog.WriteEntry(AppDomain.CurrentDomain.FriendlyName, string.Format("Report: {0} has warnings", warning.Message));
}
}
else
{
EventLog.WriteEntry(AppDomain.CurrentDomain.FriendlyName, string.Format("Report: {0} created successfully with no warnings", ReportFile.Name));
}
}
catch (InstallCanceledException ex)
{
//session.Message(InstallMessage.Error, new Record { FormatString = ex.Message });
EventLog.WriteEntry(AppDomain.CurrentDomain.FriendlyName, ex.Message);
return ActionResult.UserExit;
}
catch (SoapException ex)
{
session.Message(InstallMessage.Error, new Record { FormatString = ex.Message });
EventLog.WriteEntry(AppDomain.CurrentDomain.FriendlyName, ex.Detail.InnerXml.ToString());
return ActionResult.Failure;
}
catch (Exception ex)
{
session.Message(InstallMessage.Error, new Record { FormatString = ex.Message });
EventLog.WriteEntry(AppDomain.CurrentDomain.FriendlyName, ex.Message);
return ActionResult.Failure;
}
}
}
return ActionResult.Success;
我在课堂上也有这些
private const string SpaceForwardSlash = " /";
private const string DP = "Test";