Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.79/34: Рейтинг темы: голосов - 34, средняя оценка - 4.79
0 / 0 / 1
Регистрация: 26.09.2017
Сообщений: 12
.NET 2.x

Запустить внешнюю программу и дождаться ее завершения

27.09.2017, 08:20. Показов 6834. Ответов 19
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток.
Я новичек в программировании и тем более в C#. Очень нужна помощь.

Форма с кнопками, textbox, chekedlistbox. Основной код написан на .NET 2.0. Нужна совместимость с ХР (желательно без дополнительной установки новой .NET 4.x. ).
Суть проблеммы:
Нужно запустить внешнюю программу нажатием кнопки и дожнаться ее завершения, НО без "зависания" форми.
1) если делаю через waitforexit - виндовс начинает видеть как "зависшую" - либо пользователь, либо "настроенная" система может ликвидировать процесс
2) если делаю через таймер или sleep - съедает проц или память (или в одном варианте ведет себя как waitforexit уже не помню). Наверное не правильно код пишу не имея достаточно знаний.

Прошу вашей помощи. Никак не смог разобраться с async и await.

Добавлено через 10 часов 42 минуты
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
                Process ExternalProcess = new Process();
                ExternalProcess.StartInfo.FileName = shortcut.FullName;
                ExternalProcess.EnableRaisingEvents = true;
                ExternalProcess.Start();
                string ExtProcName = ExternalProcess.ProcessName;
                do
                {
                    DateTime delayTime = new DateTime();
                        do
                          
                        {
                            Application.DoEvents();
                            
                        }
                        while (delayTime.AddSeconds(3)>DateTime.Now);
                }
                while (Process.GetProcessesByName(ExtProcName).Length!=0);
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
27.09.2017, 08:20
Ответы с готовыми решениями:

Как дождаться завершения IHtmlElement::Click() C#
Появилась следующая проблемка: Загружаю в WebBrowser страничку, заполняю в ней поля логина и пароля, нажимаю логин с помощью метода...

Как правильно дождаться завершения потока?
Здравствуйте у меня возник вопрос как дождаться завершения потока метод Thread.join(); тормозит форму да и всу программу А мне нужно чтоб...

Как красиво дождаться завершения процесса? IntPrt имеется.
polling устраивать не хочется. на с++ это выглядело примитивно просто: WaitForSingleObject (hProcess, INFINITE); // делай что нужно...

19
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18234 / 14148 / 5366
Регистрация: 17.03.2014
Сообщений: 28,839
Записей в блоге: 1
27.09.2017, 13:25
RomeoRGRR, нужно делать запуск из отдельного потока и там вызывать WaitForExit. Или запускай из основного и подписывайся на событие Exited.

Цитата Сообщение от RomeoRGRR Посмотреть сообщение
C#
1
while (Process.GetProcessesByName(ExtProcName).Length!=0);
Это потенциально некорректное условие т.к. в системе могут быть другие процессы с таким же именем. Правильнее использовать свойство HasExited
C#
1
while (!ExternalProcess.HasExited);
0
0 / 0 / 1
Регистрация: 26.09.2017
Сообщений: 12
27.09.2017, 20:07  [ТС]
1) какраз тут и роблемма, не могу разобраться с потоками и делегатами
2) Конкретно в моем случае ето хорошо что моя программа будет ждать завершения другого такого же процесса (тоесть второй экземляр внешней программы).
3) спасибо, не додумался к такому простому коду, пробовал намного сложнее
но не могу понять, почему пока мы в етом цикле одно ядро полностью загружено.. почему так? есть способ снизить загрузку?
0
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18234 / 14148 / 5366
Регистрация: 17.03.2014
Сообщений: 28,839
Записей в блоге: 1
27.09.2017, 20:20
Цитата Сообщение от RomeoRGRR Посмотреть сообщение
но не могу понять, почему пока мы в етом цикле одно ядро полностью загружено.. почему так? есть способ снизить загрузку?
Потому что в коде есть цикл. Выполнение цикла нагружает процессор. Как иначе? Способы снизить нагрузку описаны выше.
0
0 / 0 / 1
Регистрация: 26.09.2017
Сообщений: 12
27.09.2017, 20:38  [ТС]
Подписался (не уверен, что правильно), но одно ядро все равно загружено. Что-то не так сделал? Или Вы имели ввиду что тут только другой поток поможет?
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
                Process ExternalProcess = new Process();
                ExternalProcess.StartInfo.FileName = shortcut.FullName;
                ExternalProcess.EnableRaisingEvents = true;
                ExternalProcess.Exited += new EventHandler(ExternalProcess_Exited);
                ExternalProcess.Start();
                string ExtProcName = ExternalProcess.ProcessName;
                while (!eventhandled)
                {
                    DateTime delayTime = new DateTime();
                        do
                          
                        {
                            Application.DoEvents();
                            
                        }
                        while (delayTime.AddSeconds(3)>DateTime.Now);
                }
 
         private void ExternalProcess_Exited(object sender, System.EventArgs e)
        {
            eventhandled = true;
            MessageBox.Show("ExtProcExited");
         }
0
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18234 / 14148 / 5366
Регистрация: 17.03.2014
Сообщений: 28,839
Записей в блоге: 1
27.09.2017, 21:11
RomeoRGRR, зачем здесь снова цикл? Делай нужные действия в обработчике события Exited.
0
0 / 0 / 1
Регистрация: 26.09.2017
Сообщений: 12
28.09.2017, 17:45  [ТС]
в 7 строке сделал та:
C#
1
2
// результат тот же, что и "while (!eventhandled)"
while (!ExternalProcess.HasExited)
Строки 10 и 16 удалил (оставил только Application.DoEvents() ). Все равно загружено ядро.
Попробовал с потоком, но не могу понять как ожидать завершения потока
C#
1
2
3
                ThreadStart ThrExtProcSt = new ThreadStart(() => ExternalProcess.Start());
                Thread ThrExtProc = new Thread(ThrExtProcSt);
                ThrExtProc.Start();
Добавлено через 8 минут
Цитата Сообщение от OwenGlendower Посмотреть сообщение
Делай нужные действия в обработчике события Exited.
или сюда надо прописать запуск внешнего процесса?

Добавлено через 19 часов 58 минут
Цитата Сообщение от OwenGlendower Посмотреть сообщение
Делай нужные действия в обработчике события Exited.
Можете объяснить? Не понимаю какие именно действия делать в обработчике?
0
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18234 / 14148 / 5366
Регистрация: 17.03.2014
Сообщений: 28,839
Записей в блоге: 1
29.09.2017, 15:42
Лучший ответ Сообщение было отмечено RomeoRGRR как решение

Решение

Цитата Сообщение от RomeoRGRR Посмотреть сообщение
Можете объяснить? Не понимаю какие именно действия делать в обработчике?
C#
1
2
3
4
5
6
7
8
9
10
11
12
Process ExternalProcess = new Process();
ExternalProcess.StartInfo.FileName = shortcut.FullName;
ExternalProcess.EnableRaisingEvents = true;
ExternalProcess.Exited += new EventHandler(ExternalProcess_Exited);
ExternalProcess.Start();
// Больше ничего здесь делать не нужно. Никаких циклов и никаких WaitForExit()
...
private void ExternalProcess_Exited(object sender, System.EventArgs e)
{
    // ЛЮБЫЕ НЕОБХОДИМЫЕ действия которые необходимо выполнить при завершении процесса
    MessageBox.Show("ExtProcExited");
}
2
0 / 0 / 1
Регистрация: 26.09.2017
Сообщений: 12
30.09.2017, 22:36  [ТС]
Перед запуском внешнего процесса я отключал сетевые адаптеры, чтоб внешняя программа не смогла попасть в интернет. После завершения внешнего процесса мне нужно обратно включить сетевые адаптеры. Правильно понимаю, код, который обратно включает адаптеры, нужно вставить на место 10 строки (Ваш последний ответ) и он сработает после завершения внешней программы?
0
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18234 / 14148 / 5366
Регистрация: 17.03.2014
Сообщений: 28,839
Записей в блоге: 1
30.09.2017, 22:47
Цитата Сообщение от RomeoRGRR Посмотреть сообщение
Правильно понимаю, код, который обратно включает адаптеры, нужно вставить на место 10 строки (Ваш последний ответ) и он сработает после завершения внешней программы?
Да.
0
0 / 0 / 1
Регистрация: 26.09.2017
Сообщений: 12
01.10.2017, 20:09  [ТС]
Большое спасибо!
Адаптеры включаються, но не могу обратно активировать элементы формы (перед запуском внешнего процеса я их деактивировал):
C#
1
2
3
4
5
6
ExitBut.Enabled = true;
            button1.Enabled = true;
            RunBut.Enabled = true;
            textBox1.Enabled = true;
            renewLAN.Enabled = true;
            checkedListBox1.Enabled = true;
выдает ошибку:
An unhandled exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll
Additional information: Cross-thread operation not valid: Control 'ExitBut' accessed from a thread other than the thread it was created on.
Так понимаю, что дочерний процес не может работать с родительской формой. Как правильно решить проблему? В голову приходит мысль о перехвате етого исключения и, в случае его присутствия, активировать элементы формы.

Добавлено через 34 минуты
Кажеться нашел почти такую же проблему, но не могу сделать для своего кода.
Создание и обработка события Process Exited
0
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18234 / 14148 / 5366
Регистрация: 17.03.2014
Сообщений: 28,839
Записей в блоге: 1
01.10.2017, 23:11
RomeoRGRR,
C#
1
2
3
4
5
6
7
8
this.Invoke(new Action(() => {
        ExitBut.Enabled = true;
        button1.Enabled = true;
        RunBut.Enabled = true;
        textBox1.Enabled = true;
        renewLAN.Enabled = true;
        checkedListBox1.Enabled = true;
}));
1
0 / 0 / 1
Регистрация: 26.09.2017
Сообщений: 12
02.10.2017, 15:13  [ТС]
вставлял код и в тело обработчика Exited, и в тело RunBut_Click, и в тело Form1 и все равно выдает ошибку
CS0305 Using the generic type 'Action<T>' requires 1 type arguments
Нашел, что Action доступно с .NET 3.5, нашел способ обойти проблему, но не уверен нет ли лучшено способа.
Вставил в конец тела обработчика Exited. Кажеться все хорошо.
C#
1
2
3
4
5
6
7
8
9
BeginInvoke(new MethodInvoker(delegate ()
            {
                ExitBut.Enabled = true;
                button1.Enabled = true;
                RunBut.Enabled = true;
                textBox1.Enabled = true;
                renewLAN.Enabled = true;
                checkedListBox1.Enabled = true;
            }));
0
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18234 / 14148 / 5366
Регистрация: 17.03.2014
Сообщений: 28,839
Записей в блоге: 1
02.10.2017, 15:15
RomeoRGRR, это нормальный способ
0
0 / 0 / 1
Регистрация: 26.09.2017
Сообщений: 12
02.10.2017, 16:17  [ТС]
Будет ли код, написан на .NET 2 работать на windows 8 - 10 или нужно делать проверку версии .net и под каждую писать соответстующий код? (помню у 8 и 8.1 иногда надо было включать .net 3.5 в системных компонентах)

И еще один вопрос, но наверное это другая тема уже.
Внешнюю программу удаеться запустить только через ярлык, который был создан при ее установке. Напрямую через .exe именно она запускаеться но что-то не так в ней срабатывает и она выключаеться. Создавал ярлык таким кодом
C#
1
2
3
4
5
WshShellClass shell = new WshShellClass();
IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(Path.GetDirectoryName(Application.ExecutablePath)
                               +"\\run_ExtProc_link.lnk");
shortcut.TargetPath = textBox1.Text; 
shortcut.Save();
Если скопировать созданный при установке ярлык и уже его редактировать (тот же код) - все хорошо.
Соответственно вопрос:
1) как запускать внешнюю програму с теми же атрибутами? (пока скопировал оригинальный ярлык и редактируюю в нем путь)
2) очень желательно не использовать IWshRuntimeLibrary (хочеться сделать одну .exe без копирования Interop.IWshRuntimeLibrary.dll.
Создание ярлыка допустимо (хочу без ярлыка), но в таком случае мне сначало нужно достать все параметры с оригинального ярлыка).
не смог разобраться: Создать ярлык к сторонней программе
0
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18234 / 14148 / 5366
Регистрация: 17.03.2014
Сообщений: 28,839
Записей в блоге: 1
02.10.2017, 16:52
Цитата Сообщение от RomeoRGRR Посмотреть сообщение
Будет ли код, написан на .NET 2 работать на windows 8 - 10
Скорее всего будет т.к. Microsoft старается поддерживать обратную совместимость.

Цитата Сообщение от RomeoRGRR Посмотреть сообщение
или нужно делать проверку версии .net и под каждую писать соответстующий код? (помню у 8 и 8.1 иногда надо было включать .net 3.5 в системных компонентах)
Лучше указать в файле конфигурации что приложение поддерживает разные версии CLR
XML
1
2
3
4
5
6
<configuration>  
   <startup>  
      <supportedRuntime version="v2.0.50727" />  
      <supportedRuntime version="v4.0" />  
   </startup>  
</configuration>
Цитата Сообщение от RomeoRGRR Посмотреть сообщение
как запускать внешнюю програму с теми же атрибутами?
Возможно приложение падает из-за неверного текущего каталога. Попробуй указать его с помощью свойства ProcessStartInfo.WorkingDirectory
C#
1
2
3
Process ExternalProcess = new Process();
ExternalProcess.StartInfo.FileName = shortcut.FullName;
ExternalProcess.StartInfo.WorkingDirectory = Path.GetDirectoryName(shortcut.FullName);
1
0 / 0 / 1
Регистрация: 26.09.2017
Сообщений: 12
04.10.2017, 22:29  [ТС]
Цитата Сообщение от RomeoRGRR Посмотреть сообщение
C#
1
2
3
4
5
WshShellClass shell = new WshShellClass();
IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(Path.GetDirectoryName(Application.ExecutablePath)
* * * * * * * * * * * * * * * *+"\\run_ExtProc_link.lnk");
shortcut.TargetPath = textBox1.Text; 
shortcut.Save();
Цитата Сообщение от OwenGlendower Посмотреть сообщение
Возможно приложение падает из-за неверного текущего каталога. Попробуй указать его с помощью свойства ProcessStartInfo.WorkingDirectory
в моём случае правильно было добавить такой код:
C#
1
2
int EndFolder = textBox1.Text.LastIndexOf("\\");
shortcut.WorkingDirectory = textBox1.Text.Substring(0, EndFolder);
Сейчас нормально создаеться новый ярлык и по нему запускаеться программа. Но не пойму почему напрямую exe-ник не запускаеться, а только через ярлык. Впечатление, что разработчик прописал функцию отслеживания запуска своей программы не на прямую через пользователя (такое возможно сделать?).
Если не трудно, можете еще подсказать в моей ситуации как создавать ярлык к внешней программе (или можно просто скопировать код отсюда: Создать ярлык к сторонней программе ? Но там есть лишний код для аргументов, как я понял)?

Добавлено через 17 минут
забыл добавить, что создать ярлык без использования возле моей программы библиотеки Interop.IWshRuntimeLibrary.dll
0
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18234 / 14148 / 5366
Регистрация: 17.03.2014
Сообщений: 28,839
Записей в блоге: 1
04.10.2017, 22:33
Цитата Сообщение от RomeoRGRR Посмотреть сообщение
Но не пойму почему напрямую exe-ник не запускаеться
Указать WorkingDirectory ты пробовал?
0
0 / 0 / 1
Регистрация: 26.09.2017
Сообщений: 12
04.10.2017, 23:13  [ТС]
Большое спасибо! Попробовал указать ProcessStartInfo.WorkingDirectory и запустить сам ехе-ник и запустилась!! ура!
C#
1
2
3
4
5
6
Process ExternalProcess = new Process();
ExternalProcess.StartInfo.FileName = textBox1.Text; //shortcut.FullName;
ExternalProcess.StartInfo.WorkingDirectory = Path.GetDirectoryName(textBox1.Text);  //shortcut.FullName);
ExternalProcess.EnableRaisingEvents = true;
ExternalProcess.Exited += new EventHandler(ExternalProcess_Exited);
ExternalProcess.Start();
Выходит, параметр WorkingDirectory нужно задавать в любом случае?

Как хорошо, что есть куда обратится за помощю и тебе помогут... Спасибо!
Если выбрать лучший ответ, тема будет считаться закрытой, верно? Не уверен, какой ответ выбрать лучшим (или не принципиально?)

Добавлено через 10 минут
а для общего развития, можете подсказать как создать ярлык в моём случае без использования Interop.IWshRuntimeLibrary.dll ?
0
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18234 / 14148 / 5366
Регистрация: 17.03.2014
Сообщений: 28,839
Записей в блоге: 1
05.10.2017, 00:01
Цитата Сообщение от RomeoRGRR Посмотреть сообщение
Выходит, параметр WorkingDirectory нужно задавать в любом случае?
Только для программ которые без этого не могут работать

Цитата Сообщение от RomeoRGRR Посмотреть сообщение
Как хорошо, что есть куда обратится за помощю и тебе помогут... Спасибо!
Пожалуйста

Цитата Сообщение от RomeoRGRR Посмотреть сообщение
Если выбрать лучший ответ, тема будет считаться закрытой, верно?
Да, но писать сообщения можно будет и дальше.

Цитата Сообщение от RomeoRGRR Посмотреть сообщение
Не уверен, какой ответ выбрать лучшим (или не принципиально?)
Тот который является ответом на вопрос темы. Представь себя на месте человека который в первый раз открыл эту тему. Он прочитал первое сообщение, затем сразу "лучший ответ" и понял что нужно делать. На мой взгляд в данном случае это сообщение #8.

Цитата Сообщение от RomeoRGRR Посмотреть сообщение
а для общего развития, можете подсказать как создать ярлык в моём случае без использования Interop.IWshRuntimeLibrary.dll ?
C#
1
2
3
IShellLinkW link = (IShellLinkW)new ShellLink();
link.SetPath(@"c:\windows\notepad.exe");
((IPersistFile)link).Save("notepad.lnk", true);
немного COM Interop кода необходимого для кода выше
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
[DllImport("shfolder.dll", CharSet = CharSet.Auto)]
internal static extern int SHGetFolderPath(IntPtr hwndOwner, int nFolder, IntPtr hToken, int dwFlags, StringBuilder lpszPath);
 
[Flags]
enum SLGP_FLAGS
{
    /// <summary>Retrieves the standard short (8.3 format) file name</summary>
    SLGP_SHORTPATH = 0x1,
    /// <summary>Retrieves the Universal Naming Convention (UNC) path name of the file</summary>
    SLGP_UNCPRIORITY = 0x2,
    /// <summary>Retrieves the raw path name. A raw path is something that might not exist and may include environment variables that need to be expanded</summary>
    SLGP_RAWPATH = 0x4
}
 
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct WIN32_FIND_DATAW
{
    public uint dwFileAttributes;
    public long ftCreationTime;
    public long ftLastAccessTime;
    public long ftLastWriteTime;
    public uint nFileSizeHigh;
    public uint nFileSizeLow;
    public uint dwReserved0;
    public uint dwReserved1;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
    public string cFileName;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
    public string cAlternateFileName;
}
 
[Flags]
enum SLR_FLAGS
{
    /// <summary>
    /// Do not display a dialog box if the link cannot be resolved. When SLR_NO_UI is set,
    /// the high-order word of fFlags can be set to a time-out value that specifies the
    /// maximum amount of time to be spent resolving the link. The function returns if the
    /// link cannot be resolved within the time-out duration. If the high-order word is set
    /// to zero, the time-out duration will be set to the default value of 3,000 milliseconds
    /// (3 seconds). To specify a value, set the high word of fFlags to the desired time-out
    /// duration, in milliseconds.
    /// </summary>
    SLR_NO_UI = 0x1,
    /// <summary>Obsolete and no longer used</summary>
    SLR_ANY_MATCH = 0x2,
    /// <summary>If the link object has changed, update its path and list of identifiers.
    /// If SLR_UPDATE is set, you do not need to call IPersistFile::IsDirty to determine
    /// whether or not the link object has changed.</summary>
    SLR_UPDATE = 0x4,
    /// <summary>Do not update the link information</summary>
    SLR_NOUPDATE = 0x8,
    /// <summary>Do not execute the search heuristics</summary>
    SLR_NOSEARCH = 0x10,
    /// <summary>Do not use distributed link tracking</summary>
    SLR_NOTRACK = 0x20,
    /// <summary>Disable distributed link tracking. By default, distributed link tracking tracks
    /// removable media across multiple devices based on the volume name. It also uses the
    /// Universal Naming Convention (UNC) path to track remote file systems whose drive letter
    /// has changed. Setting SLR_NOLINKINFO disables both types of tracking.</summary>
    SLR_NOLINKINFO = 0x40,
    /// <summary>Call the Microsoft Windows Installer</summary>
    SLR_INVOKE_MSI = 0x80
}
 
 
/// <summary>The IShellLink interface allows Shell links to be created, modified, and resolved</summary>
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("000214F9-0000-0000-C000-000000000046")]
interface IShellLinkW
{
    /// <summary>Retrieves the path and file name of a Shell link object</summary>
    void GetPath([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxPath, out WIN32_FIND_DATAW pfd, SLGP_FLAGS fFlags);
    /// <summary>Retrieves the list of item identifiers for a Shell link object</summary>
    void GetIDList(out IntPtr ppidl);
    /// <summary>Sets the pointer to an item identifier list (PIDL) for a Shell link object.</summary>
    void SetIDList(IntPtr pidl);
    /// <summary>Retrieves the description string for a Shell link object</summary>
    void GetDescription([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszName, int cchMaxName);
    /// <summary>Sets the description for a Shell link object. The description can be any application-defined string</summary>
    void SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName);
    /// <summary>Retrieves the name of the working directory for a Shell link object</summary>
    void GetWorkingDirectory([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, int cchMaxPath);
    /// <summary>Sets the name of the working directory for a Shell link object</summary>
    void SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir);
    /// <summary>Retrieves the command-line arguments associated with a Shell link object</summary>
    void GetArguments([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, int cchMaxPath);
    /// <summary>Sets the command-line arguments for a Shell link object</summary>
    void SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs);
    /// <summary>Retrieves the hot key for a Shell link object</summary>
    void GetHotkey(out short pwHotkey);
    /// <summary>Sets a hot key for a Shell link object</summary>
    void SetHotkey(short wHotkey);
    /// <summary>Retrieves the show command for a Shell link object</summary>
    void GetShowCmd(out int piShowCmd);
    /// <summary>Sets the show command for a Shell link object. The show command sets the initial show state of the window.</summary>
    void SetShowCmd(int iShowCmd);
    /// <summary>Retrieves the location (path and index) of the icon for a Shell link object</summary>
    void GetIconLocation([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath,
        int cchIconPath, out int piIcon);
    /// <summary>Sets the location (path and index) of the icon for a Shell link object</summary>
    void SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon);
    /// <summary>Sets the relative path to the Shell link object</summary>
    void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, int dwReserved);
    /// <summary>Attempts to find the target of a Shell link, even if it has been moved or renamed</summary>
    void Resolve(IntPtr hwnd, SLR_FLAGS fFlags);
    /// <summary>Sets the path and file name of a Shell link object</summary>
    void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile);
}
 
[ComImport, Guid("0000010c-0000-0000-c000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPersist
{
    [PreserveSig]
    void GetClassID(out Guid pClassID);
}
 
[ComImport, Guid("0000010b-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPersistFile : IPersist
{
    new void GetClassID(out Guid pClassID);
    [PreserveSig]
    int IsDirty();
 
    [PreserveSig]
    void Load([In, MarshalAs(UnmanagedType.LPWStr)]
    string pszFileName, uint dwMode);
    
    ///<summary>Saves a copy of the object to the specified file.</summary>
    ///<param name="pszFileName">The absolute path of the file to which the object should be saved. If pszFileName is NULL, the object should save its data to the current file, if there is one.</param>
    ///<param name="fRemember">Indicates whether the pszFileName parameter is to be used as the current working file. If TRUE, pszFileName becomes the current file and the object should clear its dirty flag after the save. If FALSE, this save operation is a Save A Copy As ... operation. In this case, the current file is unchanged and the object should not clear its dirty flag. If pszFileName is NULL, the implementation should ignore the fRemember flag.</param>
    [PreserveSig]
    void Save(
        [In, MarshalAs(UnmanagedType.LPWStr)] string pszFileName,
        [In, MarshalAs(UnmanagedType.Bool)] bool fRemember
    );
 
    [PreserveSig]
    void SaveCompleted([In, MarshalAs(UnmanagedType.LPWStr)] string pszFileName);
 
    [PreserveSig]
    void GetCurFile([In, MarshalAs(UnmanagedType.LPWStr)] string ppszFileName);
}
 
const uint STGM_READ = 0;
const int MAX_PATH = 260;
 
// CLSID_ShellLink from ShlGuid.h 
[ComImport]
[Guid("00021401-0000-0000-C000-000000000046")]
public class ShellLink
{
}
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
05.10.2017, 00:01
Помогаю со студенческими работами здесь

Запустить внешюю программу и дождаться ее завершения
Всем привет! Испольщую код: Private Declare Function WaitForSingleObject Lib &quot;kernel32&quot; (ByVal hHandle As Long, ByVal...

Правильно создать пул потоков, запустить эти потоки одновременно и дождаться их завершения
Добрый день! Подскажите пожалуйста, как правильно создать пул потоков, запустить эти потоки одновременно и дождаться завершения всех...

Из access запустить внешнюю программу
Уважаемые форумчане. Задача такая. База access содержит имена файлов разных типов с расширениями *.txt, *.wav, *.dat и другие. Хотелось бы...

Как запустить внешнюю программу?
Добрый день! Есть программа по шифрованию, ее можно запустить из командной строки. Например Программа: Shifr.exe Ключи -r - Шифруем...

Запустить стороннюю программу и дождаться окончания ее работы
Здравствуйте! Скажите как из формы запустить exe файл, форму скрыть и когда закроется этот exe файл форму вернуть обратно?


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru