private static IXDocument3D[] TryCommitAndGetDependencies(IXDocument doc, bool allowReadOnly) { try { doc.Commit(); return(doc.Dependencies.ToArray()); } catch (DocumentWriteAccessDeniedException) { if (allowReadOnly) { try { var docState = doc.State; if (!docState.HasFlag(DocumentState_e.ReadOnly)) { doc.State = docState | DocumentState_e.ReadOnly; try { doc.Commit(); } catch { if (!doc.IsCommitted) { //restoring state if failed to open doc.State = docState; } } return(doc.Dependencies.ToArray()); } } catch { } } } catch { } return(null); }
private bool AttemptProcessFile(ref IXApplication app, ref Process appPrc, JobItemFile file, BatchJob opts, CancellationToken cancellationToken = default) { file.Status = JobItemStatus_e.InProgress; int curAttempt = 1; var macrosStack = new List <JobItemMacro>(file.Macros); TimeSpan?timeout = null; if (opts.Timeout > 0) { timeout = TimeSpan.FromSeconds(opts.Timeout); } while (curAttempt <= MAX_ATTEMPTS) { if (app == null || !IsAppAlive(app, appPrc) && !cancellationToken.IsCancellationRequested) { TryShutDownApplication(appPrc); var vers = m_AppProvider.ParseVersion(opts.VersionId); app = AttemptStartApplication(vers, opts.StartupOptions, cancellationToken, timeout); appPrc = app.Process; } IXDocument doc = null; CancellationTokenSource cancellationTokenSrc = null; CancellationToken timeoutCancellationToken = default; try { if (timeout.HasValue) { cancellationTokenSrc = new CancellationTokenSource(timeout.Value); timeoutCancellationToken = cancellationTokenSrc.Token; var thisAppPrc = appPrc; timeoutCancellationToken.Register(() => { TryShutDownApplication(thisAppPrc); }); } if (cancellationToken.IsCancellationRequested) { throw new JobCancelledException(); } var fileProcessStartTime = DateTime.Now; m_UserLogger.WriteLine($"Started processing file {file.FilePath}"); doc = app.Documents.FirstOrDefault(d => string.Equals(d.Path, file.FilePath)); var forbidSaving = false; if (doc == null) { doc = app.Documents.PreCreate <IXDocument>(); doc.Path = file.FilePath; var state = DocumentState_e.Default; if (opts.OpenFileOptions.HasFlag(OpenFileOptions_e.Silent)) { state |= DocumentState_e.Silent; } if (opts.OpenFileOptions.HasFlag(OpenFileOptions_e.ReadOnly)) { state |= DocumentState_e.ReadOnly; } if (opts.OpenFileOptions.HasFlag(OpenFileOptions_e.Rapid)) { state |= DocumentState_e.Rapid; } if (opts.OpenFileOptions.HasFlag(OpenFileOptions_e.Invisible)) { state |= DocumentState_e.Hidden; } if (opts.OpenFileOptions.HasFlag(OpenFileOptions_e.ForbidUpgrade)) { if (app.Version.Compare(doc.Version) == VersionEquality_e.Newer) { forbidSaving = true; if (!state.HasFlag(DocumentState_e.ReadOnly)) { m_UserLogger.WriteLine($"Setting the readonly flag to {file.FilePath} to prevent upgrade of the file"); state |= DocumentState_e.ReadOnly; } } } doc.State = state; doc.Commit(cancellationToken); } if (!opts.OpenFileOptions.HasFlag(OpenFileOptions_e.Invisible)) { app.Documents.Active = doc; } AttempRunMacros(app, doc, macrosStack, opts.Actions, forbidSaving, cancellationToken); if (file.Macros.All(m => m.Status == JobItemStatus_e.Succeeded)) { file.Status = JobItemStatus_e.Succeeded; } else { file.Status = file.Macros.Any(m => m.Status == JobItemStatus_e.Succeeded) ? JobItemStatus_e.Warning : JobItemStatus_e.Failed; } m_UserLogger.WriteLine($"Processing file '{file.FilePath}' completed. Execution time {DateTime.Now.Subtract(fileProcessStartTime).ToString(@"hh\:mm\:ss")}"); return(file.Status != JobItemStatus_e.Failed); } catch (Exception ex) { var errDesc = ""; if (cancellationToken.IsCancellationRequested) { throw new JobCancelledException(); } if (timeoutCancellationToken.IsCancellationRequested) { errDesc = "Timeout processing document"; } else { if (ex is OpenDocumentFailedException) { errDesc = $"Failed to open document {file.FilePath}: {(ex as OpenDocumentFailedException).Message}"; } else { errDesc = "Failed to process document"; } } m_UserLogger.WriteLine($"{errDesc}. Attempt: {curAttempt}"); curAttempt++; } finally { cancellationTokenSrc?.Dispose(); TryCloseDocument(doc); } } file.Status = JobItemStatus_e.Failed; m_UserLogger.WriteLine($"Processing file '{file.FilePath}' failed"); return(false); }