|
» myCSharp.de Diskussionsforum |
|
|
|
Autor
 |
|
cel
myCSharp.de-Mitglied
Dabei seit: 10.01.2007
Beiträge: 6
|
|
Bei der Erstellung einer Applikation, die mit EXCEL arbeitet stiess ich auf das Problem, dass sich EXCEL nicht sauber schliessen lässt. Die Artikel in diesem Forum waren recht hilfreich, die endgültige Lösung habe ich aber in dem grandiosen Artikel von Scott Rutherford gefunden. Die dort beschriebene Lösung ist in Visual Basic geschrieben und lässt sich eins zu eins auf C# übertragen:
Bei dem Versuch EXCEL wieder sauber zu schliessen tritt das Problem auf, dass man die Applikation zwar schliessen und beenden kann, der Hauptprozess aber im Hintergrund erhalten bleibt. Das frisst nicht nur Ressourcen, sondern blockiert unter Umständen auch (temporäre) Dateien, die man nicht löschen, ändern oder überschreiben kann.
Der typsiche Ausstieg sieht wohl ao aus:
C#-Code: |
excelWorkbook.Close(false, MISSING, MISSING);
excelApp.Application.Quit();
excelApp.Quit();
Marshal.ReleaseComObject(excelWorksheet);
Marshal.ReleaseComObject(excelWorkbook);
Marshal.ReleaseComObject(excelApp);
excelWorksheet = null;
excelWorkbook = null;
excelApp = null;
|
Das reicht aber nicht aus. Um EXCEL wirklich zu beenden, muss man den Prozess abschiessen!
Nun ist die Frage natürlich, wie kommt man den Prozess ran? Antwort: wir geben EXCEL bei der Initialisierung eine 'Markierung' mit:
C#-Code: |
string GuiId = System.Guid.NewGuid().ToString().ToUpper();
excelApp.Caption = GuiId;
|
Hierüber können wir später 'unser' - und nur unser - EXCEL Fenster wiederfinden:
C#-Code: |
IntPtr hWnd = FindWindow(null, GuiId);
|
.. und dann die Prozess-ID identifizieren:
C#-Code: |
int iProcID;
GetWindowThreadProcessId(hWnd, out iProcID);
|
Achtung:
C#-Code: |
GetWindowThreadProcessId
|
verlangt als 2. Argument eine Zeiger-Referenz auf eine
C#-Code: |
int
|
Variable. In C# muss daher unbedingt das
C#-Code: |
out
|
benutzt werden!
Mit der Prozess-ID kommen wir dann wieder sehr leicht an den EXCEL Prozess ran:
C#-Code: |
Process p = Process.GetProcessById((int)iProcID);
|
Und nun hat EXCEL endgültig verloren:
C#-Code: |
p.CloseMainWindow();
p.Refresh();
p.Kill();
|
Dann noch ein letzter Hinweis: um die oben genannten Funktionen
C#-Code: |
FindWindow
|
und
C#-Code: |
GetWindowThreadProcessId
|
benutzen zu können, müssen die vorab in der Klasse sauber deklariert werden:
C#-Code: |
[DllImport("user32")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", SetLastError = true)]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId);
|
Ich habe ein komplettes Beispiel angehängt. Wenn man das ausführt und den Task-Manager offen hat, kann man sehen, wie der EXCEL Prozess wieder verschwindet.
Dateianhang: |
XlsTest.zip (30 KB, 987 mal heruntergeladen) |
|
|
10.01.2007 16:27
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
|
Es kann nicht die Lösung sein, einfach den Prozess abzuschießen. Das ist absolut dreckig.
Wenn der Excel-Prozess sich nicht richtig beendet, stimmt was nicht. Du solltest lieber die Ursache finden und sie beheben, statt nur die Auswirkungen zu bekämpfen.
Vielleicht ist ein AddIn etc. geladen, welches Excel am beenden hindert?
Ich hatte dieses "Excel beendet sich nicht"-Problem noch nicht. Es muss also irgendwas an Deiner Umgebung nicht stimmen. Excel an sicht funktioniert und beendet auch korrekt (So meine Erfahrung!).
|
|
11.01.2007 11:20
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
cel
myCSharp.de-Mitglied
Dabei seit: 10.01.2007
Beiträge: 6
Themenstarter
|
|
Nein, dem ist nicht so. Spätestens wenn EXCEL mehrfach geöffnet wird, bleiben die Prozesse hängen, in der Regel aber schon nach einmaligem öffnen. Microsoft weist in den Foren selber auf diesen Bug hin. Es schliessen sich zwar alle Fenster, d.h. die Applikation ist vermeintlich nicht mehr da, aber im Task-Manager kann man den Prozess noch sehen.
|
|
11.01.2007 15:41
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
|
Bei mir hat sich Excel bis jetzt immer sauber geschlossen. Ich habe zu Hause allerdings nur Excel 2000. Tritt das erst bei neueren Versionen auf?
Was muss ich tun, um das zu simulieren?
Hat jemand von euch vielleicht einen Link auf die Microsoft-Foren, in denen das diskutiert wurde?
|
|
14.01.2007 12:59
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
Underscare
myCSharp.de-Mitglied
Dabei seit: 20.10.2006
Beiträge: 195
Entwicklungsumgebung: Visual Studio
|
|
Also ich kann dieses Problem nur bestätigen. Nutze Excel 2003 und greife über PIA's auf Excel zu.
Hier mal die Code-Stelle, an der ich Excel schliesse:
C#-Code: |
if (chkShowExcel.Checked)
{
excelApp.Visible = true;
}
else
{
excelWorkbook.Close(false,missing,missing);
excelApp.Application.Quit();
excelApp.Quit();
excelApp = null;
excelSheets = null;
excelWorkbook = null;
excelWorksheet = null;
GC.Collect();
GC.WaitForPendingFinalizers();
}
|
Auch bei mir bleibt der Prozess offen. Und ich hab keine Ahnung warum
Vielleicht könnte mir ja jemand beiläufig erklären, wofür das gemacht wird:
C#-Code: |
Marshal.ReleaseComObject(excelWorksheet);
Marshal.ReleaseComObject(excelWorkbook);
Marshal.ReleaseComObject(excelApp);
|
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Underscare am 21.01.2007 15:46.
|
|
21.01.2007 15:41
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
sheitman
myCSharp.de-Mitglied
Dabei seit: 02.11.2005
Beiträge: 1.047
|
|
Ich habe vor 2 Jahren mal ein COM-Addin für Word und Excel geschrieben und hatte nur am Anfang Probleme mit nicht wirklich geschlossenen Prozessen.
Nach ein wenig Nachforschung fand ich dann den Hinweis mit Marshal.ReleaseComObject, und seitdem hat ich das Problem nie wieder.
Auf irgendeiner Seite laß ich dann, dass man wirklich jedes Objekt was man direkt oder indirekt nutzt wieder freigeben soll... vielleicht macht ihr genau das nicht?
Direkt heißt dabei z.b.
C#-Code: |
Word.Application app = new Word.Application();
|
Indirekt wäre bei
C#-Code: |
Word.Document doc = app.Documents.Add(...);
|
das Documents Objekt.
Besser wäre also
C#-Code: |
Word.Documents docs = app.Documents;
Word.Document doc = docs.Add(...);
|
Dabei halt immer die Resourcen der Objekte wieder freigeben.
Ich fahr damit seht gut.
Zudem sind mir häufig schlechte Addins untergekommen die selbst wohl nicht ganz sauber programmiert sind und z.b. Word daran hintern die normal.dot am Ende ordentlich zu speichern... (gerade erst wieder durch Acrobat 7.0.0 gehabt, Update auf 7.0.5 hats behoben).
Den Prozess abzuschießen halte ich nicht für eine saubere Lösung. Aber müßt ihr selbst wissen ob ihr das verantworten könnt. Man weiß ja nie ob nicht doch mal ein wichtiges Dokument mit abgeschossen wird.
Zitat: |
Vielleicht könnte mir ja jemand beiläufig erklären, wofür das gemacht wird:
C#-Code: |
Marshal.ReleaseComObject(excelWorksheet);
Marshal.ReleaseComObject(excelWorkbook);
Marshal.ReleaseComObject(excelApp);
|
|
Allein durch diese Frage könnt ich dir fast sagen warum dein Programm Probleme hat Excel richtig zu schließen...
Wenn du Objekte von Excel oder Word benutzt, dann sind das COM-Objekte. Diese werden nicht durch den Garbage Collector verwaltet und müßen selbst frei gegeben werden. Das macht man mit der Methode Marshal.ReleaseComObject. Deien explizieten Aufrufe vom GC nutzen also nichts.
Gibst du die Objekte nicht frei wirst du höchstwahrscheinlich einen noch hängenden Prozess haben.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von sheitman am 22.01.2007 10:42.
|
|
22.01.2007 10:34
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
Underscare
myCSharp.de-Mitglied
Dabei seit: 20.10.2006
Beiträge: 195
Entwicklungsumgebung: Visual Studio
|
|
Also, ersmal vielen Dank für deine Erklärung sheitman. Meine "Beendungs-Prozedur" von Excel sieht nun folgender Maßen aus:
C#-Code: |
excelWorkbook.Close(false,missing,missing);
excelApp.Application.Quit();
excelApp.Quit();
Marshal.ReleaseComObject(excelSheets);
Marshal.ReleaseComObject(excelWorksheet);
Marshal.ReleaseComObject(excelWorkbook);
Marshal.ReleaseComObject(excelApp);
|
Jetzt sieht es folgender Maßen aus. Der Excel Prozess bleibt solange aktiv (also im TaskManager sichtbar) bis ich mein Programm BEENDE. (Das Programm lief in VS). Also Excel wird erst geschlossen, wenn ich mein Programm schliesse. Weiß jemand vielleicht warum?
Muss ich vielleicht auch meine ganzen Ranges (mit denen ich die Excel Zellen anspreche) nullen oder freigeben? Sind ja an sich ganz normale Variablen oder sind es auch solche COM Objekte?
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Underscare am 22.01.2007 18:18.
|
|
22.01.2007 18:16
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
|
Ja das sind auch COM-Objekte. Die solltest Du auch freigeben, wenn sie klassenweit deklariert sind.
Ich bleibe dabei. Wenn sich Excel nicht richtig schließt, hat man was falsch gemacht.
|
|
22.01.2007 19:07
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
Underscare
myCSharp.de-Mitglied
Dabei seit: 20.10.2006
Beiträge: 195
Entwicklungsumgebung: Visual Studio
|
|
Puuh, ey ich hab voll viele Ranges in meinem Programm (sind auch extrem viele verschiedene Daten, die mein Programm an Excel schickt)....So 50 -60 Ranges dürften das sein....glaub da wärs einfacher, den Prozess einfach abzuknallen^^
//edit:
Bin das Prog grad nochma durchgegange und hab mir selbst im Arsch getreten...Ich voll Idiot hab bei vielen Sachen jedes Mal ne neue Range Variable erstellt, wobei ich die alte hätte nutzen können...hab jetzt so 10 mal mehr Ranges als ich bräuchte^^....Muss ich ma wenn ich Zeit hab verbessern....
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Underscare am 22.01.2007 22:21.
|
|
22.01.2007 19:19
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
sheitman
myCSharp.de-Mitglied
Dabei seit: 02.11.2005
Beiträge: 1.047
|
|
Zitat: |
Nun aber zum Thema, ich selbst verwende Office 2007 Beta und bei der Version wird Excel nicht korrekt geschlossen wenn vor dem Close und dem ReleaseComObject eine Exception geschmissen wird.
Vielleicht ist dass ja mal ein Ansatz, ansonsten wenn der Code keine Exception auslöst, schließt sich Excel normal, das kann ich von Version 2000, 2003 und 2007 sagen. |
würde ich übrigens fast auch meine hand für ins feuer legen das es hier am fehlenden Marshal.ReleaseComObject liegt...
hast du alles was du mit excel machst in einen try... catch... finally bzw try... finally ... eingebetten? im finally müßte dann das Marshall.ReleaseComObject rein...
würde also so aussehen
C#-Code: |
Word.Documents oDocs = null;
Word.Document oDoc = null;
try {
oDocs = oWord.Documents;
oDoc = oDocs.Add(...);
...
} catch (SomeException e) {
...
} finally {
if(oDocs!=null) {
Marshall.ReleaseComObject(oDocs);
}
if(oDoc!=null) {
Marshall.ReleaseComObject(oDoc);
}
}
|
wobei es sich schon fast lohnt den ReleaseComObject - code in eine neue methode auszulagern, der auch auf null vorher überprüft^^
jedenfalls ne menge schreibarbeit... aber damit hab ich jedenfalls nie probleme... solange mir kein anderes addin mein word zerschießt^^
Zitat: |
Muss ich vielleicht auch meine ganzen Ranges (mit denen ich die Excel Zellen anspreche) nullen oder freigeben? Sind ja an sich ganz normale Variablen oder sind es auch solche COM Objekte? |
jedes objekt einer klasse aus dem word, excel oder office namespace dürfte i.d.r. ein com object sein...
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von sheitman am 23.01.2007 09:58.
|
|
23.01.2007 09:54
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
Zwischen diesen beiden Beiträgen liegt mehr als ein Monat. |
Sirox
myCSharp.de-Mitglied
Dabei seit: 04.12.2006
Beiträge: 64
|
|
Hi , ich war an dem gleichen Problem ich hätte da nur eine Andere Lösungsart ( ich hab aber von oben gespickt 
) aber die PInvokes haben mir nicht so gefallen also :
C#-Code: |
Excel.Application xlApp = new Excel.Application();
xlApp.Caption = xlGuid;
xlApp.Visible = false;
xlApp.WindowState = Excel.XlWindowState.xlMinimized;
xlApp.Visible = true;
foreach (System.Diagnostics.Process procI in System.Diagnostics.Process.GetProcessesByName("EXCEL")){
if (procI.MainWindowTitle.IndexOf(xlGuid) != -1) {
procI.CloseMainWindow();
procI.Refresh();
procI.Kill();
}
}
|
So spart man sich den PInvoke
lG
Sirox
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von Sirox am 05.03.2007 15:07.
|
|
05.03.2007 15:05
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
sheitman
myCSharp.de-Mitglied
Dabei seit: 02.11.2005
Beiträge: 1.047
|
|
wie oben schon geschrieben war ists nicht besonders gut einfach so den prozess zu killn.letzlich verdeckt man damit nur das man selbst das problem nicht anders in den griff bekommen hat.
falsl du mal ein com-addin entwickelst stehst du eh wieder vor dem selben problem. und da kannst du wirklich nicht einfach den prozess abschießen... und unsaubere addins sind oft das quell so manch einen übels^^
|
|
05.03.2007 15:47
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
rokohl
myCSharp.de-Mitglied
Dabei seit: 07.11.2006
Beiträge: 39
|
|
hi,
ich habe mich auch eine zeitlang mit diesem problem beschäftigt und bin zu dem schluss gekommen das es ein garbage-collector problem ist.
wenn man extrem sauber und garbage collector "freundlich" programmiert so das er
alle verwendeten variablen problemlos löschen kann, geht auch excel zu. vergisst man aber eine variable in der funktion auf null zu setzten oder noch schlimmer ein dipose aufruf eines erstellten objektes, geht excel erst beim beenden des programmes zu. :-(
anbei ein kleines beispiel progi was bei mir excel wieder zumacht. setzt man aber eine von den variablen am ende nicht null geht excel nicht zu.
C#-Code: |
Excel.ApplicationClass app = null;
Excel.Workbook workBook = null;
Excel.Worksheet workSheet = null;
Excel.Range range = null;
app = new Excel.ApplicationClass();
workBook = app.Workbooks.Open(@"test.xls",
0,
true,
5,
"",
"",
true,
Excel.XlPlatform.xlWindows,
"\t",
false,
false,
0,
true,
Missing.Value,
Missing.Value
);
if (null != workBook.ActiveSheet)
{
workSheet = (Excel.Worksheet)workBook.ActiveSheet;
range = (Excel.Range)workSheet.Cells[1, 1];
}
workBook.Close(false, Missing.Value, Missing.Value);
app.Application.Quit();
app.Quit();
Marshal.ReleaseComObject(range);
Marshal.ReleaseComObject(workSheet);
Marshal.ReleaseComObject(workBook);
Marshal.ReleaseComObject(app);
range = null;
workSheet = null;
workBook = null;
app = null;
GC.Collect();
MessageBox.Show("done");
|
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von rokohl am 06.03.2007 11:37.
|
|
06.03.2007 11:34
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
rokohl
myCSharp.de-Mitglied
Dabei seit: 07.11.2006
Beiträge: 39
|
|
Nachsatz:
als ich meine function dazu bringen wollte excel nach beendigung wierder zu schließen bin ich übrigens an der function xdoc.CreateElement gescheitert.
was auch wieder auf den gc deutet!
|
|
06.03.2007 11:43
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
Programmierhans
myCSharp.de-Poweruser/ Experte
Dabei seit: 05.04.2005
Beiträge: 4.221
Entwicklungsumgebung: VS2003-VS2013 / SAP WebIDE Herkunft: Zentralschweiz
|
|
ReleaseComObject liefert doch einen int zurück welcher anzeigt wie oft das Objekt noch referenziert ist...
Wenn ein call von ReleaseComObject einen Wert > 0 zurückliefert, dann ist eine Instanz (Com-mässig) nicht freigegeben... ergo kann Excel nicht geschlossen werden.
Nachtrag:
Seit Version 2.0 bietet sich hierführ an:
FinalReleaseComObject
|
|
06.03.2007 16:36
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
rokohl
myCSharp.de-Mitglied
Dabei seit: 07.11.2006
Beiträge: 39
|
|
mhmmm ich würd aber gerne mal wissen wieso er in meinem beispiel bei
Marshal.ReleaseComObject(workSheet) keine null zurück gibt.
ich sehe da keine referenz ???
|
|
06.03.2007 18:56
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
Programmierhans
myCSharp.de-Poweruser/ Experte
Dabei seit: 05.04.2005
Beiträge: 4.221
Entwicklungsumgebung: VS2003-VS2013 / SAP WebIDE Herkunft: Zentralschweiz
|
|
Zitat: |
Original von rokohl
ich sehe da keine referenz ??? |
C#-Code: |
if (null != workBook.ActiveSheet)
{
workSheet = (Excel.Worksheet)workBook.ActiveSheet;
|
Somit zählt er vermutlich auf 2 rauf...
Und du releast nur 1
probier es mal so:
C#-Code: |
workSheet = (Excel.Worksheet)workBook.ActiveSheet;
if (workSheet!=null)
.
..
|
|
|
06.03.2007 20:59
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
rokohl
myCSharp.de-Mitglied
Dabei seit: 07.11.2006
Beiträge: 39
|
|
du hast recht. das zählt er als ref.
mhm...aber ich verstehe das immer noch nicht 100%ig.
ich hatte den fall das es an einem xdoc.CreateElement aufruf lag den ich zwischen den excel befehlen verwendet hatte. ohne ihn lief es - mit ihm hat er excel nicht zu gemacht. obwohl da nix von excel verwendet wurde sondern nur xml krams.
desweiteren is an meinem beispiel interessant das es excel auch zu macht wenn man alles am ende auf null setzt. heißt das das ReleaseComObject automatisch aufgerufen wird? das würde ja bedeuten das man ReleaseComObject garnicht aufrufen muss.
naja egal, aber komisch ist das schon...
danke nochmal
|
|
07.03.2007 09:25
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
Zwischen diesen beiden Beiträgen liegen mehr als 5 Monate. |
|
*aufweck*
Hab auch ein Problem mit dem Schließen von Excel.
Meine Methode sieht so aus (bitte nicht den Sinn hinterfragen...):
C#-Code: |
private void ReSaveExcelFile(string filename)
{
Excel.Application excelApp = new Microsoft.Office.Interop.Excel.ApplicationClass();
Excel.Workbook wb = null;
try
{
wb = excelApp.Workbooks.Open(filename, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
wb.SaveAs(filename,Excel.XlFileFormat.xlExcel7,
Type.Missing,Type.Missing,Type.Missing,Type.Missing, Excel.XlSaveAsAccessMode.xlNoChange,
Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing);
}
catch (Exception ex)
{
MessageBox.Show("Fehler beim Speichern der Datei '" + filename + "': " + ex.Message,
this.messageBoxCaption, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
wb.Close(Type.Missing, Type.Missing, Type.Missing);
excelApp.Application.Quit();
excelApp.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(excelApp);
System.Runtime.InteropServices.Marshal.ReleaseComObject(wb);
wb = null;
excelApp = null;
}
}
|
Obwohl ich mMn alles richtig geschlossen und freigegeben habe, bleibt der Excel-Prozess bis ich meine Anwendung geschlossen habe offen.
Warum?
thx for hints
|
|
05.09.2007 09:47
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
|
Moin,
Ursache:
C#-Code: |
wb = excelApp.Workbooks.Open([...]);
excelApp.Application.Quit();
|
also lieber so
C#-Code: |
Excel.Workbooks wbs = excelApp.Workbooks;
wb = wbs.Open([...]);
Excel.Application app = excelApp.Application;
app.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(wbs);
System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
|
wobei
C#-Code: |
excelApp.Application == excelApp
|
Warum nutzt du nicht System.IO.File.Copy
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von él toro am 05.09.2007 10:37.
|
|
05.09.2007 10:32
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
|
Zitat: |
Original von él toro
Warum nutzt du nicht System.IO.File.Copy
|
Ich hab doch gesagt nicht hinterfragen ;-)
Die Funktion soll eine Excel-Datei unter einer anderen Excel-Version speichern, da ich von einer anderen Anwendung eine Datei im Excel 3.0-Format erhalte und das zur Weiterverarbeitung nicht geeignet ist...
@tipp:
funktioniert, danke!
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Pendi am 05.09.2007 10:47.
|
|
05.09.2007 10:47
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
Zwischen diesen beiden Beiträgen liegt mehr als ein Jahr. |
red_dragon69
myCSharp.de-Mitglied
Dabei seit: 12.08.2009
Beiträge: 56
Entwicklungsumgebung: VisualStudio 2008, 2010
|
|
Hallo Leute.
Jetzt muss ich einen alten Beitrag wieder aufwärmen, weils bei mir einfach nicht hinhaut.
Der Prozess "Excel.exe" wird einfach nicht beendet.
Weis jemand an was das liegen könnte? Benutze Vista Enterprise und Office 2007.
Folgend noch mein code:
C#-Code: |
private void button1_Click(object sender, EventArgs e)
{
object missing = Type.Missing;
string PosX, PosY;
int i;
Excel.Application excelApp = new Excel.Application();
Excel.Workbook workbook = excelApp.Workbooks.Open(Dateipfad() + @"\File.xml", missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing);
Excel.Worksheet worksheet = (Excel.Worksheet)workbook.Worksheets["wks-Name"];
excelApp.Visible = true;
string beginCell = "A" + worksheet.Rows.Count;
string endCell = "AA" + worksheet.Rows.Count;
int row = worksheet.get_Range(beginCell, endCell).get_End(Excel.XlDirection.xlUp).Row;
for (i = 2; i <= row; i++)
{
Excel.Range Xrng = worksheet.get_Range("A"+i, "F"+i);
Excel.Range Yrng = worksheet.get_Range("P"+i, "S"+i);
PosX = (string)Xrng.get_Value(missing);
PosY = (string)Yrng.get_Value(missing);
StreamWriter Writer = new StreamWriter(Dateipfad() + ".txt", false, Encoding.Default);
Writer.WriteLine("TextTextText");
Writer.Close();
}
workbook.Close(false, missing, missing);
excelApp.Application.Quit();
excelApp.Quit();
Marshal.FinalReleaseComObject(worksheet);
Marshal.FinalReleaseComObject(workbook);
Marshal.FinalReleaseComObject(excelApp);
PosX = null;
PosY = null;
worksheet = null;
workbook = null;
excelApp = null;
}
|
Gruß
Red_Dragon69
|
|
27.08.2009 09:17
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
Programmierhans
myCSharp.de-Poweruser/ Experte
Dabei seit: 05.04.2005
Beiträge: 4.221
Entwicklungsumgebung: VS2003-VS2013 / SAP WebIDE Herkunft: Zentralschweiz
|
|
el toro hat in seinem Beitrag aufgezeigt wo Fehler gemacht wurden.
Du machst genau dieselben Fehler... findest allerdings diesen Thread....
Hast Du den Beitrag auch mal ernsthaft durchgelesen ??? eher nicht, sonst hättest Du den Fehler ja gefunden ...
--> Lies nochmals alles durch ... bin überzeugt dass Du den Fehler selber findest.
Gruss
Programmierhans
|
|
27.08.2009 17:38
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
Zwischen diesen beiden Beiträgen liegt mehr als ein Monat. |
Tschebbe
myCSharp.de-Mitglied
Dabei seit: 22.09.2009
Beiträge: 34
Herkunft: BW - Kaiserstuhl
|
|
Also ich schliess mich mal Rainbird an. Hab alles sauber zugemacht und Excel wird geschlossen.
gute und hilfreiche Diskussion hier.
|
|
05.10.2009 19:45
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
Zwischen diesen beiden Beiträgen liegt mehr als ein Monat. |
Gabe
myCSharp.de-Mitglied
Dabei seit: 03.11.2009
Beiträge: 22
|
|
Kurze Ergänzung für die Suchmaschinen:
Das Schließen von offenen Word- und Visio-Dateien funktioniert genauso...
Super Thread. Ist der nicht schon was für die FAQs?
Gruß Gabe
|
|
27.11.2009 14:12
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
Zwischen diesen beiden Beiträgen liegt mehr als ein Jahr. |
|
Hallo,
ich habe mich nun auch länger mit dem Thema beschäftigen müssen, aber leider komme ich an einem Punkt nicht weiter
C#-Code: |
try
{
oExcel = new Excel.Application();
oExcel.ScreenUpdating = true;
oExcelWorkbooks = oExcel.Workbooks;
oExcelWorkbook = oExcelWorkbooks.Add(System.Reflection.Missing.Value);
oExcelWorkSheet = oExcelWorkbook.ActiveSheet;
oExcelWorkSheet.Name = x_dateiname.ToString().Trim();
oExcelWorkSheet.Cells[1, 1] = "test";
oExcelWorkbook.Close(true, auswertung_speichern_unter.FileName, System.Reflection.Missing.Value);
}
catch (Exception ex)
{
Fehlermeldung.ErrorMessage(ex, "( --> Datei geöffnet ??? <-- )");
vorgang_fortsetzen = false;
}
finally
{
if (oExcel != null)
{
oExcel.Quit();
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(oExcelWorkSheet);
oExcelWorkSheet = null;
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(oExcelWorkbook);
oExcelWorkbook = null;
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(oExcelWorkbooks);
oExcelWorkbooks = null;
System.Runtime.InteropServices.Marshal.FinalRelease(oExcel);
oExcel = null;
}
}
|
kommentiere ich die Zeile "oExcelWorkSheet.Cells[1, 1] = "test";" aus, funktioniert alles so wie es soll, u. es wird Excel im TaskManager geschlossen
da es wohl für Cells kein Comobjekt gibt (zumindest habe ich keins gefunden...)
habe ich es dann mit Hilfe von Range versucht :
C#-Code: |
Excel.Range x_celle = (Excel.Range)oExcelWorkSheet.Cells[1, 1];
x_celle.Value2 = "test";
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(x_celle);
|
aber auch dann wird Excel nicht mehr im TaskManager geschlossen
Wenn ich die entsprechenden Release-Befehle im Direktfenster eingebe, bekomme ich immer "0" zurück, was nach den obigen Ausführungen ja bedeutet, das alle Objekte geschlossen sind ...
Was sehe ich hier nicht / mache ich immer noch falsch ?
Bin für jede Hilfe dankbar ...
MfG ChrisProrg
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von ChrisProg am 11.03.2020 14:15.
|
|
11.03.2020 13:04
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
|
|