/
spruttechnology
/
cam-api-examples
Обзор
Документация
Войти
/
spruttechnology
/
cam-api-examples
Код
Запросы
3
Задачи
Пакеты
0
Релизы
1
Аналитика
v19/develop
Project/ExtensionUtilityExportInformationNet/FilesInStreamApi/ProjectScreenshotExtractor.cs
147 строк
6 KB
renal
Добавление отображения информации в WEB - версии в расширении экспорта информации
20 июл 2026, 08:34
20 июл 2026, 08:34
c8b8e63
Код
Авторство
О чём код?
using System.Runtime.InteropServices; using System.Xml.Linq; using CAMAPI.FilesInStream; using CAMAPI.ResultStatus; namespace ExtensionUtilityExportInformationNet; /// <summary> /// Извлекает скриншоты из .stcp-проекта через ICAMAPIFilesInStreamStorage. /// </summary> public static class ProjectScreenshotExtractor { private const string ActiveSnapshotRefName = "ActiveSnapshot.ref"; private const string ThumbnailsFolderName = "Thumbnails"; private const string SnapshotEncoding = "UTF-8"; private const int RootParentIndex = 0; /// <summary> /// Возвращает все изображения папки Thumbnails; основное превью помечено IsProjectPreview. /// Бросает исключение, если dll не загрузилась или хранилище не открылось. /// </summary> /// <param name="projectFilePath">Путь к .stcp-файлу проекта.</param> /// <param name="filesInStreamDllPath">Путь к FilesInStream.dll; null — взять из папки текущего процесса.</param> public static List<ProjectScreenshot> Extract(string projectFilePath, string? filesInStreamDllPath = null) { var dllPath = filesInStreamDllPath ?? FilesInStreamLibLoader.GetDefaultDllPath(); using var loader = new FilesInStreamLibLoader(); if (!loader.LoadDll(dllPath)) throw new InvalidOperationException("Failed to load " + dllPath); var libCom = loader.LibCom ?? throw new InvalidOperationException("ICAMAPIFilesInStreamStorageLib is not available."); List<ProjectScreenshot>? screenshots = null; libCom.Invoke(lib => { var storage = lib.CreateNewStorage() ?? throw new InvalidOperationException("CreateNewStorage returned null."); try { var openStatus = storage.Open(projectFilePath, TFISStorageOpenMode.fsomRead); try { if (openStatus.Code == TResultStatusCode.rsError) throw new InvalidOperationException("Cannot open project storage: " + openStatus.Description); var previewStoragePath = ReadPreviewPathFromActiveSnapshot(storage); screenshots = CollectThumbnailFiles(loader, storage, previewStoragePath); } finally { storage.Close(false); } } finally { Marshal.ReleaseComObject(storage); } }); return screenshots ?? new List<ProjectScreenshot>(); } /// <summary> /// Возвращает путь превью проекта внутри хранилища; "" — если не найдено. /// </summary> private static string ReadPreviewPathFromActiveSnapshot(ICAMAPIFilesInStreamStorage storage) { var refIndex = storage.IndexOfFullName(ActiveSnapshotRefName, RootParentIndex); if (refIndex < 0) return string.Empty; if (storage.ReadAllTextOfFile(refIndex, SnapshotEncoding, out string snapshotName).Code == TResultStatusCode.rsError) return string.Empty; var snapshotIndex = storage.IndexOfFullName(snapshotName.Trim(), RootParentIndex); if (snapshotIndex < 0) return string.Empty; if (storage.ReadAllTextOfFile(snapshotIndex, SnapshotEncoding, out string snapshotXml).Code == TResultStatusCode.rsError) return string.Empty; return ParsePreviewPath(snapshotXml); } /// <summary> /// Возвращает путь превью из XML снапшота; "" — если узла нет. /// </summary> private static string ParsePreviewPath(string snapshotXml) { try { var document = XDocument.Parse(snapshotXml); var previewElement = document.Root? .Descendants(ThumbnailsFolderName) .Elements("ProjectPreviewFile") .FirstOrDefault(); if (previewElement is null) return string.Empty; var value = previewElement.Value.Trim(); if (value.Length == 0) value = previewElement.Attribute("Value")?.Value.Trim() ?? string.Empty; return NormalizeStoragePath(value); } catch (System.Xml.XmlException) { return string.Empty; } } private static string NormalizeStoragePath(string path) { var thumbnailsPos = path.IndexOf(ThumbnailsFolderName, StringComparison.OrdinalIgnoreCase); if (thumbnailsPos < 0) return string.Empty; return path.Substring(thumbnailsPos).Replace('\\', '/'); } /// <summary> /// Собирает все файлы папки Thumbnails. /// </summary> private static List<ProjectScreenshot> CollectThumbnailFiles( FilesInStreamLibLoader loader, ICAMAPIFilesInStreamStorage storage, string previewStoragePath) { var screenshots = new List<ProjectScreenshot>(); var folderIndex = storage.IndexOfFullName(ThumbnailsFolderName, RootParentIndex); if (folderIndex < 0) return screenshots; var itemIndex = storage.get_ItemChildIndex(folderIndex); while (itemIndex >= 0) { if (storage.get_ItemType(itemIndex) == TFISStorageItemType.fsitFile) { var storagePath = storage.get_ItemFullName(itemIndex).Replace('\\', '/'); var isPreview = storagePath.Equals(previewStoragePath, StringComparison.OrdinalIgnoreCase); screenshots.Add(new ProjectScreenshot( storage.get_ItemName(itemIndex), storagePath, isPreview, loader.ReadAllBytes(storage, itemIndex))); } itemIndex = storage.get_ItemSiblingIndex(itemIndex); } return screenshots; } }