У меня есть Отложенная библиотека пользовательских действий, написанная в DTF, которая публикует набор файлов .RDL в веб-службе отчетов SQL Server.Все работает хорошо, и я могу уловить большинство состояний ошибки в различных блоках Try Catch.
Единственная проблема, с которой я сталкиваюсь, - это если пользователь нажимает кнопку «Отмена» в установщике во время публикации.Он сразу же выдает сообщение, спрашивающее, хочу ли я отменить установку, но если я отвечаю Да , то выдает сообщение:
Исключение типа Microsoft.Deployment.WindowsInstaller.InstallCanceledException было сгенерировано
и просто кнопкой ОК.
Я пытался добавить специальный обработчик исключений
catch (InstallCanceledException ex)
{
}
до других исключений, нопохоже, что это одно конкретное исключение не отражает.
Любые предложения о том, как обрабатывать исключение InstallCanceledException при отмене долго выполняющегося отложенного настраиваемого действия?
Команда разработчиков рассмотрела возможность использования одного из приложений, но обычные пользователи запускают приложения и не хотятнеобязательно знать URL-адрес веб-службы или иметь разрешения на публикацию отчетов в веб-службе.Установщик, в который я это поместил, обычно используется для запуска сценариев SQL, и я добавляю в установщик вторую функцию для публикации отчетов.Это на самом деле работает слишком хорошо, чтобы отказаться от него сейчас.Продукт видел то, что я уже сделал, и им это нравится.Индикатор выполнения MSI обновляется с названием каждого отчета по мере его публикации.MSI запрашивает URI и учетные данные пользователя, и он уже знает, в какой папке находятся файлы .RDL. Я запускаю проверку URI, когда они нажимают следующую кнопку, поэтому к тому времени, когда я запускаю действие Deferred в последовательности выполнения, в которой он находитсяхороший 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";