С Новым годом! Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.86/21: Рейтинг темы: голосов - 21, средняя оценка - 4.86
 Аватар для Kloshar
55 / 42 / 27
Регистрация: 19.12.2013
Сообщений: 204

Получение свойств документа Word

19.12.2017, 11:31. Показов 4266. Ответов 7
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Проблема в следующем: нужно написать программу для просмотра и редактирования встроенных свойств документов Word.
Вот мой код для получения свойств. Он вылетает с ошибкой
Exception thrown: 'System.Reflection.TargetParameterCountE xception' in System.Dynamic.dll
Ошибка при вызове "Item".
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
void mainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            string path = AppDomain.CurrentDomain.BaseDirectory;
            pathes = Directory.GetFiles(path, "*.docx");
            wordPath = pathes[0];
            readProperty(wordPath);
        }
        void readProperty(string path)
        {
            //Создаём приложение Word и документ Word
            Microsoft.Office.Interop.Word.Application oWord;
            Microsoft.Office.Interop.Word.Document oDoc;
            object oMissing = System.Reflection.Missing.Value;
            oWord = new Microsoft.Office.Interop.Word.Application();
            oWord.Visible = false;
 
            try
            {
                //Добавляем документ Word в приложение
                oDoc = oWord.Documents.Add(path, ref oMissing, ref oMissing, ref oMissing);
                //Пытаемся записать в переменную коллекцию свойств
                dynamic d = ((DocumentProperties)oDoc.BuiltInDocumentProperties());
 
                //Console.WriteLine(d);
 
                oDoc.Close(SaveChanges: false);
            }
            catch (TargetParameterCountException targParEx)
            {
                Console.WriteLine(targParEx.Message);
            }
            catch (COMException ex)
            {
                Console.WriteLine(ex.Message);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
 
            oWord.Quit();
        }
Прошу помочь исправить.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
19.12.2017, 11:31
Ответы с готовыми решениями:

На оборотной стороне документа word в правой части документа, текст съезжает за границу документа
Добрый вечер. Есть код, который формирует документ из шаблона. И все вроде бы, но происходит что то непонятное. На оборотной стороне...

Получение тегов элемента из Html-документа
Здравствуйте. Много сообщений о работе с элементом Webbrowser, но ничего схожего не нашлось. На форме расположен элемент Webbrowser....

Создание документа Word
Нужно создать документ с текстом из проги, зашел в нагетс, утановил там word компонент и пишу так : ...

7
 Аватар для ViterAlex
8951 / 4863 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
19.12.2017, 12:43
Необязательные параметры можно не указывать:
C#
1
oDoc = oWord.Documents.Add(path);
Зачем назначать dynamic, если заранее известен тип?
C#
1
var d = ((DocumentProperties)oDoc.BuiltInDocumentProperties());
Ну и желательно отказаться от использования приложений офиса, а работать через OpenXml:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using System;
using DocumentFormat.OpenXml.Packaging;
 
namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var doc = WordprocessingDocument.Open(@"C:\Users\viter.alex\Documents\Инструкции для аутсорсеров.docx", false))
            {
                var propPart = doc.ExtendedFilePropertiesPart;
                foreach (var item in propPart.Properties)
                {
                    Console.WriteLine("{0} — {1}", item.LocalName,item.InnerText);
                }
            }
        }
    }
}
1
 Аватар для Kloshar
55 / 42 / 27
Регистрация: 19.12.2013
Сообщений: 204
19.12.2017, 13:34  [ТС]
Спасибо, ViterAlex!
Не знал про DocumentFormat.OpenXml.Packaging. Начал про эту сборку читать, но новичку разобраться очень сложно (нет примеров). Может подскажете как изменить значение у свойства?
0
 Аватар для ViterAlex
8951 / 4863 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
20.12.2017, 11:36
Поверхностный поиск привёл к такому коду:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
static void SetPropValue(string propName, string propValue, string path)
{
    using (var doc = WordprocessingDocument.Open(path, true))
    {
        var prop = doc.ExtendedFilePropertiesPart.Properties.ChildElements.FirstOrDefault(el => el.LocalName == propName);
        if (prop != null)
        {
            var pi = prop.GetType().GetProperty("InnerText");
            pi.SetValue(prop, propValue, BindingFlags.NonPublic | BindingFlags.Instance, null, null, null);
        }
        doc.Save();
    }
}
1
 Аватар для Kloshar
55 / 42 / 27
Регистрация: 19.12.2013
Сообщений: 204
20.12.2017, 12:04  [ТС]
Цитата Сообщение от ViterAlex Посмотреть сообщение
Поверхностный поиск привёл к такому коду:
Немного изменил код, чтобы в конце метод Save() к свойствам применился, но выдаёт ошибку.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
        static void SetPropValue(string propName, string propValue, string path)
        {
            using (var doc = WordprocessingDocument.Open(path, true))
            {
                var prop = doc.ExtendedFilePropertiesPart.Properties;
                var pr = doc.ExtendedFilePropertiesPart.Properties.ChildElements.FirstOrDefault(el => el.LocalName == propName);
                if (prop != null)
                {
                    var pi = prop.GetType().GetProperty("InnerText");
                    pi.SetValue(prop, propValue, BindingFlags.NonPublic | BindingFlags.Instance, null, null, null);
                }
                prop.Save();
            }
        }
Exception thrown: 'System.ArgumentException' in mscorlib.dll ("Не найден метод присваивания значения свойству.")

Я нашёл пример как добавить/изменить пользовательское свойство:
https://msdn.microsoft.com/ru-... 74468.aspx
Надеюсь, что мне удастся его переделать
0
 Аватар для ViterAlex
8951 / 4863 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
20.12.2017, 16:26
Kloshar, ты всё смешал в кучу. Значение нужно присваивать одному свойству, по его имени. Например:
C#
1
SetPropValue("Application", "New value for Application property", "file_path");
Ты же берёшь коллекцию Properties и меняешь всё её содержимое, которое может иметь примерно такой вид:
Кликните здесь для просмотра всего текста
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<ap:Properties xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes" xmlns:ap="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties">
  <ap:Template>Normal.dotm</ap:Template>
  <ap:TotalTime>1016</ap:TotalTime>
  <ap:Pages>1</ap:Pages>
  <ap:Words>7171</ap:Words>
  <ap:Characters>40879</ap:Characters>
  <ap:Application>test1</ap:Application>
  <ap:DocSecurity>0</ap:DocSecurity>
  <ap:Lines>340</ap:Lines>
  <ap:Paragraphs>95</ap:Paragraphs>
  <ap:ScaleCrop>false</ap:ScaleCrop>
  <ap:HeadingPairs>
    <vt:vector baseType="variant" size="4">
      <vt:variant>
        <vt:lpstr>Title</vt:lpstr>
      </vt:variant>
      <vt:variant>
        <vt:i4>1</vt:i4>
      </vt:variant>
      <vt:variant>
        <vt:lpstr>Название</vt:lpstr>
      </vt:variant>
      <vt:variant>
        <vt:i4>1</vt:i4>
      </vt:variant>
    </vt:vector>
  </ap:HeadingPairs>
  <ap:TitlesOfParts/>
  <ap:Company>USB</ap:Company>
  <ap:LinksUpToDate>false</ap:LinksUpToDate>
  <ap:CharactersWithSpaces>47955</ap:CharactersWithSpaces>
  <ap:SharedDoc>false</ap:SharedDoc>
  <ap:HyperlinksChanged>false</ap:HyperlinksChanged>
  <ap:AppVersion>16.0000</ap:AppVersion>
</ap:Properties>

Нужно же менять только дочерний элемент и то, выбирая его по имени
0
 Аватар для Kloshar
55 / 42 / 27
Регистрация: 19.12.2013
Сообщений: 204
20.12.2017, 17:00  [ТС]
ViterAlex, в приведённом тобой коде компилятор ругался на то, что doc.Save() нельзя применять. Из примера по ссылке выше я заметил, что они сохраняют всю коллекцию свойств, включая изменённые. Для этого я сохранил присвоил эти свойства переменной
C#
1
var prop = doc.ExtendedFilePropertiesPart.Properties;
но так как строку
C#
1
pi.SetValue(prop, propValue, BindingFlags.NonPublic | BindingFlags.Instance, null, null, null);
я понял с пятого на десятое, то и получил ошибку...
сейчас разбираюсь как это исправлять.
0
 Аватар для Kloshar
55 / 42 / 27
Регистрация: 19.12.2013
Сообщений: 204
22.01.2018, 10:34  [ТС]
Разобрался с чтением и записью свойств документа. Наткнулся в документации на Open XML SDK 2.5 Productivity Tool, который предлагает готовый код. Немного подправив, я получил функции для чтения свойства и записи. Отмечу, что свойства Title, Subject, Keywords, Category и Description изменяются одним методом, а свойства Company, Manager и прочие изменяются другим способом, так как находятся в другом разделе файла. Выкладываю для тех, кто сталкнётся с этим вопросом.
Чтение свойства:
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
string ViewPackage(string filePath, string propertyName)
        {
            string val = null;
            using (document = WordprocessingDocument.Open(filePath, true))
            {
                Queue<OpenXmlPartContainer> queue = new Queue<OpenXmlPartContainer>();
                queue.Enqueue(document);
                UriPartDictionary.Clear();
                while (queue.Count > 0)
                {
                    foreach (var part in queue.Dequeue().Parts)
                    {
                        if (!UriPartDictionary.Keys.Contains(part.OpenXmlPart.Uri.ToString()))
                        {
                            UriPartDictionary.Add(part.OpenXmlPart.Uri.ToString(), part.OpenXmlPart);
                            queue.Enqueue(part.OpenXmlPart);
                        }
                    }
                }
                var package = (((CoreFilePropertiesPart)UriPartDictionary["/docProps/core.xml"])).OpenXmlPackage;
                ap.Properties extProperties = (((ExtendedFilePropertiesPart)UriPartDictionary["/docProps/app.xml"])).Properties;
 
                try
                {
                    switch (propertyName)
                    {
                        case "Title":
                            val = package.PackageProperties.Title;
                            break;
                        case "Subject":
                            val = package.PackageProperties.Subject;
                            break;
                        case "Keywords":
                            val = package.PackageProperties.Keywords;
                            break;
                        case "Category":
                            val = package.PackageProperties.Category;
                            break;
                        case "Description":
                            val = package.PackageProperties.Description;
                            break;
                        case "Company":
                            if(extProperties.GetFirstChild<ap.Company>() != null)
                            {
                                val = extProperties.GetFirstChild<ap.Company>().Text;
                            }
                            else
                            {
                                val = "";
                            }                            
                            break;
                        case "Manager":
                            if (extProperties.GetFirstChild<ap.Manager>() != null)
                            {
                                val = extProperties.GetFirstChild<ap.Manager>().Text;
                            }
                            else
                            {
                                val = "";
                            }                            
                            break;
                        default:
                            val = null;
                            break;
                    }
                }
                catch(ObjectDisposedException ex)
                {
                    Console.WriteLine(ex.Message);
                }
                catch (NullReferenceException ex)
                {
                    Console.WriteLine(ex.Message);
                    Console.WriteLine("Ссылка на null во ViewPackage");
                }
            }
            return val;
        }

Запись свойства:
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
private void ChangePackage(string filePath, string propertyName, string text)
        {
            using (document = WordprocessingDocument.Open(filePath, true))
            {
                ChangeParts(propertyName, text);
            }
        }
        private void ChangeParts(string propertyName, string text)
        {
            BuildUriPartDictionary();
            //тут требуется ветвление в зависимости от того какое свойство мы меняем
            if(propertyName == propertyArray[0] || propertyName == propertyArray[1] || propertyName == propertyArray[2] || propertyName == propertyArray[3] || propertyName == propertyArray[4])
            {
                ChangeCoreFilePropertiesPart1(((CoreFilePropertiesPart)UriPartDictionary["/docProps/core.xml"]), propertyName, text);
            }
            else if (propertyName == propertyArray[5] || propertyName == propertyArray[6])
            {
                ChangeExtendedFilePropertiesPart1(((ExtendedFilePropertiesPart)UriPartDictionary["/docProps/app.xml"]), propertyName, text);
            }            
        }
        private void BuildUriPartDictionary()
        {
            Queue<OpenXmlPartContainer> queue = new Queue<OpenXmlPartContainer>();
            queue.Enqueue(document);
            UriPartDictionary.Clear();
            while (queue.Count > 0)
            {
                foreach (var part in queue.Dequeue().Parts)
                {
                    if (!UriPartDictionary.Keys.Contains(part.OpenXmlPart.Uri.ToString()))
                    {
                        UriPartDictionary.Add(part.OpenXmlPart.Uri.ToString(), part.OpenXmlPart);
                        queue.Enqueue(part.OpenXmlPart);
                    }
                }
            }
        }
        private void ChangeCoreFilePropertiesPart1(CoreFilePropertiesPart coreFilePropertiesPart1, string propertyName, string text)
        {
            var package = coreFilePropertiesPart1.OpenXmlPackage;
            switch (propertyName)
            {
                case "Title":
                    package.PackageProperties.Title = text;
                    break;
                case "Subject":
                    package.PackageProperties.Subject = text;
                    break;
                case "Keywords":
                    package.PackageProperties.Keywords = text;
                    break;
                case "Category":
                    package.PackageProperties.Category = text;
                    break;
                case "Description":
                    package.PackageProperties.Description = text;
                    break;
                default:
                    Console.WriteLine("Свойство не изменено. Какое свойство меняем?");
                    break;
            }            
        }
        private void ChangeExtendedFilePropertiesPart1(ExtendedFilePropertiesPart extendedFilePropertiesPart1, string propertyName, string text)
        {
            ap.Properties properties1 = extendedFilePropertiesPart1.Properties;
            ap.Company company1;
            ap.Manager manager1;
 
            company1 = properties1.GetFirstChild<ap.Company>();
            manager1 = properties1.GetFirstChild<ap.Manager>();
 
            switch (propertyName)
            {
                case "Company":                    
                    company1.Text = text;
                    break;
                case "Manager":
                    if(manager1 == null)
                    {
                        manager1 = new ap.Manager();
                        manager1.Text = text;
                        properties1.InsertBefore(manager1, company1);
                    }
                    else
                    {
                        manager1.Text = text;
                    }
                    break;
                default:
                    Console.WriteLine("Свойство не изменено. Какое свойство меняем?");
                    break;
            }
        }

Огромное спасибо ViterAlex за помощь (пинок в нужном направлении )!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
22.01.2018, 10:34
Помогаю со студенческими работами здесь

Откытие документа Word
Доброго всем времени суток. Прошу прощения, если повторяюсь. Но бьюсь уже не первый день. Проблема следующая. Есть простое...

Получение свойств формы
задача такая, сделал приложение, в нем есть &quot;Настройка&quot;, открывается в отдельном окне... нужно получить свойство прозрачности основной...

Получение свойств Ярлыка Windows
Захотелось написать утилитку для обработки файлов, созданных другой программой. В качестве исходных данных достаточно взять из ярлыка...

Получение свойств из Generic объекта
Всем привет. Есть generic класс: public class Wrapper&lt;T&gt; where T : Entity { public T Entity { get; set; } ...

Получение свойств файла (Свойства -> Подробно)
Каким образом можно вытащить свойства файла из вкладки &quot;Подробно&quot;? Пробовал искать по путиSystem.IO.File. , но ничего подобного не...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru