Как закрыть excel application

Razinalex

12 / 12 / 3

Регистрация: 17.08.2010

Сообщений: 84

1

25.05.2011, 13:11. Показов 50077. Ответов 15

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

Добрый день.
Не могу решить следующую проблему:
Создаю экземпляр Excel, открываю файл, закрываю его. В результате в task manager все равно остается висеть процесс Excel.exe. Он пропадает только после полного закрытия приложения.
Вот код:

C#
1
2
3
4
5
 Microsoft.Office.Interop.Excel.Application excelapp = new Microsoft.Office.Interop.Excel.Application();
            excelapp.Workbooks.Open(System.Windows.Forms.Application.StartupPath + "\Шаблон1.xlsx", Type.Missing, false, Type.Missing, Type.Missing, Type.Missing, true, Type.Missing,
                 Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing)
 
excelapp.Quit();

Подскажите пожалуйста как закрыть так, чтобы из процессов также убралось?



0



Redfex

614 / 538 / 114

Регистрация: 24.03.2011

Сообщений: 576

25.05.2011, 13:33

2

Попробуйте сделать так:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
            Microsoft.Office.Interop.Excel.Application excelapp = new Microsoft.Office.Interop.Excel.Application();
            Microsoft.Office.Interop.Excel.Workbook workbook = excelapp.Workbooks.Open(System.Windows.Forms.Application.StartupPath + "\Шаблон1.xlsx", Type.Missing, false, Type.Missing, Type.Missing, Type.Missing, true, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
 
            if (workbook != null)
            {
                workbook.Close(false, Type.Missing, Type.Missing);
                excelapp.Workbooks.Close();
                System.Runtime.InteropServices.Marshal.ReleaseComObject(workbook);
            }
 
            excelapp.Quit();
            GC.Collect();
            System.Runtime.InteropServices.Marshal.FinalReleaseComObject(excelapp);



0



мастер топоров

915 / 740 / 101

Регистрация: 16.08.2009

Сообщений: 1,476

25.05.2011, 13:36

3



0



TreaNT

4 / 4 / 3

Регистрация: 28.04.2011

Сообщений: 43

25.05.2011, 15:03

4

C#
1
2
3
4
5
6
7
8
9
10
11
using System.Diagnostics;
 
 public void CloseProcess()
        {
            Process[] List;
            List = Process.GetProcessesByName("EXCEL");
            foreach (Process proc in List)
            {
                proc.Kill();
            }
        }



0



PhoenixJack

19.04.2012, 16:34

5

Хоть уже и не актуально но нашёл решение проблемы. Сборщик мусора не срабатывает, если есть ссылки на приложение Excel.
Вот в примере

C#
1
2
3
4
5
6
7
8
9
Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
            Microsoft.Office.Interop.Excel.Workbook xlDoc = xlApp.Workbooks.Add();
            Microsoft.Office.Interop.Excel.Worksheet xlSheet = xlDoc.Worksheets[1];
            Microsoft.Office.Interop.Excel.Range xlR = xlSheet.Range["A1"];
            xlR.Value = "5";
            xlApp.Visible = true;
            xlDoc.Close(false);
            xlApp.Quit();
            GC.Collect();

В процессах останется висеть EXCEL.EXE, пока не закроется программа. А вот если добавить

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
            Microsoft.Office.Interop.Excel.Workbook xlDoc = xlApp.Workbooks.Add();
            Microsoft.Office.Interop.Excel.Worksheet xlSheet = xlDoc.Worksheets[1];
            Microsoft.Office.Interop.Excel.Range xlR = xlSheet.Range["A1"];
            xlR.Value = "5";
            xlApp.Visible = true;
            xlDoc.Close(false);
            xlApp.Quit();
            xlApp = null;
            xlDoc = null;
            xlSheet = null;
            xlR = null;
            GC.Collect();

То есть обнулить все ссылки, то процесс удалится сборщиком мусора.
Можно через Process.Kill, как в примере выше, но тогда вы убьёте все открытые окна, которые могут висеть. Вот если кто найдёт как убить именно одно открытое нами окно — буду премного благодарен.

vaque

3 / 3 / 1

Регистрация: 22.04.2011

Сообщений: 31

05.07.2012, 12:06

6

Цитата
Сообщение от TreaNT
Посмотреть сообщение

C#
1
2
3
4
5
6
7
8
9
10
using System.Diagnostics;
public void CloseProcess()
* * * * {
* * * * * * Process[] List;
* * * * * * List = Process.GetProcessesByName("EXCEL");
* * * * * * foreach (Process proc in List)
* * * * * * {
* * * * * * * * proc.Kill();
* * * * * * }
* * * * }

Очень клево! действительно освобождает ресурс
только до этого надо сделать

C#
1
2
3
4
5
6
               oWB.Close(false);//aplication
                oXL.Quit();//workbook
                oXL = null;
                oWB = null;
                sheets = null;//Sheet
)



1



es_

217 / 216 / 114

Регистрация: 14.01.2013

Сообщений: 459

06.06.2013, 10:43

7

Много времени прошло после создания поста, но всё же я наткнулся на него поисковиком, значит тема актуальна и я могу кому-нибудь помочь.

Вот если кто найдёт как убить именно одно открытое нами окно — буду премного благодарен.

В своей проге я сначала проверяю открыто ли Exce приложение — если да, то прицепляюсь к нему, если нет то создаю новое:

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
using System.Runtime.InteropServices; // Здесь живёт Marshal - нужен для присоединения
...
private Excel.Application excelapp; // Создаём ссылку на Excel приложение
private Excel.Workbook excelappworkbook; // Создаём ссылку на рабочую книгу
...
int flagexcelapp = 0;
try
{// Присоединение к открытому приложению Excel (если оно открыто)
 excelapp = (Excel.Application)Marshal.GetActiveObject("Excel.Application"); 
 flagexcelapp = 1; // устанавливаем флаг в 1, будем знать что присоединились
}
catch
{
 excelapp = new Excel.Application();// Если нет, то создаём новое приложение
}
... 
// далее закрытие
// если не присоединялись, а создавали своё приложение то тупо убиваем процессы
if (flagexcelapp == 0)
{
 excelappworkbooks.Close();
 excelapp.Quit();
 Process[] ps2 = System.Diagnostics.Process.GetProcessesByName("EXCEL");
 foreach (Process p2 in ps2)
 {
  p2.Kill();
 }
}
else // Если же мы присоединялись, то закрываем рабочую книгу, по поводу параметров
{    // "false" - можете почитать на MSDN - мне разбираться было лень :)
 excelappworkbook.Close(false,false,false);
}



2



breakboyandre

16.07.2013, 12:37

8

C#
1
2
3
4
5
6
7
8
9
Excel.Application excelApp = new Excel.Application();
System.Diagnostics.Process excelProc = System.Diagnostics.Process.GetProcessesByName("EXCEL").Last();
excelWorkBook = excelApp.Workbooks.Open(...);
...
...
...
excelWorkBook.Close();
excelApp.Application.Quit();
excelProc.Kill();

У меня прекрасно работает, закрывая открытый моей программой Excel и не трогая остальные Excel’и.

Эксперт Java

4088 / 3822 / 745

Регистрация: 18.05.2010

Сообщений: 9,331

Записей в блоге: 11

16.07.2013, 16:02

9

Цитата
Сообщение от breakboyandre
Посмотреть сообщение

меня прекрасно работает, закрывая открытый моей программой Excel и не трогая остальные Excel’и.

Ужасное решение.
Не будет работать, если между вызовами 1-й и 2-й строчки создастся еще один процесс Excel.
Не будет работать, если другая программа решит использовать ваш процесс.



0



breakboyandre

16.07.2013, 18:27

10

Цитата
Сообщение от turbanoff
Посмотреть сообщение

Не будет работать, если между вызовами 1-й и 2-й строчки создастся еще один процесс Excel.

Не будет. А вы не создавайте процесс между 1-й и 2-й строчкой.

Цитата
Сообщение от turbanoff
Посмотреть сообщение

Не будет работать, если другая программа решит использовать ваш процесс.

Из ваших слов складывается чувство, что программы сами решают что им делать. Я считаю, что вероятность подключения к созданному мною процессу сторонней (не моей) программой, довольно мала.
У меня опыта в программировании не очень много. Поэтому нашел оптимальное решение для себя. Недочеты указаны вами. Кто захочет — использует.

4 / 4 / 0

Регистрация: 30.05.2013

Сообщений: 61

09.05.2014, 15:34

11

Извиняюсь за поднятие старой темы, но все же у меня аналогичный вопрос.
В ручную убивать процесс я не буду, это вообще ужас. Просто нет слов. Например, что, если у пользователя запущен свой Excel?
Использовать GC — отлично, но почему то мне не помогает, процесс все еще висит.



0



0 / 0 / 0

Регистрация: 17.08.2015

Сообщений: 15

17.08.2015, 23:24

12

Та же проблема. В одной программе, где надо было просто закрыть сформированный файл екселя все решило убийство процесса. Но сейчас стоит задача, сформировать файл екселя и оставить его для редактирования. Здесь появились трудности, процесс созданный программой даже после закрытия окна екселя через крестик не выгружается из процессов…. Помогите сделать так, что бы созданный программой процесс екселя корректно закрывался.



0



es_

217 / 216 / 114

Регистрация: 14.01.2013

Сообщений: 459

24.08.2015, 08:56

13

Так как вопросы ещё есть, хочу попробовать подвести итог, моей эпопеи с не убиваемым(на самом деле убиваемым) Excel приложением.
Вообще если есть возможность (Если нужно, например, забить ячейки Excel какой-нибудь инфой) то я бы советовал использовать SQL запросы.
Если же нужно редактировать стиль ячеек (границы, свет и т.д. и т.п.) то без библиотеки
Microsoft.Office.Interop.Excel не обойтись
Ну и так об Microsoft.Office.Interop.Excel,
Вот мой кодик. Всё отлажено, Excel процесс не висит.
Всё хорошо работает, если приложение уже было открыто, если приложение не было открыто и если в процессе работы нашей программы пользователь открыл другу книгу.
Такс такс, что ещё… Библиотеку Microsoft.Office.Interop.Excel я использовал версии 12. Специально использовал относительно старенькую версию. В других версиях работа с книгами, листами, ячейками может отличаться. Точно помню, что в 14 версии по-другому выбираются ячейки.
Раньше PhoenixJack писал Сборщик мусора не срабатывает, если есть ссылки на приложение Excel.Вот в примере.
Я давно это пробовал, но почему-то у меня всё равно процесс висел в памяти. Может не все ссылки удалял, а может, чем чёрт не шутит, зависит и от версии библиотеки Microsoft.Office.Interop.Excel
Ну в общем вот:

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
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Excel = Microsoft.Office.Interop.Excel;   
using System.Runtime.InteropServices;
 
namespace KILLEXCEL
{
    public partial class Form1 : Form
    {
        public Excel.Application excelApp;          
        public Excel.Range excelCells;
        public Excel.Sheets excelSheets;
        public Excel.Worksheet excelWorkSheet;
        public Excel.Workbooks excelAppWorkbooks;
        public Excel.Workbook excelAppWorkbook;
        public Form1()
        {
            InitializeComponent();
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            try
            {// Присоединение к открытому приложению Excel (если оно открыто), имхо так тру, ибо 2 excel процесса в памяти не кошерно
                excelApp = (Excel.Application)Marshal.GetActiveObject("Excel.Application");
            }
            catch
            {
                excelApp = new Excel.Application(); // Если нет открытого, то создаём новое приложение
            }
            excelApp.Visible = true;                // Делаем приложение видимым
            excelApp.SheetsInNewWorkbook = 3;       // В новой созданной книге будет 3 листа
            excelApp.Workbooks.Add(Type.Missing);   // Добавляем книгу
            excelAppWorkbooks = excelApp.Workbooks; // Получаем список открытых книг
            excelAppWorkbook = excelAppWorkbooks[excelAppWorkbooks.Count];  // Устанавливаем ссылку на нашу книгу и да именно Count, а не Count-1, так как отсчёт идёт с 1!!!!!!
            excelSheets = excelAppWorkbook.Worksheets; // Получаем список листов в нашей книге
            excelWorkSheet = (Excel.Worksheet)excelSheets.get_Item(1);  // Берем первый лист
            excelCells = excelWorkSheet.get_Range("A1", "A1");          // Берём ячейку А1
            excelCells.Value2 = "HiCyberForum";                         // Пишем в неё что-нибудь
            // Далее опишу закрытие, для того что-бы не висел процесс в памяти, нужно обнулить ВСЕ! ссылки, которые связаны с библиотекой Microsoft.Office.Interop.Excel
            excelCells = null;
            excelWorkSheet = null;
            excelSheets = null;
            try
            {// Тут уж простите за заплатку, выпадало исключение, если файл с таким именем существует и пользователь откажется перезаписывать его
                // Не знаю почему, времени нет разбираться.
                excelAppWorkbook.Save();
            }
            catch { }
            excelAppWorkbook.Close(false, false, false);// Закрываем книгу
            excelAppWorkbooks = excelApp.Workbooks;     // Далее проверяем есть ли ещё другие открытые книги, ведь во время работы нашей программы пользователь мог открыть другую книгу
            if (excelAppWorkbooks.Count == 0)
                excelApp.Quit();            // Если нет то закрываем приложение
            excelAppWorkbook = null;        // Продолжаем обнулять ссылки
            excelAppWorkbooks = null;
            excelApp = null;
            GC.Collect();       // Зовём МистераПропера на помощь
            // С MSDN: Сборке мусора подвергаются все объекты, вне зависимости от времени их нахождения в памяти. Однако объекты, на которые имеются ссылки в управляемом коде, не освобождаются. Используйте этот метод, чтобы принудительно предпринять попытку высвободить максимальный объем доступной памяти.
        }
    }
}

Миниатюры

Как закрыть процесс Excel?
 



6



tdm_nlomov

42 / 2 / 0

Регистрация: 09.12.2015

Сообщений: 2

01.03.2016, 09:08

14

Если тема ещё актуальна, могу предложить своё решение.
В моей программе открывается файл (шаблон) Excel, в него записываются необходимы данные, файл сохраняется на диск под определённым именем (NewFileName). Если ничего дополнительно не делать, то процесс Excel так и будет висеть до закрытия самой программы.
В данном случае создаётся новый Excel.Application, что позволяет получить в памяти отдельный процесс Excel, в независимости есть ли открытые книги Excel:

C#
1
using Excel = Microsoft.Office.Interop.Excel;

В самом начале после объявления класса делаем импорт из DLL

C#
1
2
        [System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint = "GetWindowThreadProcessId")]
        public static extern int GetWindowThreadProcessId([System.Runtime.InteropServices.InAttribute()] System.IntPtr hWnd, out int lpdwProcessId);

Сама процедура записи в файл (лишнее убрал)

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
            Excel.Application application = new Excel.Application
            {
                DisplayAlerts = false
            };
            Excel.Workbook workbook = null;
            Excel.Worksheet worksheet = null;
 
            try
            {
                const string template = "Форма.xltx";
 
                // Открываем книгу из папки с откуда запускаем файлом
                workbook = application.Workbooks.Open(System.IO.Path.Combine(System.IO.Path.GetDirectoryName(Application.ExecutablePath), template));
 
                // Получаем активную таблицу
                worksheet = workbook.ActiveSheet as Excel.Worksheet;
/*
Внесение необходимых данных
*/
                //Закрываем Excel
                workbook.Close(false, System.Reflection.Missing.Value, System.Reflection.Missing.Value);
                System.Runtime.InteropServices.Marshal.FinalReleaseComObject(worksheet);
                System.Runtime.InteropServices.Marshal.FinalReleaseComObject(workbook);
                
                ////Подготовка к убийству процесса Excel
                int ExcelPID = 0;
                int Hwnd = 0;
                Hwnd = application.Hwnd;
                System.Diagnostics.Process ExcelProcess;
                GetWindowThreadProcessId((IntPtr)Hwnd, out ExcelPID);
                ExcelProcess = System.Diagnostics.Process.GetProcessById(ExcelPID);
                ////Конец подготовки к убийству процесса Excel
 
                application.Quit();
                System.Runtime.InteropServices.Marshal.FinalReleaseComObject(application);
 
                GC.Collect();
                GC.WaitForPendingFinalizers();
 
                ////Убийство процесса Excel
                ExcelProcess.Kill();
                ExcelProcess = null;

Далее этот сохранённый файл открывается для просмотра пользователю.
Кроме зависшего (до момента закрытия самой программы) в памяти процесса Excel, возникала ещё одна проблема, если файл с именем NewFileName открыт для просмотра, а пользователь попытается сформировать файл с таким же именем, то, разумеется, при попытке сохранить такой файл, будет ошибка. Убивать процесс Excel без проверки нельзя, так как могут быть открыты другие документы.
Вот как это решено у меня:

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
                try
                {// Присоединение к открытому приложению Excel (если оно открыто).
                    excelApp = (Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
 
                    foreach (var item in excelApp.Workbooks)
                    {
                        string tstr = (item as Excel.Workbook).Name;
                        if (tstr== NewFileName)  //Если открыт документ с таким же именем как и тот, что мы сохраняем, то
                        {
                            (item as Excel.Workbook).Close(false); //закрываем его.
                        }
                    }
 
                    if (excelApp.Workbooks.Count < 1) //Если открытых книг не осталось, то завершим процесс
                    {
                        ////Подготовка к убийству процесса Excel
                        int tExcelPID = 0;
                        int tHwnd = 0;
                        tHwnd = excelApp.Hwnd; //Получим HWND окна
                        System.Diagnostics.Process tExcelProcess;
                        GetWindowThreadProcessId((IntPtr)tHwnd, out tExcelPID); //По HWND получим PID
                        tExcelProcess = System.Diagnostics.Process.GetProcessById(tExcelPID); //Подключимся к процессу
                        ////Убийство процесса Excel
                        tExcelProcess.Kill(); 
                        tExcelProcess = null;
                    }
 
 
                }



2



Archi0

31 / 17 / 5

Регистрация: 18.07.2013

Сообщений: 220

25.09.2018, 14:26

15

Процесс можно получить из самого экземпляра

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[DllImport("user32.dll")]
static extern int GetWindowThreadProcessId(int hWnd, out int lpdwProcessId);
 
static Process GetExcelProcess(Excel.Application excelApp)
        {
            GetWindowThreadProcessId(excelApp.Hwnd, out int id);
            return Process.GetProcessById(id);
        }
 
Excel.Application app = new Excel.Application();
Process appProcess = GetExcelProcess(app);
Excel.Workbook workBook = app.Workbooks.Open(doc.pathLoadDocument);
 
workBook.Close();
app.Quit();
appProcess.Kill();



0



129 / 67 / 31

Регистрация: 24.07.2018

Сообщений: 787

03.04.2019, 11:52

16

tdm_nlomov, Давно уже ищу решение, вроде работает!



0



Try this:

excelBook.Close(0); 
excelApp.Quit();

When closing the work-book, you have three optional parameters:

Workbook.close SaveChanges, filename, routeworkbook 

Workbook.Close(false) or if you are doing late binding, it sometimes is easier to use zero
Workbook.Close(0)
That is how I’ve done it when automating closing of workbooks.

Also I went and looked up the documentation for it, and found it here:
Excel Workbook Close

shA.t's user avatar

shA.t

16.4k5 gold badges53 silver badges111 bronze badges

answered Jul 21, 2013 at 23:03

Michael's user avatar

7

xlBook.Save();
xlBook.Close(true);
xlApp.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp);

try this.. it worked for me…
you should release that xl application object to stop the process.

answered Nov 26, 2013 at 9:23

Sameera R.'s user avatar

Sameera R.Sameera R.

4,3442 gold badges36 silver badges53 bronze badges

1

Ref: https://stackoverflow.com/a/17367570/132599

Avoid using double-dot-calling expressions, such as this:

var workbook = excel.Workbooks.Open(/*params*/)

…because in this way you create RCW objects not only for workbook, but for Workbooks, and you should release it too (which is not possible if a reference to the object is not maintained).

This resolved the issue for me. Your code becomes:

public Excel.Application excelApp = new Excel.Application();
public Excel.Workbooks workbooks;
public Excel.Workbook excelBook;
workbooks = excelApp.Workbooks;
excelBook = workbooks.Add(@"C:/pape.xltx");

...

Excel.Sheets sheets = excelBook.Worksheets;
Excel.Worksheet excelSheet = (Worksheet)(sheets[1]);
excelSheet.DisplayRightToLeft = true;
Range rng;
rng = excelSheet.get_Range("C2");
rng.Value2 = txtName.Text;

And then release all those objects:

System.Runtime.InteropServices.Marshal.ReleaseComObject(rng);
System.Runtime.InteropServices.Marshal.ReleaseComObject(excelSheet);
System.Runtime.InteropServices.Marshal.ReleaseComObject(sheets);
excelBook .Save();
excelBook .Close(true);
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBook);
System.Runtime.InteropServices.Marshal.ReleaseComObject(workbooks);
excelApp.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp);

I wrap this in a try {} finally {} to ensure everything gets released even if something goes wrong (what could possibly go wrong?) e.g.

public Excel.Application excelApp = null;
public Excel.Workbooks workbooks = null;
...
try
{
    excelApp = new Excel.Application();
    workbooks = excelApp.Workbooks;
    ...
}
finally
{
    ...
    if (workbooks != null) System.Runtime.InteropServices.Marshal.ReleaseComObject(workbooks);
    excelApp.Quit();
    System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp);
}

Community's user avatar

answered Jan 22, 2015 at 2:24

David Clarke's user avatar

David ClarkeDavid Clarke

12.8k9 gold badges87 silver badges114 bronze badges

3

Think of this, it kills the process:

System.Diagnostics.Process[] process=System.Diagnostics.Process.GetProcessesByName("Excel");
foreach (System.Diagnostics.Process p in process)
{
    if (!string.IsNullOrEmpty(p.ProcessName))
    {
        try
        {
            p.Kill();
        }
        catch { }
    }
}

Also, did you try just close it normally?

myWorkbook.SaveAs(@"C:/pape.xltx", missing, missing, missing, missing, missing, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange, missing, missing, missing, missing, missing);
excelBook.Close(null, null, null);                 // close your workbook
excelApp.Quit();                                   // exit excel application
excel = null;                                      // set to NULL

answered Jul 21, 2013 at 22:27

Morris Miao's user avatar

Morris MiaoMorris Miao

7201 gold badge8 silver badges19 bronze badges

5

Killing Excel is not always easy; see this article: 50 Ways to Kill Excel

This article takes the best advice from Microsoft (MS Knowlege Base Article) on how to get Excel to quit nicely, but then also makes sure about it by killing the process if necessary. I like having a second parachute.

Make sure to Close any open workbooks, Quit the application and Release the xlApp object. Finally check to see if the process is still alive and if so then kill it.

This article also makes sure that we don’t kill all Excel processes but only kills the exact process that was started.

See also Get Process from Window Handle

Here is the code I use: (works every time)

Sub UsingExcel()

    'declare process; will be used later to attach the Excel process
    Dim XLProc As Process

    'call the sub that will do some work with Excel
    'calling Excel in a separate routine will ensure that it is 
    'out of scope when calling GC.Collect
    'this works better especially in debug mode
    DoOfficeWork(XLProc)

    'Do garbage collection to release the COM pointers
    'http://support.microsoft.com/kb/317109
    GC.Collect()
    GC.WaitForPendingFinalizers()

    'I prefer to have two parachutes when dealing with the Excel process
    'this is the last answer if garbage collection were to fail
    If Not XLProc Is Nothing AndAlso Not XLProc.HasExited Then
        XLProc.Kill()
    End If

End Sub

'http://msdn.microsoft.com/en-us/library/ms633522%28v=vs.85%29.aspx
<System.Runtime.InteropServices.DllImport("user32.dll", SetLastError:=True)> _
    Private Shared Function GetWindowThreadProcessId(ByVal hWnd As IntPtr, _
    ByRef lpdwProcessId As Integer) As Integer
End Function

Private Sub ExcelWork(ByRef XLProc As Process)

    'start the application using late binding
    Dim xlApp As Object = CreateObject("Excel.Application")

    'or use early binding
    'Dim xlApp As Microsoft.Office.Interop.Excel

    'get the window handle
    Dim xlHWND As Integer = xlApp.hwnd

    'this will have the process ID after call to GetWindowThreadProcessId
    Dim ProcIdXL As Integer = 0

    'get the process ID
    GetWindowThreadProcessId(xlHWND, ProcIdXL)

    'get the process
    XLProc = Process.GetProcessById(ProcIdXL)


    'do some work with Excel here using xlApp

    'be sure to save and close all workbooks when done

    'release all objects used (except xlApp) using NAR(x)


    'Quit Excel 
    xlApp.quit()

    'Release
    NAR(xlApp)

End Sub

Private Sub NAR(ByVal o As Object)
    'http://support.microsoft.com/kb/317109
    Try
        While (System.Runtime.InteropServices.Marshal.ReleaseComObject(o) > 0)
        End While
    Catch
    Finally
        o = Nothing
    End Try
End Sub

Community's user avatar

answered Jul 23, 2013 at 3:53

D_Bester's user avatar

D_BesterD_Bester

5,6735 gold badges34 silver badges77 bronze badges

1

I met the same problems and tried many methods to solve it but doesn’t work.
Finally , I found the by my way. Some reference enter link description here

Hope my code can help someone future. I have been spent more than two days to solve it.
Below is my Code:

//get current in useing excel
            Process[] excelProcsOld = Process.GetProcessesByName("EXCEL");
            Excel.Application myExcelApp = null;
            Excel.Workbooks excelWorkbookTemplate = null;
            Excel.Workbook excelWorkbook = null;
try{
    //DO sth using myExcelApp , excelWorkbookTemplate, excelWorkbook
}
catch (Exception ex ){
}
finally
            {
                //Compare the EXCEL ID and Kill it 
                Process[] excelProcsNew = Process.GetProcessesByName("EXCEL");
                foreach (Process procNew in excelProcsNew)
                {
                    int exist = 0;
                    foreach (Process procOld in excelProcsOld)
                    {
                        if (procNew.Id == procOld.Id)
                        {
                            exist++;
                        }
                    }
                    if (exist == 0)
                    {
                        procNew.Kill();
                    }        
                }
            }

answered Mar 16, 2017 at 9:42

Kenneth Wong's user avatar

I have found that it is important to have Marshal.ReleaseComObject within a While loop AND
finish with Garbage Collection.

static void Main(string[] args)
{
    Excel.Application xApp = new Excel.Application();
    Excel.Workbooks xWbs = xApp.Workbooks;
    Excel.Workbook xWb = xWbs.Open("file.xlsx");

    Console.WriteLine(xWb.Sheets.Count);

    xWb.Close();
    xApp.Quit();

    while (Marshal.ReleaseComObject(xWb) != 0);
    while (Marshal.ReleaseComObject(xWbs) != 0);
    while (Marshal.ReleaseComObject(xApp) != 0);

    GC.Collect();
    GC.WaitForPendingFinalizers();
}

answered Jun 29, 2020 at 18:25

Emanuel Oliveira's user avatar

1

You may kill process with your own COM object excel pid

add somewhere below dll import code

[DllImport("user32.dll", SetLastError = true)]
private static extern int GetWindowThreadProcessId(IntPtr hwnd, ref int lpdwProcessId);

and use

 if (excelApp != null)
            {
                int excelProcessId = -1;
                GetWindowThreadProcessId(new IntPtr(excelApp.Hwnd), ref excelProcessId);

                Process ExcelProc = Process.GetProcessById(excelProcessId);
                if (ExcelProc != null)
                {
                    ExcelProc.Kill();
                }
            }

MAhipal Singh's user avatar

answered Jan 17, 2018 at 19:14

Alican Kuklaci's user avatar

0

         wb.Close();
         app.Quit();

         System.Diagnostics.Process[] process = System.Diagnostics.Process.GetProcessesByName("Excel");
         foreach (System.Diagnostics.Process p in process)
         {
             if (!string.IsNullOrEmpty(p.ProcessName) && p.StartTime.AddSeconds(+10) > DateTime.Now)
             {
                 try
                 {
                     p.Kill();
                 }
                 catch { }
             }
         }

It Closes last 10 sec process with name «Excel»

answered May 27, 2015 at 8:05

xrhstos's user avatar

xrhstosxrhstos

911 silver badge3 bronze badges

Use a variable for each Excel object and must loop Marshal.ReleaseComObject >0. Without the loop, Excel process still remain active.

public class test{
        private dynamic ExcelObject;
        protected dynamic ExcelBook;
        protected dynamic ExcelBooks;
        protected dynamic ExcelSheet;

public void LoadExcel(string FileName)
        {
            Type t = Type.GetTypeFromProgID("Excel.Application");
            if (t == null) throw new Exception("Excel non installato");
            ExcelObject = System.Activator.CreateInstance(t);
            ExcelObject.Visible = false;
            ExcelObject.DisplayAlerts = false;
            ExcelObject.AskToUpdateLinks = false;
            ExcelBooks = ExcelObject.Workbooks;
            ExcelBook = ExcelBooks.Open(FileName,0,true);
            System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
            ExcelSheet = ExcelBook.Sheets[1];
        }
 private void ReleaseObj(object obj)
        {
            try
            {
                int i = 0;
             while(   System.Runtime.InteropServices.Marshal.ReleaseComObject(obj) > 0)
                {
                    i++;
                    if (i > 1000) break;
                }
                obj = null;
            }
            catch 
            {
                obj = null;
            }
            finally
            {
                GC.Collect();
            }
        }
        public void ChiudiExcel() {
            System.Threading.Thread.CurrentThread.CurrentCulture = ci;

            ReleaseObj(ExcelSheet);
            try { ExcelBook.Close(); } catch { }
            try { ExcelBooks.Close(); } catch { }
            ReleaseObj(ExcelBooks);
            try { ExcelObject.Quit(); } catch { }
            ReleaseObj(ExcelObject);
        }
}

anothernode's user avatar

anothernode

4,95311 gold badges43 silver badges60 bronze badges

answered Aug 2, 2018 at 8:48

user10170010's user avatar

Most of the methods works, but the excel process always stay until close the appliation.

When kill excel process once it can’t be executed once again in the same thread — don’t know why.

answered Sep 30, 2018 at 9:58

Atanas Atanasov's user avatar

The right way to close all excel process

var _excel = new Application();
foreach (Workbook _workbook in _excel.Workbooks) {
    _workbook.Close(0);
}

_excel.Quit();
_excel = null;

Using process example, this may close all the excel process regardless.

var process = System.Diagnostics.Process.GetProcessesByName("Excel");
foreach (var p in process) {
    if (!string.IsNullOrEmpty(p.ProcessName)) {
        try {
            p.Kill();
        } catch { }
    }
}

answered May 17, 2016 at 10:47

Md. Alim Ul Karim's user avatar

1

workbook.Close(0);
excelApp.Quit();

Worked for me.

answered Dec 25, 2020 at 5:57

quan_bui's user avatar

quan_buiquan_bui

691 gold badge3 silver badges8 bronze badges

excelBook.Close();
excelApp.Quit();

add end of the code, it could be enough. it is working on my code

shA.t's user avatar

shA.t

16.4k5 gold badges53 silver badges111 bronze badges

answered Jul 21, 2013 at 22:37

user2605046's user avatar

1

using System;
using Excel = Microsoft.Office.Interop.Excel;

private Excel.Worksheet excelSheet;
private Excel.Workbook wb;
private Excel.Application excel;
public void Close()
{
    wb.Close(true);
    excel.Quit();
    System.Runtime.InteropServices.Marshal.ReleaseComObject(excel);
    System.Runtime.InteropServices.Marshal.ReleaseComObject(wb);
    if(excelSheet!=null)
       System.Runtime.InteropServices.Marshal.ReleaseComObject(excelSheet);
    GC.Collect();
}

Call GC collect to force a garbage collection after closing the application and workbook.

answered Aug 1, 2022 at 9:10

yanzzz's user avatar

I came up with a good solution for this issue that works in many use cases.

Check my previous post for code and explanation: https://stackoverflow.com/a/75414974/10391983

Here is the code:

using System;
using System.Runtime.InteropServices;
using Microsoft.Office.Interop.Excel;

namespace YourNameSpace
{
    public class MicrosoftApplications
    {
        [DllImport("user32.dll")]
        static extern int GetWindowThreadProcessId(int hWnd, out int lpdwProcessId);
        public class Excel
        {   
            public Excel()
            {
                Application = new Microsoft.Office.Interop.Excel.Application();
                RegisterExitEvent();
            }

            public Microsoft.Office.Interop.Excel.Application Application;
            
            private void RegisterExitEvent()
            {
                Application.WindowDeactivate -= XlApp_WindowDeactivate;
                Application.WindowDeactivate += XlApp_WindowDeactivate;
            }

            private void XlApp_WindowDeactivate(Workbook Wb, Window Wn)
            {
                Kill();
            }

            public void Kill()
            {
                int pid = 0;
                GetWindowThreadProcessId(Application.Hwnd, out pid);
                if (pid > 0)
                {
                    System.Diagnostics.Process p = System.Diagnostics.Process.GetProcessById(pid);
                    p.Kill();
                }
                Application = null;
                GC.Collect();
                GC.WaitForPendingFinalizers();
            }
        }
    }
}

And you can call it by:
YourNameSpace.MicrosoftApplications.Excel xlApp = new YourNameSpace.MicrosoftApplications.Excel();

To exit, either the user closes the window or programmatically you can call xlApp.Kill();

answered Feb 10 at 19:21

LancourWestbrook's user avatar

1

Based on another solutions. I have use this:

IntPtr xAsIntPtr = new IntPtr(excelObj.Application.Hwnd);
excelObj.ActiveWorkbook.Close();

System.Diagnostics.Process[] process = System.Diagnostics.Process.GetProcessesByName("Excel");
                foreach (System.Diagnostics.Process p in process)
                {
                    if (p.MainWindowHandle == xAsIntPtr)
                    {
                        try
                        {
                            p.Kill();
                        }
                        catch { }
                    }
                }

Using the «MainWindowHandle» to identify the process and close him.

excelObj: This is my Application Interop excel objecto

answered May 16, 2017 at 22:51

merryrppin's user avatar

We can close the Excel Application while converting xls to xlsx by using following code.
When we perform this kind of task then Excel application is running in task manager, we Should close this excel which is running in background. Interop is a Com component ,to release the com component we used Marshal.FinalReleaseComObject.

 private void button1_Click(object sender, EventArgs e)
    {

        Excel03to07("D:\TestExls\TestExcelApp.XLS");

    }
    private void Excel03to07(string fileName)
    {
        string svfileName = Path.ChangeExtension(fileName, ".xlsx");
        object oMissing = Type.Missing;
        var app = new Microsoft.Office.Interop.Excel.Application();
        var wb = app.Workbooks.Open(fileName, oMissing, oMissing,
                        oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing);
        wb.SaveAs(svfileName, XlFileFormat.xlOpenXMLWorkbook, Type.Missing, Type.Missing, Type.Missing, Type.Missing, XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);

        wb.Close(false, Type.Missing, Type.Missing);
        app.Quit();
        GC.Collect();
        Marshal.FinalReleaseComObject(wb);
        Marshal.FinalReleaseComObject(app);
   }

answered Aug 18, 2018 at 3:28

Sumant Singh's user avatar

Sumant SinghSumant Singh

8661 gold badge13 silver badges16 bronze badges

Another solution to this problem is to save the ProcessID of the Excel program in which you are working with. Then when you are done with the program, you can specifially kill that Excel process without targeting other excel processes.

I got the solution from this answer. Thought I would share it here

So first, you add these line of code outside of a class method

// The DllImport requires -- Using System.Runtime.InteropServices;
[DllImport("user32.dll", SetLastError = true)]
private static extern int GetWindowThreadProcessId(IntPtr hwnd, ref int lpdwProcessId);

After that,

Now in a method of your choosing, add these lines.
These lines discard the specific excel process that you are working with

Modify them to your needs, but the logic is thesame

        if (ExcelApp != null)
        {
            int excelProcessId = 0;

            //your Excel Application variable has access to its Hwnd property
            GetWindowThreadProcessId(new IntPtr(ExcelApp.Hwnd), ref excelProcessId);

            // you need System.Diagnostics to use Process Class
            Process ExcelProc = Process.GetProcessById(excelProcessId);

            if (ExcelProc != null)
            {
                ExcelProc.Kill();
            }
        }

Hence in total your program should look like this

class Program
{
    [DllImport("user32.dll", SetLastError = true)]
    private static extern int GetWindowThreadProcessId(IntPtr hwnd, ref int lpdwProcessId);

    static void Main(string[] args)
    {
        Application ExcelApp = new Application();

        _Workbook ExcelWrkBook = ExcelApp.Workbooks.Open(filePath);

        _Worksheet ExcelWrkSht = ExcelWrkBook.ActiveSheet;

        ExcelWrkSht.Cells[1, 2] = "70";

        if (ExcelApp != null)
        {
            int excelProcessId = 0; // simple declare, zero is merely a place holder

            GetWindowThreadProcessId(new IntPtr(ExcelApp.Hwnd), ref excelProcessId);

            Process ExcelProc = Process.GetProcessById(excelProcessId);

            if (ExcelProc != null)
            {
                ExcelProc.Kill();
            }
        }

    }
}

I have tested this and it removes my Excel processes as shown in Task Manager

answered May 19, 2021 at 0:36

Jamisco's user avatar

JamiscoJamisco

1,5933 gold badges13 silver badges17 bronze badges

I’m going to write what worked for me in case it can help somebody in the future.

Doing this before Save, SaveAs AND Quit fixed my problem. It might be needed around other methods I don’t use.

m_pXLApp->PutDisplayAlerts( VARIANT_FALSE );

No more dangling EXCEL.EXE

From what I’m understanding from Microsoft documentation, this was designed to silence messages prompting the user to save his work but also works for other messages like compatibility issues.

Those messages never showed up for me but something was preventing Excel from exiting.
After trying to track ref counts on COM objects, this was the only «longshot» I had left to try.

Hope this helps somebody

answered Mar 28 at 16:59

Jean-Simon Brochu's user avatar

        GetWindowThreadProcessId((IntPtr)app.Hwnd, out iProcessId);
        wb.Close(true,Missing.Value,Missing.Value);
        app.Quit();
        System.Diagnostics.Process[] process = System.Diagnostics.Process.GetProcessesByName("Excel");
        foreach (System.Diagnostics.Process p in process)
        {
            if (p.Id == iProcessId)
            {
                try
                {
                    p.Kill();
                }
                catch { }
            }
        }
}
[DllImport("user32.dll")]

private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

uint iProcessId = 0;

this GetWindowThreadProcessId finds the correct Process Id o excell ….
After kills it….
Enjoy It!!!

answered Jun 16, 2015 at 13:37

xrhstos's user avatar

xrhstosxrhstos

911 silver badge3 bronze badges

private void releaseObject(object obj)
{
    try
    {
        System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
        obj = null;
    }
    catch (Exception ex)
    {
        obj = null;
        MessageBox.Show("Unable to release the Object " + ex.ToString());
    }
    finally
    {
        GC.Collect();
    }
}

Milo's user avatar

Milo

3,3379 gold badges29 silver badges44 bronze badges

answered Feb 3, 2020 at 19:34

Mehmet Yardım's user avatar

1

   Aswed

10.04.09 — 11:57

САБЖ, делаю

Ексель.Application.Workbooks.Close();

Ексель.Application.Quit();

Ексель = «»;

всё по барабану, в диспетчере задач так и весит процесс.

   Aprobator

1 — 10.04.09 — 12:01

Странно. Кстати, Application нафига? У тебя Ексель — что такое?

   Aswed

2 — 10.04.09 — 12:02

Ексель = Новый COMОбъект(«Excel.Application»)

может ни к той переменной применяю?:)

   Aprobator

3 — 10.04.09 — 12:03

Applaction в сад.

   vde69

4 — 10.04.09 — 12:03

   Aprobator

5 — 10.04.09 — 12:04

Ексель.Workbooks.Close(0); — чтобы про запсиывать или нет не спрашивал
и Ексель.Quit()

   vde69

6 — 10.04.09 — 12:04

(4)+ от туда

Процедура EXCEL_РазорватьСвязь (Соответстие) Экспорт

   Попытка

       Соответстие[«EXCEL»].DisplayAlerts = 0;

       Соответстие[«ExcelФайл»].Close();

       Соответстие[«EXCEL»].DisplayAlerts = 1;

       Соответстие[«EXCEL»].Quit();

       Соответстие[«EXCEL»] = Неопределено;

   Исключение

       #Если Клиент Тогда

           Сообщить(ОписаниеОшибки());

       #КонецЕсли

   КонецПопытки;                  

КонецПроцедуры

   Aprobator

7 — 10.04.09 — 12:05

(5) хотя про 0 вру — он не нужен.

   gr13

8 — 10.04.09 — 12:06

   gr13

9 — 10.04.09 — 12:06

Закрываем файл Excel
CODE
ФайлExcel.Quit();

   Aswed

10 — 10.04.09 — 12:07

(3) Не катит:) Вылетает с ошибкой что к тому объекту не применима данная команда

   Aswed

11 — 10.04.09 — 12:09

(6) Что такое соответствие?

   vde69

12 — 10.04.09 — 12:10

(11) по ссылке сходить религия не позволяет?

   Aprobator

13 — 10.04.09 — 12:12

Короче возможная проблема — вопрос записывать файл или нет?

Eксель.DisplayAlerts = 0;
Ексель.Quit();

   Aswed

14 — 10.04.09 — 12:12

(12) Сходил:)

   Aswed

15 — 10.04.09 — 12:14

(13) В точку!

   Aswed

16 — 10.04.09 — 12:14

Спасибо!:)

   Aswed

17 — 10.04.09 — 12:15

(12) спасиб, за подборку, то что нужно:)

   Aprobator

18 — 10.04.09 — 12:15

(15) ну дык — советы товарища vde69 надо читать внимательно :)

   vde69

19 — 10.04.09 — 12:15

(13) правильно так

Eксель.DisplayAlerts = 0;

Ексель.Quit();

Eксель.DisplayAlerts = 1;

по тому как если запущено 2 екземпляра, то будет прико

   Aprobator

20 — 10.04.09 — 12:17

(19) хм — это я не учел. Вернее не сталкивался с этим на практике. Я просто не закрываю свои файлы оптом. А по одному через Close(0)

   Aswed

21 — 10.04.09 — 12:19

(19) Закроет все открытые?

   Aprobator

22 — 10.04.09 — 12:21

(19) а что Ексель — может ссылаться одновременно на два экземпляра?

   vde69

23 — 10.04.09 — 12:49

(22) сколько процессов (не окон) EXEL — может висеть?

   Torquader

24 — 10.04.09 — 13:06

Процессов может быть и более одного, например, если запускать их через CreateProcess, но объект в таблице объектов будет общий (хотя, иногда бывает, что оказываются два разных объекта — если запускать одновременно).
При этом, ссылка будет на один конкретный объект приложения.
(19) После того, как мы вызвали Excel.Quit() ничего уже нельзя вызывать из методов, так как Excel закрывается и можно увидеть ошибку (а можно и не увидеть, если не успеет закрыться). Quit явно завешает OLE-сервер вне зависимости от того, есть ли на него ссылки.

  

Aprobator

25 — 10.04.09 — 13:14

(23) процессов то может быть несколько, но я как то считал, что воздействуя на 1 процесс, другие не затрагиваю.

Всем доброго дня!

Столкнулся с проблемой, с которой уже столкнулось много народу, занимающихся разработкой под Excel: экземпляр приложения остается висеть в Диспетчере задач, даже после закрытия книг, приложений и их высвобождения.

Перечитал довольно много форумов и уже что только не попробовал — вот ни в какую…не работает. По сабжу могу выделить следующие ресурсы:

раз,
два. Но, собсн, либо лыжи не едут, либо я не так пишу…

Притом, я заметил, что все работает нормально, когда объекты, относящиеся к Excel, не участвуют в циклах. Как только чтение или запись воткнуть в цикл, так все…капут. По этому поводу пробовал засунуть диапазон ячеек цикла в один
Range, а затем высвободить его, но это тоже не помогло.

Пожалуйста, помогите решить проблему!)))

Добавляю кусок кода для примера. В примере: если закомментировать строки

Console.WriteLine("Reading | Cell[" + RowID + ", 1] = " + ExcelWorksheet.UsedRange.Cells[RowID, 1].Value2);
Temp = Convert.ToInt32(ExcelWorksheet.UsedRange.Cells[RowID, 1].Value2);

то все работает нормально, но если хотя бы одна из них выполняется, так все, ппц.

Заранее всем спасибо! :)

static void TestMethod()
{
        int RowID = 1;
        int Temp = 0;

        Excel.Application ExcelApplication = new Excel.Application();

        Excel.Workbooks ExcelWorkbooks = ExcelApplication.Workbooks;
        Excel.Workbook ExcelWorkbook = ExcelApplication.Workbooks.Open("D:\Downloads\TestWorkbook.xlsx");
            
        Excel.Sheets ExcelWorksheets = ExcelWorkbook.Worksheets;
        Excel.Worksheet ExcelWorksheet = ExcelWorksheets.Item[1];
            
        while (ExcelWorksheet.UsedRange.Cells[RowID, 1].Value2 != null)
        {
            Console.WriteLine("Reading | Cell[" + RowID + ", 1] = " + ExcelWorksheet.UsedRange.Cells[RowID, 1].Value2);
            Temp = Convert.ToInt32(ExcelWorksheet.UsedRange.Cells[RowID, 1].Value2);
            RowID++;
        }
            
        Console.WriteLine("Closing...");
            
        ExcelWorkbook.Save();
        ExcelWorkbook.Close();
        ExcelApplication.Quit();
            
        Marshal.ReleaseComObject(ExcelWorksheets);
        Marshal.ReleaseComObject(ExcelWorksheet);
        Marshal.ReleaseComObject(ExcelWorkbooks);
        Marshal.ReleaseComObject(ExcelWorkbook);
        Marshal.ReleaseComObject(ExcelApplication);
            
        GC.Collect();
            
        Console.WriteLine("Closed");
        Console.ReadLine();
}
 

CAHO

Пользователь

Сообщений: 2183
Регистрация: 25.02.2013

#1

07.07.2015 14:07:19

Здравствуйте друзья.
Каким образом можно закрыть текущую книгу вместе с приложением.
Просто закрыть книгу можно так:

Код
ThisWorkbook.Close

Таким образом удобно закрывать когда открыто несколько книг. А вот если открыта всего одна книга, то при закрытии остаётся открытым само приложение Excel. И его ещё раз приходится закрывать. Как же можно закрыть книгу вместе с приложение, если она одна?
Спасибо.

Прикрепленные файлы

  • Закрыть.xlsm (12.87 КБ)

Мастерство программиста не в том, чтобы писать программы, работающие без ошибок.
А в том, чтобы писать программы, работающие при любом количестве ошибок.

 

Sanja

Пользователь

Сообщений: 14838
Регистрация: 10.01.2013

#2

07.07.2015 14:10:04

?

Код
Application.Quit                  

Согласие есть продукт при полном непротивлении сторон.

 

CAHO

Пользователь

Сообщений: 2183
Регистрация: 25.02.2013

Sanja

, спасибо. Тогда придётся делать проверку на количество открытых книг с таким способом закрытия, ибо если открыто их несколько, то он всё закрывает.

Мастерство программиста не в том, чтобы писать программы, работающие без ошибок.
А в том, чтобы писать программы, работающие при любом количестве ошибок.

 

Sanja

Пользователь

Сообщений: 14838
Регистрация: 10.01.2013

#4

07.07.2015 14:16:50

Цитата
CAHO написал: Как же можно закрыть книгу вместе с приложение, ЕСЛИ ОНА ОДНА?
Цитата
ибо если открыто их НЕСКОЛЬКО, то он всё закрывает.

?

Изменено: Sanja07.07.2015 14:22:05

Согласие есть продукт при полном непротивлении сторон.

 

CAHO

Пользователь

Сообщений: 2183
Регистрация: 25.02.2013

#5

07.07.2015 14:24:12

И как закрыть книгу в таком случае без сохранения?

Код
ThisWorkbook.Close (False)

с application это не проканало

Цитата
…или лыжи не едут…

вообще не понял при чём тут лыжи.

Мастерство программиста не в том, чтобы писать программы, работающие без ошибок.
А в том, чтобы писать программы, работающие при любом количестве ошибок.

 

Sanja

Пользователь

Сообщений: 14838
Регистрация: 10.01.2013

#6

07.07.2015 14:32:13

CAHO, вроде не первую сотню сообщений на сайте. В стартовом топике стоял вопрос

Цитата
Как же можно закрыть книгу вместе с приложение, если она одна?

сообщение #2 отвечает на него. Про то

Цитата
И как закрыть книгу в таком случае без сохранения?
Код
With Application
    .DisplayAlerts = False
    .Quit
End With

Согласие есть продукт при полном непротивлении сторон.

 

CAHO

Пользователь

Сообщений: 2183
Регистрация: 25.02.2013

Sanja

, спасибо. Разобрался. В файле (оригинале другом) ошибка была сделана и поэтому #6 сообщение у меня не работало. Поэтому и переспросил как сохранить без возможности сохранения.

Мастерство программиста не в том, чтобы писать программы, работающие без ошибок.
А в том, чтобы писать программы, работающие при любом количестве ошибок.

 

юнат

Пользователь

Сообщений: 22
Регистрация: 18.10.2022

#8

03.11.2022 14:29:44

Сенсеи подскажите чем можно излечить мою болячку?
Проблема в заполнении процессом EXCEL.EXE при каждом срабатывании скрипта в скаде.
Один раз скрипт отработал — один процесс EXCEL.EXE запустился, и т. д.
Вот такой код в скрипте, работа с екселем:

Код
Set objExcelApp = CreateObject("Excel.Application")
objExcelApp.Visible = False
objExcelApp.Workbooks.Open ""+path
Set objWorkSheet = objExcelApp.ActiveWorkbook.Worksheets(num_sheet)
Set objTag1= SmartTags(""+name_tag2)
objTag1.Value= objWorkSheet.Cells(num_row,num_colum).Value
objTag1.Write

objExcelApp.ActiveWorkbook.Save
objExcelApp.Workbooks.Close
objExcelApp.Quit
Set objTag1= Nothing

А может можно в конце макроса или другим макросом закрывать этот процесс вот здесь C:Program FilesMicrosoft OfficerootOffice16EXCEL.EXE?

Прикрепленные файлы

  • дисп зад.jpg (64.8 КБ)

 

МатросНаЗебре

Пользователь

Сообщений: 5516
Регистрация: 05.02.2014

#9

03.11.2022 14:42:02

А если эту строку убрать?

Код
objExcelApp.Workbooks.Close

Цитата
написал:
А может можно в конце макроса или другим макросом закрывать этот процесс

Вот так можно закрыть все процессы. При желании, если знаете ID, то можно и конкретный процесс убрать.

Код
Shell "TASKKILL /F /im excel.exe", 0
 

юнат

Пользователь

Сообщений: 22
Регистрация: 18.10.2022

#10

04.11.2022 10:04:16

МатросНаЗебре, спасибо,

objExcelApp.Workbooks.Close  — убрал, не помогло.

Shell, TASKKILL, KILL — скада не знает таких команд, ругается.

А вот как узнать ИД процесса и удалить его это может помочь, но для этого вопроса скорее всего нужна отдельная тема, я такую не нашёл.

Как закрыть Эксель, если не закрывается? Воспользуйтесь комбинацией Alt+F4, запустите «Диспетчер задач» и удалите процесс Excel, снимите задачу для приложения или просто перезагрузите компьютер / ноутбук (рекомендуется в крайнем случае). Ниже подробно рассмотрим, как действовать при возникновении подобных проблем, и какими методами можно закрыть программу.

Причины, почему не закрывается Excel

Существует множество причин, почему не закрывается Эксель, как и в случае с другими программами. К основным объяснениям можно отнести:

  1. Ошибка в программном коде.
  2. Конфликты с другими ПО.
  3. Загрязненная операционная система.
  4. Применение не подходящей версии Виндовс.
  5. Сбои работы жесткого диска.
  6. Дефицит оперативной памяти.
  7. Действие вирусов.
  8. Прочие причины.

Что делать

При возникновении зависания нужно сначала разобраться, как закрыть программу, если при нажатии на «крестик» Эксель не закрывается. Рассмотрим основные варианты.

Используйте горячие клавиши

Первое, что стоит сделать при возникновении подобных проблем — попробовать закрыть приложение с помощью комбинации горячих кнопок. Чаще всего работает Alt+F4. В ее задачи входит принудительное прекращение работы процесса.

Закройте приложение через специальную панель

Если рассмотренный метод не помогает, можно использовать еще один метод, как закрыть Эксель — сделать это с помощью вызова специальной панели. Для этого жмите на Ctrr+Alt+Del, после чего войдите в «Диспетчер задач» и во вкладку «Процессы». Здесь найдите нужный вариант с названием Excel, жмите правой кнопкой мышки и кликните «Снять задачу». Как вариант, можно зайти в раздел «Служба приложений» и отключить нужный софт там.

Специальная программа

Бывают ситуации, когда не закрывается файл Эксель из-за отсутствия процесса в списке. В таком случае может потребоваться специальная программа — Process Exprorer. Она не требует установки. Достаточно скачать ее с официального сайта docs.microsoft.com/ru-ru/previous-versions/bb896653(v=msdn.10)?redirectedfrom=MSDN, запустить и найти нужный процесс.  В отличие от «Диспетчера задач» здесь отображаются все процессы. Найдите интересующий, кликните на него правой кнопкой мышки и выберите кнопку удаления.

Альтернативный вариант

Крайний метод, что делать, если не закрывается Эксель при выполнении всех рассмотренных выше шагов — принудительно перезапустить компьютер / ноутбук. После запуска программа будет закрыта, и ее можно будет снова запустить. При этом сохраняется риск сбоев во время работы, поэтому нужно определить причину.

Что еще сделать после закрытия / во время работы

Ситуация, когда не закрываются файлы Excel, нужно разобраться с дальнейшими шагами. Важно выявить причину и избежать подобных ситуаций в будущем. Сделайте следующие шаги.

Убедитесь, что Эксель не пользуется другим процессом

В ситуации, когда Excel занята другим процессом, эти данные будут отображаться в нижней части окна. Если параллельно какие-то приложения пытаются выполнить действия, Эксель не будет отвечать, и закрыть его не получится. В таком случае дождитесь, пока задание выполниться, после чего сделайте еще одну попытку.

Проверьте систему на вирусы

Если Excel не закрывается, проверьте ПК / ноутбук на вирусы. Проблемы с прекращением работы могут возникнуть на фоне действия вредоносного ПО. В случае его удаления можно попробовать закрыть контент, и это происходит без проблем.

Решение проблем с надстройками

Применение надстроек упрощает работу с Эксель, но параллельно могут возникать конфликты. Попробуйте запустить приложение без надстроек и проверьте, удастся ли закрыть приложение. При работе в Виндовс 10 кликните на Win+R, а после — Excel / safe. Далее жмите «ОК». Если проблему удалось устранить, кликните на «Файл», а далее «Параметры» и «Надстройки».

Выберите «Надстройки СОМ» и жмите на кнопку «Перейти». После очистки флажков жмите «ОК». После откройте и попробуйте закрыть Эксель. Если он все равно не закрывается, причина может быть в другом.

Убедитесь, что файл не создается другим приложением. В таком случае некоторые функции Excel могут работать некорректно.

Дополнительные советы

Жалобы, мол, не могу закрыть Эксель, часто встречаются в Интернете. Пользователи не могут разобраться с зависанием и часто решают вопрос кардинально и путем отключения ПК / ноутбука. Но в большинстве случаев проблему можно решить более простым путем:

  1. Убедитесь, что софт не закрывается именно из-за внутренних проблем. Бывают ситуации, что неисправность именно в компьютере. Распространенная ситуация, когда закрыть Эксель не удается из-за дефицита оперативной памяти или сбоях в работе процессора. В таком случае нужно попробовать закрыть другое «тяжелое» ПО и повторить попытку.
  2. Переустановите программу. Если с Excel регулярно возникают проблемы, возможно, он установился некорректно и требует перестановки. Попробуйте удалить и установить заново программу.
  3. Обновите Excel, если он регулярно не закрывается, до последней версии.
  4. Убедитесь, что версия и разрядность Виндовс соответствуют требованиям.
  5. Выждите время. Многие пользователи слишком торопятся и хотят, чтобы ПО закрывалось мгновенно. Но иногда программа немного зависает. Нужно просто подождать и закрыть ее через несколько минут.

Зная, как закрыть Эксель, и почему он не закрывается, вы сможете решить проблему с программой и исключить ее появление в будущем. Для начала перепробуйте приведенные выше методы, а перезапуск / выключение оставьте на крайний случай. Это связано с тем, что при грубой перезагрузки многая информация может быть утеряна. Также не забывайте сохраняться перед попыткой закрытия, чтобы не допустить потери важных файлов.

В комментариях расскажите, какой из приведенных советов вам действительно помог, и какие еще шаги можно реализовать для решения ситуации.

Отличного Вам дня!

Понравилась статья? Поделить с друзьями:

А вот еще интересные статьи:

  • Как закруглить ячейку excel
  • Как закруглить углы word
  • Как закреплять ячейку в формулах таблиц excel
  • Как закреплять ячейки в excel сочетание клавиш
  • Как закреплять ссылки в excel

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии