ADN Club > AutoCAD .NET API

Не удаётся создать Subsection (раздел в реестре) для настроек PaletteSet

(1/6) > >>

Андрей Бушман:
Доброго времени суток.

- AutoCAD 2009 x86 SP3 Enu.

На событие PaletteSet.Save вешаю такой код:

--- Код - C# [Выбрать] ---void palette_set_Save(object sender, Win.PalettePersistEventArgs e) {        App.IConfigurationSection subsection_company = null;        App.IConfigurationSection subsection_product = null;         GetSubsections(e.ConfigurationSection, out subsection_company, out subsection_product);         if (palette_set != null) {                if (subsection_company == null)                        subsection_company = e.ConfigurationSection.CreateSubsection(company_name);                                Boolean is_read_only = subsection_company.IsReadOnly; // False                 if (subsection_product == null)                        // COMException here!                        // Message: Error HRESULT E_FAIL has been returned from a call to a COM component.                        subsection_product = subsection_company.CreateSubsection(product_name);                 subsection_company.WriteProperty("Copyright", "© Andrey Bushman, 2013");                subsection_company.WriteProperty("Site", "http://sites.google.com/site/bushmansnetlaboratory/");                 subsection_product.WriteProperty("Location X", palette_set.Location.X);                subsection_product.WriteProperty("Location Y", palette_set.Location.Y);                subsection_product.WriteProperty("Width", palette_set.Size.Width);                subsection_product.WriteProperty("Height", palette_set.Size.Height);        }} void GetSubsections(App.IConfigurationSection config_section,        out App.IConfigurationSection subsection_company,        out App.IConfigurationSection subsection_product) {         subsection_company = null;        subsection_product = null;         if (config_section == null)                return;         subsection_company = config_section.ContainsSubsection(company_name) ?                config_section.OpenSubsection(company_name) : null;         subsection_product = subsection_company != null && subsection_company.ContainsSubsection(product_name) ?                subsection_product = subsection_company.OpenSubsection(product_name) : null;}
Однако получаю исключение, обозначенное в комментариях. Я пробовал создавать вложенную секцию (Subsection) и в коде, подключенном к PaletteSet.Load - там та же история.

Почему не удаётся создать вложенную секцию?

Спасибо.

Андрей Бушман:
Хм... Написал простой пример, где посредством IConfigurationSection вношу изменения в реестр двумя способами (второй - это аналог коду из первого сообщения). Как это ни странно, но сейчас оба способа работают...

Возникли некоторые непонятные моменты:

1. Я не понял, почему в этот раз не возникает ошибка, обозначенная в аналогичном коде, приведённом выше.
2. Брэйкпоинт в palette_set_Save никогда не срабатывает, а срабатывает лишь в palette_set_Load.
3. Несмотря на п.2, палитра каким-то чудом запоминает свою позицию. Поиск по реестру ничего не даёт (искал по "ААА", "Location X", а так же по указанному GUID). Куда AutoCAD сохраняет эту информацию?

Наверное у меня уже глаз замылился... :(


--- Код - C# [Выбрать] ---// © Andrey Bushman, 2013using System;using Microsoft.Win32; using cad = Autodesk.AutoCAD.ApplicationServices.Application;using App = Autodesk.AutoCAD.ApplicationServices;using Db = Autodesk.AutoCAD.DatabaseServices;using Ed = Autodesk.AutoCAD.EditorInput;using Rtm = Autodesk.AutoCAD.Runtime;using Win = Autodesk.AutoCAD.Windows;using System.IO; [assembly: Rtm.CommandClass(typeof(Bushman.CAD.Problems.Commands))][assembly: Rtm.ExtensionApplication(typeof(Bushman.CAD.Problems.Commands))] namespace Bushman.CAD.Problems {         public class Commands : Rtm.IExtensionApplication {                 internal static Win.PaletteSet palette_set = null;                 [Rtm.CommandMethod("cmd_1", Rtm.CommandFlags.Modal)]                public void Command_1() {                        Ed.Editor ed = cad.DocumentManager.MdiActiveDocument.Editor;                        App.IConfigurationSection cp = cad.UserConfigurationManager.OpenCurrentProfile();                         const String name = "Bushman";                        const String name2 = "My Some Application";                        const String propName = "Property 1";                        App.IConfigurationSection section = cp.ContainsSubsection(name) ?                                cp.OpenSubsection(name) : cp.CreateSubsection(name);                         App.IConfigurationSection section2 = section.ContainsSubsection(name2) ?                                section.OpenSubsection(name2) : section.CreateSubsection(name2);                         section2.WriteProperty(propName, "Hello, World!");                        String cprofile = cad.GetSystemVariable("cprofile") as String;                        String path = Path.Combine(Db.HostApplicationServices.Current.RegistryProductRootKey, @"Profiles\" + cprofile);                        RegistryKey regKey = Registry.CurrentUser.OpenSubKey(path, false);                        RegistryKey regKey2 = regKey.OpenSubKey(name).OpenSubKey(name2);                        String value = regKey2.GetValue(propName, String.Empty) as String;                        ed.WriteMessage("Register: {0}\n", regKey2.Name);                        ed.WriteMessage("The register is successfully changed!\n");                }                 [Rtm.CommandMethod("cmd_2", Rtm.CommandFlags.Modal)]                public void Command_2() {                        Ed.Editor ed = cad.DocumentManager.MdiActiveDocument.Editor;                        if (palette_set == null) {                                palette_set = new Win.PaletteSet("My Palette", new Guid("{49DBC66F-21BE-4D9F-A5A9-BA750543042E}"));                                palette_set.Load += new Win.PalettePersistEventHandler(palette_set_Load);                                palette_set.Save += new Win.PalettePersistEventHandler(palette_set_Save);                        }                        palette_set.KeepFocus = true;                        palette_set.Visible = true;                }                 void palette_set_Load(object sender, Win.PalettePersistEventArgs e) {                        App.IConfigurationSection section = e.ConfigurationSection;                        App.IConfigurationSection subsection = null;                        App.IConfigurationSection subsection2 = null;                        const String name = "AAA";                        const String name2 = "BBB";                        if (!section.IsReadOnly) {                                subsection = section.ContainsSubsection(name) ?                                section.OpenSubsection(name) : section.CreateSubsection(name);                                 if (!subsection.IsReadOnly) {                                        subsection2 = subsection.ContainsSubsection(name2) ?                                        subsection.OpenSubsection(name2) : subsection.CreateSubsection(name2);                                }                                Int32 x = (Int32)subsection2.ReadProperty("Location X", 300);                                Int32 y = (Int32)subsection2.ReadProperty("Location Y", 200);                        }                }                 void palette_set_Save(object sender, Win.PalettePersistEventArgs e) {                        App.IConfigurationSection section = e.ConfigurationSection;                        App.IConfigurationSection subsection = null;                        App.IConfigurationSection subsection2 = null;                        const String name = "AAA";                        const String name2 = "BBB";                        if (!section.IsReadOnly) {                                subsection = section.ContainsSubsection(name) ?                                section.OpenSubsection(name) : section.CreateSubsection(name);                                 if (!subsection.IsReadOnly) {                                        subsection2 = subsection.ContainsSubsection(name2) ?                                        subsection.OpenSubsection(name2) : subsection.CreateSubsection(name2);                                }                                subsection2.WriteProperty("Location X", palette_set.Location.X);                                subsection2.WriteProperty("Location Y", palette_set.Location.Y);                        }                }                  public void Initialize() {                        Ed.Editor ed = cad.DocumentManager.MdiActiveDocument.Editor;                        ed.WriteMessage("The 'Hello World' is loaded... \n");                }                 public void Terminate() {                        // throw new NotImplementedException();                }        }}

Александр Ривилис:

--- Цитата: Андрей Бушман от 04-12-2013, 16:08:36 ---3. Несмотря на п.2, палитра каким-то чудом запоминает свою позицию. Поиск по реестру ничего не даёт (искал по "ААА", "Location X", а так же по указанному GUID). Куда AutoCAD сохраняет эту информацию?
--- Конец цитаты ---
Может по имени палитры поищешь? Мне всегда казалось, что сохраняется эта информация сюда:
HKEY_CURRENT_USER\Software\Autodesk\AutoCAD\RXX.X\ACAD-YYYY:LLL\Profiles\<<Имя профиля>>\Dialogs

Андрей Бушман:

--- Цитата: Александр Ривилис от 05-12-2013, 03:13:33 ---Может по имени палитры поищешь? Мне всегда казалось, что сохраняется эта информация сюда:
HKEY_CURRENT_USER\Software\Autodesk\AutoCAD\RXX.X\ACAD-YYYY:LLL\Profiles\<<Имя профиля>>\Dialogs
--- Конец цитаты ---
Нет, вы ошибаетесь. Как выяснилось, информация записывается в файл %AppData%\Autodesk\AutoCAD 2014\R19.1\enu\Support\Profiles\Unnamed Profile\Profile.aws Вместо Unnamed Profile подставляете имя своего профиля.
Записанная в указанном файле информация выглядит так:

--- Код - XML [Выбрать] ---<Tool CLSID="{49DBC66F-21BE-4D9F-A5A9-BA750543042E}">  <CAdUiDockControlBar Orientation="-1" AllowDocking="1">    <FloatInfo Left="342" Top="310" Width="300" Height="300"/>    <DockInfo Left="0" Top="792" Width="300" Height="798" MRUDockID="59420"/>  </CAdUiDockControlBar>  <CAdUiPaletteSet/>  <AAA>    <BBB/>  </AAA></Tool>
Обратите внимание на то, что элементы AAA и BBB созданы за счёт выполнения метода palette_set_Load. Однако я регистрировал и метод palette_set_Save, который должен был при завершении работы AutoCAD дописывать туда два дополнительных элемента, но этого почему-то не происходит (зарегистрированный код не вызывается автокадом)...

Поскольку информация, связанная с палитрами записывается в XML фай, то сразу становится понятна причина сбоя... Я ведь изначально ожидал, что информация будет записываться в реестр и вложенному подразделу пытался задать имя "Sheet Set Viewer". В реестре такие имена допустимы, но не в XML - там в имени элемента не должно содержаться пробелов. Т.о. заменив имя подраздела на "Sheet_Set_Viewer", я тем самым устранил проблему. В XML это выглядит так:


--- Код - XML [Выбрать] ---<Tool CLSID="{E06974C1-B748-4D8A-B1CC-CB9AADA26B79}">  <CAdUiDockControlBar Orientation="-1" AllowDocking="1">    <FloatInfo Left="150" Top="200" Width="300" Height="300"/>    <DockInfo Left="0" Top="396" Width="300" Height="798" MRUDockID="59420"/>  </CAdUiDockControlBar>  <CAdUiPaletteSet/>  <Bushman>    <Sheet_Set_Viewer/>  </Bushman></Tool>
Отсюда вывод: если не хотите, чтобы в один прекрасный момент ваш код, использующий IConfigurationSection перестал работать, когда компания Autodesk вдруг решит часть настроек перенести из реестра в XML, то имена своим пользовательским разделам, подразделам и параметрам следует на всякий случай назначать без пробелов. :)

Т.о. вопрос, обозначенный в первом сообщении темы закрыт. Однако меня по прежнему интересует, почему выполняется мой код, зарегистрированный на событие Load и не выполняется код, зарегистрированный на событие Save?

Показываю простой исходный код, демонстрирующий проблему:


--- Код - C# [Выбрать] ---// © Andrey Bushman, 2013using System;using Microsoft.Win32; using cad = Autodesk.AutoCAD.ApplicationServices.Application;using App = Autodesk.AutoCAD.ApplicationServices;using Db = Autodesk.AutoCAD.DatabaseServices;using Ed = Autodesk.AutoCAD.EditorInput;using Rtm = Autodesk.AutoCAD.Runtime;using Win = Autodesk.AutoCAD.Windows;using System.IO; [assembly: Rtm.CommandClass(typeof(Bushman.CAD.Problems.Commands))][assembly: Rtm.ExtensionApplication(typeof(Bushman.CAD.Problems.Commands))] namespace Bushman.CAD.Problems {         public class Commands : Rtm.IExtensionApplication {                 internal static Win.PaletteSet palette_set = null;                 [Rtm.CommandMethod("cmd_1", Rtm.CommandFlags.Modal)]                public void Command_1() {                        Ed.Editor ed = cad.DocumentManager.MdiActiveDocument.Editor;                        App.IConfigurationSection cp = cad.UserConfigurationManager.OpenCurrentProfile();                         const String name = "Bushman";                        // This names can to contain the spaces                        const String name2 = "My Some Application";                        const String propName = "Property 1";                        // This settings will created in the registry (HKCU)                        App.IConfigurationSection section = cp.ContainsSubsection(name) ?                                cp.OpenSubsection(name) : cp.CreateSubsection(name);                         App.IConfigurationSection section2 = section.ContainsSubsection(name2) ?                                section.OpenSubsection(name2) : section.CreateSubsection(name2);                         section2.WriteProperty(propName, "Hello, World!");                        String cprofile = cad.GetSystemVariable("cprofile") as String;                        String path = Db.HostApplicationServices.Current.UserRegistryProductRootKey                                + @"\Profiles\" + cprofile;                         using (RegistryKey regKey = Registry.CurrentUser.OpenSubKey(path, false)) {                                using (RegistryKey regKey2 = regKey.OpenSubKey(name).OpenSubKey(name2)) {                                        String value = regKey2.GetValue(propName, String.Empty) as String;                                        ed.WriteMessage("Register: {0}\n", regKey2.Name);                                        ed.WriteMessage("The register is successfully changed!\n");                                }                        }                }                 [Rtm.CommandMethod("cmd_2", Rtm.CommandFlags.Modal)]                public void Command_2() {                        Ed.Editor ed = cad.DocumentManager.MdiActiveDocument.Editor;                        if (palette_set == null) {                                // This settings will be saved into the                                 // %AppData%\Autodesk\AutoCAD 2014\R19.1\enu\Support\Profiles\Unnamed Profile\Profile.aws                                // if the current profile is <<Unnamed Profile>>.                                palette_set = new Win.PaletteSet("My Palette",                                        new Guid("{49DBC66F-21BE-4D9F-A5A9-BA750543042E}"));                                palette_set.Load += new Win.PalettePersistEventHandler(palette_set_Load);                                palette_set.Save += new Win.PalettePersistEventHandler(palette_set_Save);                        }                         palette_set.KeepFocus = true;                        palette_set.Visible = true;                }                 // This names can't to contain the spaces!                const String name = "AAA";                const String name2 = "BBB";                const String val_1_name = "Value_1";                const String val_2_name = "Value_2";                 void palette_set_Load(object sender, Win.PalettePersistEventArgs e) {                        App.IConfigurationSection section = e.ConfigurationSection;                        App.IConfigurationSection subsection = null;                        App.IConfigurationSection subsection2 = null;                         if (!section.IsReadOnly) {                                subsection = section.ContainsSubsection(name) ?                                section.OpenSubsection(name) : section.CreateSubsection(name);                                 if (!subsection.IsReadOnly) {                                        subsection2 = subsection.ContainsSubsection(name2) ?                                        subsection.OpenSubsection(name2) : subsection.CreateSubsection(name2);                                }                                Int32 val_1 = (Int32)subsection2.ReadProperty(val_1_name, 100);                                Int32 val_2 = (Int32)subsection2.ReadProperty(val_2_name, 200);                        }                }                 void palette_set_Save(object sender, Win.PalettePersistEventArgs e) {                        App.IConfigurationSection section = e.ConfigurationSection;                        App.IConfigurationSection subsection = null;                        App.IConfigurationSection subsection2 = null;                        if (!section.IsReadOnly) {                                subsection = section.ContainsSubsection(name) ?                                section.OpenSubsection(name) : section.CreateSubsection(name);                                 if (!subsection.IsReadOnly) {                                        subsection2 = subsection.ContainsSubsection(name2) ?                                        subsection.OpenSubsection(name2) : subsection.CreateSubsection(name2);                                }                                subsection2.WriteProperty(val_1_name, 700);                                subsection2.WriteProperty(val_2_name, 800);                        }                }                  public void Initialize() {                        Ed.Editor ed = cad.DocumentManager.MdiActiveDocument.Editor;                        ed.WriteMessage("The 'Hello World' is loaded... \n");                }                 public void Terminate() {                        // throw new NotImplementedException();                }        }}
На всякий случай прикрепляю исходники, настроенные на AutoCAD 2014 x64.

Спасибо.

Андрей Бушман:
Я попробовал выполнить сохранение настроек, подписавшись на событие Application.BeginQuit, но это не помогло. В комментариях я показал точку сбоя и своё предположение о его причине...

--- Код - C# [Выбрать] ---// © Andrey Bushman, 2013using System;using Microsoft.Win32; using cad = Autodesk.AutoCAD.ApplicationServices.Application;using App = Autodesk.AutoCAD.ApplicationServices;using Db = Autodesk.AutoCAD.DatabaseServices;using Ed = Autodesk.AutoCAD.EditorInput;using Rtm = Autodesk.AutoCAD.Runtime;using Win = Autodesk.AutoCAD.Windows;using System.IO; [assembly: Rtm.CommandClass(typeof(Bushman.CAD.Problems.Commands))][assembly: Rtm.ExtensionApplication(typeof(Bushman.CAD.Problems.Commands))] namespace Bushman.CAD.Problems {         public class Commands : Rtm.IExtensionApplication {                 internal static Win.PaletteSet palette_set = null;                 [Rtm.CommandMethod("cmd_1", Rtm.CommandFlags.Modal)]                public void Command_1() {                        Ed.Editor ed = cad.DocumentManager.MdiActiveDocument.Editor;                        App.IConfigurationSection cp = cad.UserConfigurationManager.OpenCurrentProfile();                         const String name = "Bushman";                        // This names can to contain the spaces                        const String name2 = "My Some Application";                        const String propName = "Property 1";                        // This settings will created in the registry (HKCU)                        App.IConfigurationSection section = cp.ContainsSubsection(name) ?                                cp.OpenSubsection(name) : cp.CreateSubsection(name);                         App.IConfigurationSection section2 = section.ContainsSubsection(name2) ?                                section.OpenSubsection(name2) : section.CreateSubsection(name2);                         section2.WriteProperty(propName, "Hello, World!");                        String cprofile = cad.GetSystemVariable("cprofile") as String;                        String path = Db.HostApplicationServices.Current.UserRegistryProductRootKey                                + @"\Profiles\" + cprofile;                         using (RegistryKey regKey = Registry.CurrentUser.OpenSubKey(path, false)) {                                using (RegistryKey regKey2 = regKey.OpenSubKey(name).OpenSubKey(name2)) {                                        String value = regKey2.GetValue(propName, String.Empty) as String;                                        ed.WriteMessage("Register: {0}\n", regKey2.Name);                                        ed.WriteMessage("The register is successfully changed!\n");                                }                        }                }                 [Rtm.CommandMethod("cmd_2", Rtm.CommandFlags.Modal)]                public void Command_2() {                        Ed.Editor ed = cad.DocumentManager.MdiActiveDocument.Editor;                        if (palette_set == null) {                                // This settings will be saved into the                                 // %AppData%\Autodesk\AutoCAD 2014\R19.1\enu\Support\Profiles\Unnamed Profile\Profile.aws                                // if the current profile is <<Unnamed Profile>>.                                palette_set = new Win.PaletteSet("My Palette",                                        new Guid("{49DBC66F-21BE-4D9F-A5A9-BA750543042E}"));                                palette_set.Load += new Win.PalettePersistEventHandler(palette_set_Load);                                cad.BeginQuit += new EventHandler(cad_BeginQuit);                        }                         palette_set.KeepFocus = true;                        palette_set.Visible = true;                }                 static App.IConfigurationSection _palette_set = null;                 void cad_BeginQuit(object sender, EventArgs e) {                        palette_set_Save(null, _palette_set);                }                 // This names can't to contain the spaces!                const String name = "AAA";                const String name2 = "BBB";                const String val_1_name = "Value_1";                const String val_2_name = "Value_2";                 void palette_set_Load(object sender, Win.PalettePersistEventArgs e) {                        App.IConfigurationSection section = _palette_set = e.ConfigurationSection;                        App.IConfigurationSection subsection = null;                        App.IConfigurationSection subsection2 = null;                         if (!section.IsReadOnly) {                                subsection = section.ContainsSubsection(name) ?                                section.OpenSubsection(name) : section.CreateSubsection(name);                                 if (!subsection.IsReadOnly) {                                        subsection2 = subsection.ContainsSubsection(name2) ?                                        subsection.OpenSubsection(name2) : subsection.CreateSubsection(name2);                                }                                Int32 val_1 = (Int32)subsection2.ReadProperty(val_1_name, 100);                                Int32 val_2 = (Int32)subsection2.ReadProperty(val_2_name, 200);                        }                }                 void palette_set_Save(object sender, App.IConfigurationSection section) {                        App.IConfigurationSection subsection = null;                        App.IConfigurationSection subsection2 = null;                        if (section != null && !section.IsReadOnly) {                                // TODO: Problem is here.                                // Here execution of code interrupts... Maybe IConfigurationSection is disposed already...                                subsection = section.ContainsSubsection(name) ?                                section.OpenSubsection(name) : section.CreateSubsection(name);                                 if (!subsection.IsReadOnly) {                                        subsection2 = subsection.ContainsSubsection(name2) ?                                        subsection.OpenSubsection(name2) : subsection.CreateSubsection(name2);                                }                                subsection2.WriteProperty(val_1_name, 700);                                subsection2.WriteProperty(val_2_name, 800);                        }                }                  public void Initialize() {                        Ed.Editor ed = cad.DocumentManager.MdiActiveDocument.Editor;                        ed.WriteMessage("The 'Hello World' is loaded... \n");                }                 public void Terminate() {                        // throw new NotImplementedException();                }        }}

Навигация

[0] Главная страница сообщений

[#] Следующая страница

Перейти к полной версии