1. Обязательно представиться на русском языке кириллицей (заполнить поле "Имя").
  2. Фиктивные имена мы не приветствуем. Ивановых и Пупкиных здесь уже достаточно.
  3. Не писать свой вопрос в первую попавшуюся тему - вместо этого создать новую тему.
  4. За поиск, предложение и обсуждение пиратского ПО и средств взлома - бан без предупреждения.
  5. Рекламу и частные объявления "куплю/продам/есть халтура" мы не размещаем ни на каких условиях.
  6. Перед тем как что-то написать - читать здесь и здесь, а студентам - обязательно здесь.
  7. Не надо писать в ЛС администраторам свои технические вопросы. Администраторы форума отлично знают как работает форум, а не все-все контроллеры, о которых тут пишут.

Закрытие программы EPLAN

Сценарии / Модули API

Модератор: специалисты Eplan

Ответить

Автор темы
epic
здесь недавно
здесь недавно
Сообщения: 16
Зарегистрирован: 25 авг 2017, 23:17
Имя: Руслан
Благодарил (а): 7 раз

Закрытие программы EPLAN

Сообщение epic »

Здравствуйте!

Есть такой класс EplApplication, у которого есть метод Exit. С помощью него получаю результат такой, что закрываются открытые проекты. Закрытие проекта тоже устраивает, хотя цель закрыть сам Eplan.
Подскажите пожалуйста, на сколько это правильно так закрывать проекты? И безопасно ли это для БД проектов?
Аватара пользователя

Barmaley4
знаток Eplan
знаток Eplan
Сообщения: 48
Зарегистрирован: 30 окт 2018, 09:17
Имя: Павел
Страна: РФ
город/регион: Москва
Благодарил (а): 2 раза
Поблагодарили: 48 раз

Закрытие программы EPLAN

Сообщение Barmaley4 »

Вроде как EplApplication это класс для создания инстанса рантайма среды еплан (для выполнения операций с проектом без GUI еплана), и по идее метод Exit() закрывает рантайм в инстансе.
Если все проекты закрыты, то ничего страшного если применить немного варварства:

Код: Выделить всё

foreach (var process in Process.GetProcessesByName("EPLAN"))
{
    process.Kill();
}

wapdimon72ru
здесь недавно
здесь недавно
Сообщения: 19
Зарегистрирован: 11 апр 2019, 06:55
Имя: Марат
Благодарил (а): 1 раз
Поблагодарили: 1 раз

Закрыть EPLAN

Сообщение wapdimon72ru »

Данный метод конечно работает, но оставлю его использование на потом

Код: Выделить всё

foreach (var process in Process.GetProcessesByName("EPLAN"))
{
    process.Kill();
}
Так же можно закрыть его с помощью, тоже закроет, но этот вариант оставлю пока

Код: Выделить всё

Environment.Exit(0);
Меня интересует класс EplApplication , именно метод Exit
Вот такой вариант не закроет же сам еплан, потому что это новый экземляр класса,

Код: Выделить всё

EplApplication e = new EplApplication();
e.Exit();
а ссылку на текущее запущенное окно еплана не пойму где узнать

Вопрос: Как закрыть с помощью EplApplication или еще может какой метод есть сам Eplan, с примером в пару строк желательно бы...
Аватара пользователя

Barmaley4
знаток Eplan
знаток Eplan
Сообщения: 48
Зарегистрирован: 30 окт 2018, 09:17
Имя: Павел
Страна: РФ
город/регион: Москва
Благодарил (а): 2 раза
Поблагодарили: 48 раз

Закрыть EPLAN

Сообщение Barmaley4 »

Добрый день!

А почему необходимо использовать именно класс EplApplication? Это же не аналог ProjectManager'a для управления GUI, согласно описанию класс предназначен для:
EplApplication Class
This class allows you to use EPLAN functions in other processes.

То есть он для выполнения операций Eplan не из под родного GUI Eplan, а не для работы с запущеным приложением с ярлыка.

Для безопасного закрытия Eplan тогда уж проще использовать WinAPI и отправлять команду Alt+F4 в окно Eplan.

wapdimon72ru
здесь недавно
здесь недавно
Сообщения: 19
Зарегистрирован: 11 апр 2019, 06:55
Имя: Марат
Благодарил (а): 1 раз
Поблагодарили: 1 раз

Закрыть EPLAN

Сообщение wapdimon72ru »

EplApplication да это не то, немного почитал о нем.
Barmaley4 писал(а): 28 авг 2019, 09:10 Для безопасного закрытия Eplan тогда уж проще использовать WinAPI и отправлять команду Alt+F4 в окно Eplan.
Как это сделать ?
Или как закрыть с помощью ProjectManager'a , можете показать пару строк кода для примера?
Аватара пользователя

Barmaley4
знаток Eplan
знаток Eplan
Сообщения: 48
Зарегистрирован: 30 окт 2018, 09:17
Имя: Павел
Страна: РФ
город/регион: Москва
Благодарил (а): 2 раза
Поблагодарили: 48 раз

Закрыть EPLAN

Сообщение Barmaley4 »

Если не нужно переключать фокус окон, и главное окно Eplan по умолчанию в фокусе, то можно использовать пакет InputSimulator из NuGet менеджера, и выполнить отправку комбинации:

Код: Выделить всё

using WindowsInput;
using WindowsInput.Native;


            InputSimulator InpSim = new InputSimulator();
            InpSim.Keyboard.ModifiedKeyStroke(VirtualKeyCode.LMENU, VirtualKeyCode.F4);
Если же перефокусировка окна всё таки понадобится, то придётся подключить WinAPI:

Код: Выделить всё

	[DllImport("user32")]
        private static extern bool SetForegroundWindow(IntPtr hwnd);

        private void SetEplanWindow()
        {
            var proc = Process.GetProcessesByName("EPLAN").FirstOrDefault();
            if (proc != null && proc.MainWindowHandle != IntPtr.Zero)
                SetForegroundWindow(proc.MainWindowHandle);
        }

wapdimon72ru
здесь недавно
здесь недавно
Сообщения: 19
Зарегистрирован: 11 апр 2019, 06:55
Имя: Марат
Благодарил (а): 1 раз
Поблагодарили: 1 раз

Закрыть EPLAN

Сообщение wapdimon72ru »

Ага, спасибо за ответ. Но ваш способ не закроет еплан)) Конкретно в случае если из еплана, но нажатию кнопки была нарисована форма. Поможет решение если искать найти хэндл этого окна с помощью вин апи. Конкретный рабочий пример:

Код: Выделить всё

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

        static uint WM_CLOSE = 0x10;

        [DllImport("user32.dll", CharSet = CharSet.Unicode)]
        private static extern int GetWindowText(IntPtr hWnd, StringBuilder strText, int maxCount);

        [DllImport("user32.dll", CharSet = CharSet.Unicode)]
        private static extern int GetWindowTextLength(IntPtr hWnd);

        [DllImport("user32.dll")]
        private static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam);

        // Delegate to filter which windows to include 
        public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);

        /// <summary> Получить текст для окна, на которое указывает hWnd </summary>
        public static string GetWindowText(IntPtr hWnd)
        {
            int size = GetWindowTextLength(hWnd);
            if (size > 0)
            {
                var builder = new StringBuilder(size + 1);
                GetWindowText(hWnd, builder, builder.Capacity);
                return builder.ToString();
            }

            return String.Empty;
        }

        /// <summary> Найти все окна, соответствующие заданному фильтру </summary>
        /// <param name="filter"> A delegate that returns true for windows
        ///    that should be returned and false for windows that should
        ///    not be returned </param>
        public static IEnumerable<IntPtr> FindWindows(EnumWindowsProc filter)
        {
            IntPtr found = IntPtr.Zero;
            List<IntPtr> windows = new List<IntPtr>();

            EnumWindows(delegate (IntPtr wnd, IntPtr param)
            {
                if (filter(wnd, param))
                {
                    // добавляют только те окна, которые подходят под фильтр - названия формы
                    windows.Add(wnd);
                }

                // but return true here so that we iterate all windows
                return true;
            }, IntPtr.Zero);

            return windows;
        }

        /// <summary> Поиск всех окон, содержащих данный текст заголовка </summary>
        /// <param name="titleText"> Текст, который должен содержать заголовок окна. </param>
        public static IEnumerable<IntPtr> FindWindowsWithText(string titleText)
        {
            return FindWindows(delegate (IntPtr wnd, IntPtr param)
            {
                return GetWindowText(wnd).Contains(titleText);
            });
        }

        [StructLayout(LayoutKind.Sequential)]
        struct LASTINPUTINFO
        {
            public static readonly int SizeOf = Marshal.SizeOf(typeof(LASTINPUTINFO));

            [MarshalAs(UnmanagedType.U4)]
            public UInt32 cbSize;
            [MarshalAs(UnmanagedType.U4)]
            public UInt32 dwTime;
        }

        [DllImport("user32.dll")]
        static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);

        static int GetLastInputTime()
        {
            int idleTime = 0;
            LASTINPUTINFO lastInputInfo = new LASTINPUTINFO();
            lastInputInfo.cbSize = (UInt32)Marshal.SizeOf(lastInputInfo);
            lastInputInfo.dwTime = 0;

            int envTicks = Environment.TickCount;

            if (GetLastInputInfo(ref lastInputInfo))
            {
                int lastInputTick = (Int32)lastInputInfo.dwTime;

                idleTime = envTicks - lastInputTick;
            }

            return ((idleTime > 0) ? (idleTime / 1000) : 0);
        }



И тогда вызвав

Код: Выделить всё

                                        IEnumerable<IntPtr> windows = FindWindowsWithText("EPLAN");
                                        foreach (IntPtr hndl in windows)
                                        {
                                            SendMessage(hndl, WM_CLOSE, new IntPtr(0), new IntPtr(0));
                                        }
в любом нужном месте, eplan закроется как будто на крестик нажали. Это вот точно сработает, в данный момент на этом решении остановился.

Надеюсь кому нибудь поможет данное решение, ибо я нормально времени на это потратил...
Аватара пользователя

Barmaley4
знаток Eplan
знаток Eplan
Сообщения: 48
Зарегистрирован: 30 окт 2018, 09:17
Имя: Павел
Страна: РФ
город/регион: Москва
Благодарил (а): 2 раза
Поблагодарили: 48 раз

Закрыть EPLAN

Сообщение Barmaley4 »

:thankyou: Сохраню , хорошо работает)
С отрисованой формой я вызывал с паузой комбинацию Alt+F4 пока еплан не закроется
Ответить

Вернуться в «Eplan API»