Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [VC#] Запуск программы - Process, Process newProcess = new Process(); 
:(
    Опции темы
MuForum
Дата 30.1.2008, 00:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

Репутация: нет
Всего: 4



Доброе время суток!

# Задача: Необходимо запустить программу, считать её handle и затем свернуть.
- Программы находятся в списке. (То есть программ много)

Код

        private List<FileInfo> FileList = new List<FileInfo>();
        private class FileInfo
        {
            public String Path = String.Empty;b // Полный путь к файлу.
            public String ShortPath = String.Empty; // Путь к папке, в которой находиться файл.
            public String FileName = String.Empty; // Имя файла.
            public String Parameters = String.Empty; // Параметры, с которыми нужно запустить программу.
            public String StartInterval = "0"; // Интервал, с которым нужно запускать программу.
            public IntPtr Handle = IntPtr.Zero; // handle окна программы.
            public Byte Exists = 0x00; // Статус программы.
        }
......
......
......
        private void ProcessStart()
        {
            if (FileList.Count > 0)
            {
                Process newProcess = new Process();
                for (int i = 0; i < (FileList.Count - 1); i++)
                {
                    if (File.Exists(FileList[i].Path))
                    {
                        newProcess.StartInfo.FileName = FileList[i].FileName; // Имя программы. (Пример: 'Goblin.exe')
                        newProcess.StartInfo.Arguments = FileList[i].Parameters; // Параметры, с которыми нужно запустить программу.
                        newProcess.StartInfo.WorkingDirectory = FileList[i].ShortPath; // Путь к папке, в которой лежит файл.
                        newProcess.StartInfo.WindowStyle = ProcessWindowStyle.Normal; // В каком режиме запустить программу.
                        Thread.Sleep(Convert.ToInt16(FileList[i].StartInterval)); // Задержка перед запуском программы.
                        if (newProcess.Start()) // Проверка на успешный запуск программы.
                        {
                            while (FileList[i].Handle == IntPtr.Zero) // Вот тут проблема!
                            {
                                FileList[i].Handle = newProcess.MainWindowHandle;
                                Thread.Sleep(100);
                            }
                            dgv_main.Invoke((MethodInvoker)delegate
                            {
                                dgv_main.Rows[i].Cells[2].Value = "Succes";
                                dgv_main.CurrentCell = dgv_main.Rows[i].Cells[1];
                            });
                            SW.ShowWindow(FileList[i].Handle, SW.SW_HIDE);
                        }
                        else
                        {
                            dgv_main.Invoke((MethodInvoker)delegate
                            {
                                dgv_main.Rows[i].Cells[2].Value = "Failure";
                                dgv_main.CurrentCell = dgv_main.Rows[i].Cells[1];
                            });
                        }
                    }
                    else
                    {
                        dgv_main.Invoke((MethodInvoker)delegate
                        {
                        dgv_main.Rows[i].Cells[2].Value = "Not found";
                        dgv_main.CurrentCell = dgv_main.Rows[i].Cells[1];
                        });
                        WLog("The following file is not found. Please check Path:\n" + FileList[i].Path);
                    }
                }
                b_status.Invoke((MethodInvoker)delegate { b_status.Enabled = true; });
                cb_log.Invoke((MethodInvoker)delegate { cb_log.Enabled = true; });
            }
            else WLog("The file list is empty!");
            ThrProcess.Abort();
        }



# Подключаемая функция с WinApi:
Код

        private class SW
        {
            [DllImport("user32.dll")]
            public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

            public const int SW_HIDE = 0;
            public const int SW_SHOWNORMAL = 1;
            public const int SW_NORMAL = 1;
            public const int SW_SHOWMINIMIZED = 2;
            public const int SW_SHOWMAXIMIZED = 3;
            public const int SW_MAXIMIZE = 3;
            public const int SW_SHOWNOACTIVATE = 4;
            public const int SW_SHOW = 5;
            public const int SW_MINIMIZE = 6;
            public const int SW_SHOWMINNOACTIVE = 7;
            public const int SW_SHOWNA = 8;
            public const int SW_RESTORE = 9;
            public const int SW_SHOWDEFAULT = 10;
            public const int SW_FORCEMINIMIZE = 11;
            public const int SW_MAX = 11;
        }



Проблема заключается в следующем: Почему-то 'newProcess.MainWindowHandle' возращает ноль. (Если сделать задержку на некоторое время, то тогда возращает handle). Но тут проблема, так как программа пишется для запуска программ игрового Сервера, то время на запуск каждой программы разный + На это ещё влияет сами параметры компьютера...


То есть вопрос заключается в следующем: Как мне запустить программу, дождаться пока она вернёт мне handle, чтобы я затем мог свернуть программу?

Это сообщение отредактировал(а) MuForum - 30.1.2008, 00:23


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
mr.DUDA
Дата 30.1.2008, 10:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



Можно запускать программы в одном потоке, а ждать появления MainWindowHandle и сворачивать окно в другом потоке. Кстати, если нужно просто свернуть прогу после запуска, можно прописать newProcess.StartInfo.WindowStyle = ProcessWindowStyle.Minimized, тогда не нужно потом вызывать ShowWindow(SW_HIDE).


--------------------
user posted image
PM MAIL WWW   Вверх
MuForum
Дата 30.1.2008, 10:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

Репутация: нет
Всего: 4



Цитата(mr.DUDA)

Можно запускать программы в одном потоке...

- Я так и делаю, запускаю поток и в нём запускаю всё.

Код

private Thread ThrProcess = null;
......
......
......
        private void b_start_Click(object sender, EventArgs e)
        {
            if (b_start.Text == "Start")
            {
                if (ThrProcess == null)
                {
                    ......
                    ThrProcess = new Thread(ProcessStart);
                    ThrProcess.IsBackground = true;
                    ThrProcess.Start();
                    b_start.Text = "Stop";
                    ......
                }
            }
            else
            {
                ......
                if (ThrProcess != null)
                {
                    ThrProcess.Abort();
                    ThrProcess = null;
                }
                ......
            }
            ......
        }



Цитата(mr.DUDA)

Кстати, если нужно просто свернуть прогу после запуска, можно прописать newProcess.StartInfo.WindowStyle = ProcessWindowStyle.Minimized, тогда не нужно потом вызывать ShowWindow(SW_HIDE).

- Делал, но мне данный способ не подходит, так как мне нужно скрывать окно с экрана и с 'Панели задач'.
- А если делать 'newProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden', то тогда затем если делаешь 'ShowWindow(SW_SHOW)', то окно в 'Панели задач' не появляется.

Это сообщение отредактировал(а) MuForum - 30.1.2008, 10:36


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
farad
Дата 30.1.2008, 11:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 199
Регистрация: 1.11.2007

Репутация: -1
Всего: 6



Код

Process newProcess = new Process();
            newProcess.StartInfo.FileName = "notepad.exe";
            if (newProcess.Start())
            {
                newProcess.WaitForInputIdle();
                if(newProcess.MainWindowHandle == IntPtr.Zero)
                {
                    Debug.WriteLine("только не это!");
                }
            }

PM MAIL   Вверх
MuForum
Дата 30.1.2008, 14:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

Репутация: нет
Всего: 4



Цитата(farad @ 30.1.2008,  11:40)
Код

Process newProcess = new Process();
            newProcess.StartInfo.FileName = "notepad.exe";
            if (newProcess.Start())
            {
                newProcess.WaitForInputIdle();
                if(newProcess.MainWindowHandle == IntPtr.Zero)
                {
                    Debug.WriteLine("только не это!");
                }
            }

Спасибо, от части помогло.
- Если программа грузится медленно, то всё срабатывает на ура, а если быстро, то выдаёт сообщение о 'newProcess.MainWindowHandle == 0'


P.S. -> Может есть ещё какой-то способ прослеживать запущено ли приложение и чтобы возвращало значение 'handle не равное 0'?


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
farad
Дата 30.1.2008, 14:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 199
Регистрация: 1.11.2007

Репутация: -1
Всего: 6



попробуй таймаут задать в WaitForInputIdle... вообще странно, на блокноте-то работает, сложно представить что что-то быстрее его грузится...
Цитата(MuForum @  30.1.2008,  14:24 Найти цитируемый пост)
Может есть ещё какой-то способ прослеживать запущено ли приложение и чтобы возвращало значение 'handle не равное 0'
 FindWindowEx из API

Добавлено через 6 минут и 9 секунд
да, еще: WaitForInputIdle будет ждать инициализацию только оконных приложений. Если прога консольная, или досовская какая-нибудь, то она сразу вернет управление
PM MAIL   Вверх
vadj
Дата 1.1.2018, 16:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 1
Регистрация: 1.1.2018

Репутация: нет
Всего: нет



парни как добавить программу другую уже в соброный .exe
что бы он не рядом лежал в папке
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.1627 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.