vb.net 调用退出后应用程序不退出
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15697282/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Application not quitting after calling quit
提问by ???ěxě?
I have a small problem that I can't seem to figure out. I am saving a DataGridView (it's contents) to an xls file. I have no problem in doing so except in my task manager its still showing up that it's running. I have called:
我有一个小问题,我似乎无法弄清楚。我正在将 DataGridView(它的内容)保存到一个 xls 文件中。我这样做没有问题,除了在我的任务管理器中它仍然显示它正在运行。我打电话给:
xlApp.Application.Quit()
This is declared as:
这被声明为:
Dim xlApp As New excel.Application
This seems to not work, BUT this is the same way I quit when I let the user choose to export it to a Word Document. Im not sure where I am going wrong...
这似乎不起作用,但这与我让用户选择将其导出到 Word 文档时退出的方式相同。我不确定我哪里出错了......
Here is my complete code
这是我的完整代码
Imports Word = Microsoft.Office.Interop.Word
Imports Excel = Microsoft.Office.Interop.Excel
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
For x As Integer = 1 To 3500
DataGridView1.Rows.Add(New Object() {"r" & x.ToString & "c1", "r" & x.ToString & "c2", "r" & x.ToString & "c3", "r" & x.ToString & "c4", "r" & x.ToString & "c5"})
Next
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
exportToWord (DataGridView1)
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim xlApp As New Excel.Application
Dim xlWorkBook As Excel.Workbook
Dim xlWorkSheet As Excel.Worksheet
'Dim misValue As Object = System.Reflection.Missing.Value
xlWorkBook = xlApp.Workbooks.Add
xlWorkSheet = DirectCast(xlWorkBook.Sheets("sheet1"), Excel.Worksheet)
xlApp.Visible = True
Dim headers = (From ch In DataGridView1.Columns _
Let header = DirectCast(DirectCast(ch, DataGridViewColumn).HeaderCell, DataGridViewColumnHeaderCell) _
Select header.Value).ToArray()
Dim headerText() As String = Array.ConvertAll(headers, Function(v) v.ToString)
Dim items() = (From r In DataGridView1.Rows _
Let row = DirectCast(r, DataGridViewRow) _
Where Not row.IsNewRow _
Select (From cell In row.Cells _
Let c = DirectCast(cell, DataGridViewCell) _
Select c.Value).ToArray()).ToArray()
Dim table As String = String.Join(vbTab, headerText) & Environment.NewLine
For Each a In items
Dim t() As String = Array.ConvertAll(a, Function(v) v.ToString)
table &= String.Join(vbTab, t) & Environment.NewLine
Next
table = table.TrimEnd(CChar(Environment.NewLine))
Clipboard.SetText (table)
Dim alphabet() As Char = "abcdefghijklmnopqrstuvwxyz".ToUpper.ToCharArray
Dim range As excel.Range = xlWorkSheet.Range("B2:" & alphabet(headerText.Length) & (items.Length + 2).ToString)
range.Select()
xlWorkSheet.Paste()
range.Borders(Excel.XlBordersIndex.xlDiagonalDown).LineStyle = Excel.XlLineStyle.xlLineStyleNone
range.Borders(Excel.XlBordersIndex.xlDiagonalUp).LineStyle = Excel.XlLineStyle.xlLineStyleNone
With range.Borders(Excel.XlBordersIndex.xlEdgeLeft)
.LineStyle = Excel.XlLineStyle.xlContinuous
.ColorIndex = 1 'black
.TintAndShade = 0
.Weight = Excel.XlBorderWeight.xlMedium
End With
With range.Borders(Excel.XlBordersIndex.xlEdgeTop)
.LineStyle = Excel.XlLineStyle.xlContinuous
.ColorIndex = 1 'black
.TintAndShade = 0
.Weight = Excel.XlBorderWeight.xlMedium
End With
With range.Borders(Excel.XlBordersIndex.xlEdgeBottom)
.LineStyle = Excel.XlLineStyle.xlContinuous
.ColorIndex = 1 'black
.TintAndShade = 0
.Weight = Excel.XlBorderWeight.xlMedium
End With
With range.Borders(Excel.XlBordersIndex.xlEdgeRight)
.LineStyle = Excel.XlLineStyle.xlContinuous
.ColorIndex = 1 'black
.TintAndShade = 0
.Weight = Excel.XlBorderWeight.xlMedium
End With
With range.Borders(Excel.XlBordersIndex.xlInsideVertical)
.LineStyle = Excel.XlLineStyle.xlContinuous
.ColorIndex = 1 'black
.TintAndShade = 0
.Weight = Excel.XlBorderWeight.xlThin
End With
With range.Borders(Excel.XlBordersIndex.xlInsideHorizontal)
.LineStyle = Excel.XlLineStyle.xlContinuous
.ColorIndex = 1 'black
.TintAndShade = 0
.Weight = Excel.XlBorderWeight.xlThin
End With
'xlApp.Visible = True
xlWorkBook.SaveAs("C:\Users\CoDeXeR\Desktop\Word1.xls", True)
xlWorkBook.Close()
xlApp.Application.Quit()
ReleaseObject(xlWorkSheet) '<~~~ Added as per comment from deleted post
ReleaseObject (xlWorkBook)
ReleaseObject (xlApp)
End Sub
Public Sub exportToWord(ByVal dgv As DataGridView)
' Create Word Application
Dim oWord As Word.Application = DirectCast(CreateObject("Word.Application"), Word.Application)
' Create new word document
Dim oDoc As Word.Document = oWord.Documents.Add()
Dim headers = (From ch In dgv.Columns _
Let header = DirectCast(DirectCast(ch, DataGridViewColumn).HeaderCell, DataGridViewColumnHeaderCell) _
Select header.Value).ToArray()
Dim headerText() As String = Array.ConvertAll(headers, Function(v) v.ToString)
Dim items() = (From r In dgv.Rows _
Let row = DirectCast(r, DataGridViewRow) _
Where Not row.IsNewRow _
Select (From cell In row.Cells _
Let c = DirectCast(cell, DataGridViewCell) _
Select c.Value).ToArray()).ToArray()
Dim table As String = String.Join(vbTab, headerText) & Environment.NewLine
For Each a In items
Dim t() As String = Array.ConvertAll(a, Function(v) v.ToString)
table &= String.Join(vbTab, t) & Environment.NewLine
Next
table = table.TrimEnd(CChar(Environment.NewLine))
Clipboard.SetText (table)
Dim oTable As Word.Table = oDoc.Tables.Add(oDoc.Bookmarks.Item("\endofdoc").Range, items.Count + 1, headers.Count)
oTable.Range.Paste()
'make the first row bold, fs 14 + change textcolor
oTable.Rows.Item(1).range.Font.Bold = &H98967E
oTable.Rows.Item(1).range.Font.Size = 14
oTable.Rows.Item(1).range.Font.Color = Word.WdColor.wdColorWhite
'change backcolor of first row
oTable.Rows.Item(1).range.Shading.Texture = Word.WdTextureIndex.wdTextureNone
oTable.Rows.Item(1).range.Shading.ForegroundPatternColor = Word.WdColor.wdColorAutomatic
oTable.Rows.Item(1).range.Shading.BackgroundPatternColor = Word.WdColor.wdColorLightBlue
''set table borders
'With oTable.Range.Tables(1)
' With .Borders(Word.WdBorderType.wdBorderLeft)
' .LineStyle = Word.WdLineStyle.wdLineStyleSingle
' .LineWidth = Word.WdLineWidth.wdLineWidth100pt
' .Color = Word.WdColor.wdColorAutomatic
' End With
' With .Borders(Word.WdBorderType.wdBorderRight)
' .LineStyle = Word.WdLineStyle.wdLineStyleSingle
' .LineWidth = Word.WdLineWidth.wdLineWidth100pt
' .Color = Word.WdColor.wdColorAutomatic
' End With
' With .Borders(Word.WdBorderType.wdBorderTop)
' .LineStyle = Word.WdLineStyle.wdLineStyleSingle
' .LineWidth = Word.WdLineWidth.wdLineWidth100pt
' .Color = Word.WdColor.wdColorAutomatic
' End With
' With .Borders(Word.WdBorderType.wdBorderBottom)
' .LineStyle = Word.WdLineStyle.wdLineStyleSingle
' .LineWidth = Word.WdLineWidth.wdLineWidth100pt
' .Color = Word.WdColor.wdColorAutomatic
' End With
' With .Borders(Word.WdBorderType.wdBorderHorizontal)
' .LineStyle = Word.WdLineStyle.wdLineStyleSingle
' .LineWidth = Word.WdLineWidth.wdLineWidth050pt
' .Color = Word.WdColor.wdColorAutomatic
' End With
' With .Borders(Word.WdBorderType.wdBorderVertical)
' .LineStyle = Word.WdLineStyle.wdLineStyleSingle
' .LineWidth = Word.WdLineWidth.wdLineWidth050pt
' .Color = Word.WdColor.wdColorAutomatic
' End With
' .Borders(Word.WdBorderType.wdBorderDiagonalDown).LineStyle = Word.WdLineStyle.wdLineStyleNone
' .Borders(Word.WdBorderType.wdBorderDiagonalUp).LineStyle = Word.WdLineStyle.wdLineStyleNone
' .Borders.Shadow = False
'End With
' Save this word document
oDoc.SaveAs("C:\Users\CoDeXeR\Desktop\Word1.doc", True)
oDoc.Close()
oWord.Application.Quit()
'oWord.Visible = True
End Sub
Public Sub exportToExcel(ByVal dgv As DataGridView)
End Sub
Private Sub ReleaseObject(ByVal obj As Object)
Try
System.Runtime.InteropServices.Marshal.ReleaseComObject (obj)
obj = Nothing
Catch ex As Exception
obj = Nothing
Finally
GC.Collect()
End Try
End Sub
End Class
回答by Siddharth Rout
Just Calling .Quit()
will not remove the Application from memory. It is very important to close the objects after you are done with your coding. This ensures that all objects are released properly and nothing remains in the memory.
仅调用.Quit()
不会从内存中删除应用程序。完成编码后关闭对象非常重要。这确保了所有对象都被正确释放,并且没有任何东西留在内存中。
See this example
看这个例子
Imports Excel = Microsoft.Office.Interop.Excel
Public Class Form1
'~~> Define your Excel Objects
Dim xlApp As New Excel.Application
Dim xlWorkBook As Excel.Workbook
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'~~> Add a New Workbook
xlWorkBook = xlApp.Workbooks.Add
'~~> Display Excel
xlApp.Visible = True
'~~> Do some stuff Here
'~~> Save the file
xlWorkBook.SaveAs(Filename:="C:\Tutorial\SampleNew.xlsx", FileFormat:=51)
'~~> Close the File
xlWorkBook.Close()
'~~> Quit the Excel Application
xlApp.Quit()
'~~> Clean Up
releaseObject (xlApp)
releaseObject (xlWorkBook)
End Sub
'~~> Release the objects
Private Sub releaseObject(ByVal obj As Object)
Try
System.Runtime.InteropServices.Marshal.ReleaseComObject (obj)
obj = Nothing
Catch ex As Exception
obj = Nothing
Finally
GC.Collect()
End Try
End Sub
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
Me.Close()
End Sub
End Class
Also worth mentioning is the 2 DOT Rule.
另外值得一提的是2 DOT规则。
If you love automating Excel from VB.Net then you might also want to have a look at this link.
如果您喜欢从 VB.Net 自动化 Excel,那么您可能还想查看此链接。
FOLLOWUP
跟进
The problem is the 2 DOT Rule as I mentioned above. When you use the 2 DOT Rule (Ex: Excel.XlBordersIndex.xlDiagonalDown
) then you have to do the Garbage Collection by using GC.Collect()
. So All you need to do is add this part
问题是我上面提到的 2 DOT 规则。当您使用 2 DOT 规则(例如:)时,Excel.XlBordersIndex.xlDiagonalDown
您必须使用GC.Collect()
. 所以你需要做的就是添加这部分
Finally
GC.Collect()
in the Private Sub ReleaseObject(ByVal obj As Object)
在里面 Private Sub ReleaseObject(ByVal obj As Object)
Private Sub ReleaseObject(ByVal obj As Object)
Try
Dim intRel As Integer = 0
Do
intRel = System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
Loop While intRel > 0
MsgBox("Final Released obj # " & intRel)
Catch ex As Exception
MsgBox("Error releasing object" & ex.ToString)
obj = Nothing
Finally
GC.Collect()
End Try
End Sub
FINAL CODE (Tried And Tested)
最终代码(经过试验和测试)
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim xlApp As New excel.Application
Dim xlWorkBook As excel.Workbook
Dim xlWorkSheet As excel.Worksheet
Dim xlRange As excel.Range
'Dim misValue As Object = System.Reflection.Missing.Value
xlWorkBook = xlApp.Workbooks.Add
xlWorkSheet = DirectCast(xlWorkBook.Sheets("sheet1"), excel.Worksheet)
xlApp.Visible = True
Dim headers = (From ch In DataGridView1.Columns _
Let header = DirectCast(DirectCast(ch, DataGridViewColumn).HeaderCell, DataGridViewColumnHeaderCell) _
Select header.Value).ToArray()
Dim headerText() As String = Array.ConvertAll(headers, Function(v) v.ToString)
Dim items() = (From r In DataGridView1.Rows _
Let row = DirectCast(r, DataGridViewRow) _
Where Not row.IsNewRow _
Select (From cell In row.Cells _
Let c = DirectCast(cell, DataGridViewCell) _
Select c.Value).ToArray()).ToArray()
Dim table As String = String.Join(vbTab, headerText) & Environment.NewLine
For Each a In items
Dim t() As String = Array.ConvertAll(a, Function(v) v.ToString)
table &= String.Join(vbTab, t) & Environment.NewLine
Next
table = table.TrimEnd(CChar(Environment.NewLine))
Clipboard.SetText(table)
Dim alphabet() As Char = "abcdefghijklmnopqrstuvwxyz".ToUpper.ToCharArray
xlRange = xlWorkSheet.Range("B2:" & alphabet(headerText.Length) & (items.Length + 2).ToString)
xlRange.Select()
xlWorkSheet.Paste()
xlRange.Borders(excel.XlBordersIndex.xlDiagonalDown).LineStyle = excel.XlLineStyle.xlLineStyleNone
xlRange.Borders(excel.XlBordersIndex.xlDiagonalUp).LineStyle = excel.XlLineStyle.xlLineStyleNone
With xlRange.Borders(excel.XlBordersIndex.xlEdgeLeft)
.LineStyle = excel.XlLineStyle.xlContinuous
.ColorIndex = 1 'black
.TintAndShade = 0
.Weight = excel.XlBorderWeight.xlMedium
End With
With xlRange.Borders(excel.XlBordersIndex.xlEdgeTop)
.LineStyle = excel.XlLineStyle.xlContinuous
.ColorIndex = 1 'black
.TintAndShade = 0
.Weight = excel.XlBorderWeight.xlMedium
End With
With xlRange.Borders(excel.XlBordersIndex.xlEdgeBottom)
.LineStyle = excel.XlLineStyle.xlContinuous
.ColorIndex = 1 'black
.TintAndShade = 0
.Weight = excel.XlBorderWeight.xlMedium
End With
With xlRange.Borders(excel.XlBordersIndex.xlEdgeRight)
.LineStyle = excel.XlLineStyle.xlContinuous
.ColorIndex = 1 'black
.TintAndShade = 0
.Weight = excel.XlBorderWeight.xlMedium
End With
With xlRange.Borders(excel.XlBordersIndex.xlInsideVertical)
.LineStyle = excel.XlLineStyle.xlContinuous
.ColorIndex = 1 'black
.TintAndShade = 0
.Weight = excel.XlBorderWeight.xlThin
End With
With xlRange.Borders(excel.XlBordersIndex.xlInsideHorizontal)
.LineStyle = excel.XlLineStyle.xlContinuous
.ColorIndex = 1 'black
.TintAndShade = 0
.Weight = excel.XlBorderWeight.xlThin
End With
xlWorkBook.SaveAs(Filename:="C:\Users\Siddharth Rout\Desktop\Word1.xls", FileFormat:=56)
xlWorkBook.Close()
xlApp.Quit()
ReleaseObject(xlRange)
ReleaseObject(xlWorkSheet)
ReleaseObject(xlWorkBook)
ReleaseObject(xlApp)
End Sub
Private Sub ReleaseObject(ByVal obj As Object)
Try
Dim intRel As Integer = 0
Do
intRel = System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
Loop While intRel > 0
MsgBox("Final Released obj # " & intRel)
Catch ex As Exception
MsgBox("Error releasing object" & ex.ToString)
obj = Nothing
Finally
GC.Collect()
End Try
End Sub
回答by ppete3
None of the above recommendations worked for me until I followed @SiddharthRout's comment above. "As of today, what is the right way to work with COM objects?"
在我遵循@SiddharthRout 上面的评论之前,上述建议均不适合我。“截至今天,使用 COM 对象的正确方法是什么?”
It points out that com object references are kept alive under the debugger. A work-around is to call GC from the procedure that calls the com procedure. It worked for me.
它指出 com 对象引用在调试器下保持活动状态。解决方法是从调用 com 过程的过程中调用 GC。它对我有用。
Run GC from Finally in a TRY Catch block.
在 TRY Catch 块中从 finally 运行 GC。
copied from:post by "Govert" on what is the right way to work with COM objects?
复制自:post by "Govert" on what is the right way to work with COM objects?
using System;
using System.Runtime.InteropServices;
using Microsoft.Office.Interop.Excel;
namespace TestCsCom
{
Class Program
{
static void Main(string[] args)
{
// NOTE: Don't call Excel objects in here...
// Debugger would keep alive until end, preventing GC cleanup
// Call a separate function that talks to Excel
DoTheWork();
// Now let the GC clean up (repeat, until no more)
do
{
GC.Collect();
GC.WaitForPendingFinalizers();
}
while (Marshal.AreComObjectsAvailableForCleanup());
}
static void DoTheWork()
{
Application app = new Application();
Workbook book = app.Workbooks.Add();
Worksheet worksheet = book.Worksheets["Sheet1"];
app.Visible = true;
for (int i = 1; i <= 10; i++) {
worksheet.Cells.Range["A" + i].Value = "Hello";
}
book.Save();
book.Close();
app.Quit();
// NOTE: No calls the Marshal.ReleaseComObject() are ever needed
}
}
}
回答by Michael Edmison
I have used the ability to close a EXCEL Document in script many times along with hiding making visible and now closing if it's the only workbook open else close this worksheet. Here is my
我已经多次使用在脚本中关闭 EXCEL 文档的功能以及隐藏使其可见,如果它是唯一打开的工作簿,则现在关闭,否则关闭此工作表。这是我的
Sub ExitWorkBook()
Dim wb As Workbook
Dim c As Integer
c = 0
For Each wb In Application.Workbooks
c = c + 1
Next wb
If c = 1 Then
Application.Quit '--Quit this worksheet but keep excel open.
Else
Workbooks("(excel workbook name).xls").Close '-- Close Excel
End If
'
End Sub
回答by Jon
I had the same problem. However, the problem only persisted while debugging. All you should need to do is
我有同样的问题。但是,问题仅在调试时仍然存在。您需要做的就是
xlWorkBook.Close
xlApp.Quit
Then just let the code run. You may need to call the Garbage Collector after Button1_Click
is finished, but I didn't even need that. It seems to be that stepping through the code or not letting it completelyfinish throws things off and leaves Excel open.
然后让代码运行。完成后您可能需要调用垃圾收集器Button1_Click
,但我什至不需要那个。似乎是单步执行代码或不让它完全完成会抛出一些东西并使 Excel 保持打开状态。
回答by farope
I solved the problem using:
我使用以下方法解决了问题:
Set xlApp = Nothing
You can check monitoring TaskManager.
您可以检查监控TaskManager。
回答by farope
For Each w In Application.Workbooks
w.Save
Next w
Application.Quit
For Each w In Application.Workbooks
w.Save
Next w
Application.Quit
http://msdn.microsoft.com/en-us/library/office/ff839269.aspx
http://msdn.microsoft.com/en-us/library/office/ff839269.aspx
回答by user8233562
I found that every instance of a reference to an Excel object had to be explicitly released:
我发现对 Excel 对象的每个引用实例都必须显式释放:
xlApp = New Excel.Application
xlWorkBooks = xlApp.Workbooks
xlWorkBook = xlWorkBooks.Open(Me.txtFilePath.Text)
xlWorkSheets = xlWorkBook.Worksheets
xlWorkSheet = CType(xlWorkSheets(1), Excel.Worksheet)
xlWorkBook.Close()
xlWorkBooks.Close()
xlApp.Quit()
releaseObject(xlWorkSheet)
xlWorkSheet = Nothing
releaseObject(xlWorkSheets)
xlWorkSheets = Nothing
releaseObject(xlWorkBook)
xlWorkBook = Nothing
releaseObject(xlWorkBooks)
xlWorkBooks = Nothing
releaseObject(xlApp)
xlApp = Nothing
Private Sub releaseObject(ByVal obj As Object)
Try
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(obj)
obj = Nothing
Catch ex As Exception
obj = Nothing
Finally
GC.Collect()
End Try
End Sub
回答by hamid khp
I Use This Function After My Work and in The first of the XlApp Call , set the now() date to the FirstDate
我在工作后使用此函数,在 XlApp 调用的第一个中,将 now() 日期设置为 FirstDate
Private Sub End_Excel_App_After_Work(ByVal DateStart As Date, ByVal DateEnd As Date)
Dim xlp() As Process = Process.GetProcessesByName("EXCEL")
For Each Process As Process In xlp
If Process.StartTime >= DateStart Then
If Process.StartTime <= DateEnd Then
Process.Kill()
Exit For
End If
End If
Next
xlp = Process.GetProcessesByName("Microsoft EXCEL")
For Each Process As Process In xlp
If Process.StartTime >= DateStart Then
If Process.StartTime <= DateEnd Then
Process.Kill()
Exit For
End If
End If
Next
xlp = Process.GetProcessesByName("EXCEL.EXE")
For Each Process As Process In xlp
If Process.StartTime >= DateStart Then
If Process.StartTime <= DateEnd Then
Process.Kill()
Exit For
End If
End If
Next
End Sub
and After The Process Call this Function. somthing like this:
并在流程之后调用此函数。像这样的东西:
Dim FromDT As Date = Now
Dim xlApp As New Excel.Application
xlApp = New Excel.Application()
Dim xlWorkBook As Excel.Workbook
Dim xlWorkSheet As Excel.Worksheet
Microsoft.Office.Interop.Excel.Application()
'End Using
Try
xlWorkBook = xlApp.Workbooks.Open("d:\"FIle NAME".xlsX")
xlWorkSheet = xlWorkBook.Worksheets("WORKSHEET")
...CODE BE IN HERE
xlWorkBook.Close()
xlApp.Quit()
xlApp = Nothing
ReleaseObject(xlApp)
ReleaseObject(xlWorkBook)
ReleaseObject(xlWorkSheet)
End_Excel_App_After_Work(FromDT, Now)
Catch ex As Exception
xlApp.Application.Quit()
End_Excel_App_After_Work(FromDT, Now)
End Try
回答by Paul Smith
I have an issue with this code for releasing objects.
我对这段用于释放对象的代码有疑问。
Private Sub ReleaseObject(ByVal obj As Object)
Try
Dim intRel As Integer = 0
Do
intRel = System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
Loop While intRel > 0
MsgBox("Final Released obj # " & intRel)
Catch ex As Exception
MsgBox("Error releasing object" & ex.ToString)
obj = Nothing
Finally
GC.Collect()
End Try
End Sub
In the above sub, the object is being passed with ByValwhich passes a copyof the object you are trying to release. Kind of pointless. You should be passing ByRefwhich passes a reference (or a pointer to the object in memory for those familiar with C++) and then the above routine willrelease the memory being used by the object.
在上面的 sub 中,对象是通过ByVal传递的,它传递了您尝试释放的对象的副本。有点无意义。您应该传递ByRef,它传递一个引用(或者对于那些熟悉 C++ 的人来说是一个指向内存中对象的指针),然后上述例程将释放该对象正在使用的内存。
Paul
保罗
回答by meires
Please use this
请使用这个
Private Sub releaseObject(ByVal obj As Object)
Try
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
obj = Nothing
Catch ex As Exception
obj = Nothing
Finally
GC.Collect()
Try
'Dim MSExcelControl() As Process
Dim iID As Integer
Dim lastOpen As DateTime
Dim obj1(10) As Process
obj1 = Process.GetProcessesByName("EXCEL")
lastOpen = obj1(0).StartTime
For Each p As Process In obj1
If lastOpen < p.StartTime Then
iID = p.Id
Exit For
End If
Next
For Each p As Process In obj1
If p.Id = iID Then
p.Kill()
Exit For
End If
Next
Catch ex As Exception
End Try
End Try
End Sub