Problem mit process.start
-
An der geöffneten Datei wird nichts geändert, sie soll nur angesehen werden.
Ich sterte mein Programm nur 1x. Welche Instanzen meinst du?
Das Ziel des Programmes ist es, das man im c# Prog anklickt welche Excelfiles man ansehen will und diese dann in der richtigen Reihenfolge (zuerst die alten Daten, dann die Neuen, dann die Diagramme usw.) gestarten werden.
Und zwar möglichst ohne Schreibgeschützt Meldung und eben in der richtigen Reihenfolge.
-
starchild schrieb:
"einen anderen Benutzer" bereits geöffnet
Kommt meistenz wenn zuvor schon ein Programm File-Handles auf diese Dateien hat!
Kann es vielleicht sein das Du z.B. für diese Dateien FileStream-Objekte die vom Scope her Public,private etc. sind noch zur Programmlaufzeit noch hälst?
Und das Du obwohl das diese Streams noch nicht abgebaut sind Du versuchst diese Dateien mit Excel aus dem Programm zu öffnen.Dann wäre es klar 2 Progrmme wollen sich eine Datei teilen!
Dein C#-Programm hat schon die Datei und will es oder muss es mit Excel teilen.
Gruss Sclearscreen
-
starchild schrieb:
"einen anderen Benutzer" bereits geöffnet .... und schließe mein Programm, meldet Excel, das die Datei freigegeben wurde.
Dein Programm bunkert bestimmt in irgendwelchen Arrays,Collections,Variablen
die innerhalb der Klasse public,private,protected sind
Streams,Filehandles die Du wahrscheinlich bei der Dateisuche beim Auflisten erzeugst.bevor Du über Process.Start (Excel mit Datei starten) loslegst muss sichergestellt werden
das diese Objekte wenn sie in Arraylisten,Collections sind per Clear glöscht werden, oder das jedes einzelne perDispose
oder Zuweisung null freigegeben werdensuch und guckmal genau in Deinem C#-Programm nach es ist bestimmt so.
In Deiner Aussage siehe wo ich Dich zitiere bestätigst Du meine Vermutung.
Demnach hält Dein Programm was Excel mit dieen Dateien per Start versorgt
über irgendlweche Objekte göffnete Streams auf diese Dateien.Gruss sclearscreen
P.S.: Ich habe im Netz mal ein Nützliches Tool gefunden
das kann anzeigen von welchen Programm eine Datei genutzt wird!
nennt sich UnLocker weil man kann damit Dateien auch entsperren.
D.h. Programme mit Gewalt von Ihren Ressourcen trennen.http://unlocker.softonic.de/ie/40696
Du könntest Dein C#-Programm starten und dann damit auf eine Excel-Datei gehen
wo Du selbst weisst die ist 100% mit im Boot und wird von meinem Programm aufgelistet. Genau die überprüfst Du mit dem Tool. Weil das Ding zeigt ja an von welchen Prozessen eine Datei benutzt wird.Da hätten Wir dann auf jeden Fall genau Aufschluss!
-
Also ich lese ein Verzeichnis mit folgendem Code ein und schreibe die Dateinamen in ein globales Stringarray filename[]
Excel meckert aber immer noch, das die Datei benützt wird.private void OpenFiles_Click(object sender, System.EventArgs e) { FileInfo[] filelist={null}; if (openFileDialog1.ShowDialog() != System.Windows.Forms.DialogResult.OK) return; string Dir = openFileDialog1.FileName; Dir = Dir.Substring(0, Dir.LastIndexOf("\\")); FilenameOutput.Text = Dir; DirectoryInfo di = new DirectoryInfo(Dir); filelist = di.GetFiles(); //"*.DAT" anzFiles = filelist.Length; for (int i = 0; i < anzFiles; i++) filename[i] = filelist[i].Name; }
-
ja ich sehe dabei auch nicht wo es klemmen kann. Du erinnerst Dich Doch noch an das Tool? Was ich Dir ans Herz gelegt habe.
Hmm das Programm wenn ich mich zurückerinnere schreibst Du ja im Labor Deiner UNI.
Müsstes gegebenenfalls mal Deinem Laborguru den Link von dem Tool geben das der mal abcheckt ds es harmlos ist. Es kann Dir sagen von welchen Programm eine Datei blockiert wird. Oder zeihst es Dir auf einen Rechner von einem Kumpel der das .NET SDK 1.1 auf seinem Kasten hat.
Wirklich es würde Dir schneller zur Gewissheit verschaffen welches Programm der Übeltäter ist.
FileInfo
DirectoryInfomachen nur temporären kurzeitigen Zugriff auf Dateien und Verzeichnise wenn man deren, ich nenne sie mal, Servicmethoden aufruft bzw. nutzen diese dann intern bestimmt FileStream. Dieses Objekt kennt auch den Modus FileShare.
Anderes wäre es halt wenn Du einen Stream auf eine Datei setzt, einmal sein Open aufrufst und solange das Programm läuft kein Close mehr machst.
Ja dann hat ich Dir sagen können ja guck Dir mal diese Stelle an.Aber in deinem Code-Auszug ist von sowas nix zu sehen.
Mein Rat also:
Mach vorab zu Deinem Softwarsystem eine Liste welche Applikation[en]
auf diese .xls-Files Zugreifen müsen, könnten und dürfen!
Bring das Softwaresystem in Gang!
Lass die Fehlermeldunge von Excel offen. Nimm jetzt besagtes Tool von dem ich sprach. Wechsele in den Ordner per Arbeitsplatz geh mit Rechtsklick auf die
.xls-Files wähle aus dem Kontextmenü (was im Kontextmenü einen Eintrag hat)
"Unlocker" aus dann siehst Du wirklich aus welcher Programminstanz der Zugriff
auf die .xls-Datei erfolgt.
Voraussetzung Du hast Dir den "Unlocker" installiert.
-
Es ist eindeutig meine c# Anwendung, die auf das Excelfile zugreift.
Wen ich beim in Excel erscheinenden Dialog aus "Benachrichtigen" klicke und mien Programm schließe, meldet Excel, das die Datei freigegeben wurde und bietet an, sie zum schreiben zu öffnen.
Programme installieren ist leider nicht so einfach. (sehr restriktive Richtlinien)
-
haha was mir jetzt einfiel habe ja Excel hier bei mir am start
Excel kann man ja doppel und dreifach vierfach aufmachen
es tummeln sich dan mehrer Excel-Tasks daran kann es auch liegenEine Excel hat Deine Datei
Du klickst wie wild auf Excel und die eine Excel-Instanz regt sich dann
auf das noch andere Excel-Brüder/Schwestern/Verwandte/Erbschleicher auftauchen
die auch anspruch auf diese Dateien erheben! Wobei mir unbekannt ist ob Excel vor der Öffnung immer eine Kopie macht. Ich bin ja schliesslich kein Excel-Entwickler.Du musst also vorher abchecken durch Code ob schon Excel läuft und ob das Excelinstanzen sind die schon Datei nutzen die in deiner Liste sind!
Lösungsmöglichkeit Office-Automation auch bekannt unter Interoperabolität.
Der Namensraum System.Diagnostics sollte hier auch wieder brauchbare Sachen dazu beisteuern können!
-
starchild schrieb:
Es ist eindeutig meine c# Anwendung, die auf das Excelfile zugreift.
Wen ich beim in Excel erscheinenden Dialog aus "Benachrichtigen" klicke und mien Programm schließe, meldet Excel, das die Datei freigegeben wurde und bietet an, sie zum schreiben zu öffnen.
Programme installieren ist leider nicht so einfach. (sehr restriktive Richtlinien)Kann es sein da Excel auch mit .csv-Dateien arbeiten Tut das Du in Deiner IDE
jedesmal wenn Du es öffnest auch eine solche Datei mit aufmachst.
-
Wo zeigst Du eigentlich die geordneten Datein in deiner C#-Anwendung an?
In einer ListBox um sie von da per Klick zu staretn was dann über
Process.Start läuft.
-
Das Problem folgendermassen aus ..... wenn Du diese Dateien jedesmal wenn Du eine Datei aus der ListBox wählst müsste wenn Du daraufihn im SelectItem-Delegaten
der Listbox mit den .xls-Files, aufrufst. Innerhalb dieser DelegatenCallbackMethode rufst du dann bestimmtProcess.Start(SeletedItem.....); immer ein extra Excel-Instanz auf!
Wenn Du an der Stelle in der ListBox 2mal dieselbe Datei aufmachst,
Hast Du aus Deiner C#-Anwendung heraus einen Neuen Excel-Nachkommen erstellt
der auf die gleiche xls-Datei zugreift wie ein Excel-Vorfahre schon zuvor!Lösung dafür anders machen per Automation/Interoperabilität:
Eine Excel-Instanz wird hierbei von deiner C# anwendung kontrolliert.
Aus C# heraus kannst Du dieser einen Excel-Marionette sagen öffne diese Datei tue das usw.. Du kommst damit vom Process.Start-Ansatz weg, der unter Umstaänden für mehrfaczugriffe auf .xls-Files sorgt.
-
Ich verwende folgenden Code zum auswählen und Starten.
Umgehe ich testweise die Listbox, indem ich Process.Start direkt einen String übergebe, wird die Datei ohne meckern geöffnet.
Es liegt also tatsächlich an der Listbox Komponente.
Gibt es eine Alternative?private void Open_Click(object sender, System.EventArgs e) { string item = listBox1.Items[listBox1.SelectedIndex].ToString(); string filepath = @filename[int.Parse(item.Substring(10, item.IndexOf(":")-10))-1]; string excelpath = @PathToExcel.Text; Process.Start(excelpath, filepath); }
-
starchild schrieb:
Gibt es eine Alternative?
Die hatte ich in meiner Antwort vor Deiner Antwort ja schon angedeutet!
Process.Start in Deinem Anwendungskontext weglassen.Office-Automation verwwenden genauer Excel-Automation Stichwort Interoperabilität verwenden.
Deine C#-Anwendung macht damit eine Excel-Instanz zu Ihrer Marionette.
Ist eine ganz legale Technik die von Microsoft mit Werbung für .NET propagiert wird.Damit sagts Du zur marionette lade die Datei mache mit der datei das .....
usw. und sofort.Wie bei Process-Start kannst du darüber eine Excel-Instanz starten
als auch versuchen eine laufende Excel-Instanz über dein C#-Programm
zur Marionette zu machen.
-
Selbst der Mozilla-Browser lässt sich fernsteuern, diese Interoperabilität
ist mein persöhnlicher Kracher/Favorit/C#-Droge/Abhängigkeit. Und ein Argument warum ich mich C#
abgebe. Naja ich will mal nicht übertreiben sonst kommt noch jemand mit einer weissen Jacke.... *lach*Aber ich findes es eine super Sache.
-
Eigendlich hätte ich ja nur die Datei einfach öffnen wollen...
Aber so werde ich mir das ganze Automatisationszeug nur mal ansehen müssen.
Danke für die Hilfe!
-
starchild schrieb:
Eigendlich hätte ich ja nur die Datei einfach öffnen wollen...
Aber so werde ich mir das ganze Automatisationszeug nur mal ansehen müssen.
Danke für die Hilfe!Was willst Du machen wenn Excel so gestrickt ist und pro ein Process.Start
eine extra Excel-Instanz/Task aufmacht.
-
hier ich bekomme zwar bei einem direkten using Excel einen Fehler
"Appliction mehrdeutig"
aber habe ich umgangen bei meinem .NET 1.1 bekomme ich excel über C# so Excel (als Marionette eines C#-Prog.) an den Start
using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; using DasExcel = Excel; // ein using Excel; führt zu einem mehrdeutigen Vereiss bei mir dann eben so namespace ImagesInAssembly { /// <summary> /// Zusammenfassung für Form1. /// </summary> public class Form1 : System.Windows.Forms.Form { /// <summary> /// Erforderliche Designervariable. /// </summary> private System.ComponentModel.Container components = null; DasExcel.ApplicationClass excelApp = null; public Form1() { // // Erforderlich für die Windows Form-Designerunterstützung // InitializeComponent(); // // TODO: Fügen Sie den Konstruktorcode nach dem Aufruf von InitializeComponent hinzu // excelApp = new Excel.ApplicationClass(); excelApp.Visible = true; }
funktioniert nat. nur wenn Du einen verwies auf ein COM-Assembly in den Projekt bringst
"Microsoft Excel Object Library 10.0" oder so heisst das
jo und dann starte dei C#-Applikation und es macht eine Marionette von Excel auf jo es funzt toll
-
funktioniert bei mir beides
eine schon laufende Excelinstanz zur Marionette machen
wenn noch kein Excel im System rumkraucht eben eine Marionette selbst aufmachen!using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Runtime.InteropServices; using System.Data; using DasExcel = Excel; namespace ImagesInAssembly { /// <summary> /// Zusammenfassung für Form1. /// </summary> public class Form1 : System.Windows.Forms.Form { /// <summary> /// Erforderliche Designervariable. /// </summary> private System.ComponentModel.Container components = null; private DasExcel.Application excelApp = null; public Form1() { // // Erforderlich für die Windows Form-Designerunterstützung // InitializeComponent(); // // TODO: Fügen Sie den Konstruktorcode nach dem Aufruf von InitializeComponent hinzu // // Versuch eine vielleicht schon laufende Excel-Instanz zur Marionette zu machen try { object oApp = Marshal.GetActiveObject("Excel.Application"); excelApp = (Excel.Application) oApp; } catch{} if(excelApp == null) // kein laufendes Excel gefunden { // Marionette selbst aufmachen excelApp = new Excel.ApplicationClass(); excelApp.Visible = true; } } ..
-
// Excel-Interopmarionette // Projekktverweis auf "Microsoft Excel 10.0 Object Library" machen // using-Klausel machen // using DasExcel = Excel; // da man sonst zumindest bei mir Mehrdeutigkeitsverweis bekommt auf 'Application' // ich benutz .NET 1.1 private DasExcel.Application excelApp = null; private void ExcelInteropRemote() { // Versuch eine vielleicht schon laufende Excel-Instanz zur Marionette zu machen // bedarf Verweis auf Excel-COM-Library und eines using aber nur so bei mir in .NET 1.1 // using DasExcel = Excel; // ansonsten wird Application ein mehrdeutiger Verweis try { object oApp = Marshal.GetActiveObject("Excel.Application"); excelApp = (Excel.Application) oApp; } catch{} if(excelApp == null) // kein laufendes Excel gefunden { // Marionette selbst aufmachen excelApp = new Excel.ApplicationClass(); excelApp.Visible = true; } }
barauchst jetzt nurnoch im Load deiner Form oder Ctor
son Aufruf zu tunExcelInteropRemote();
-
eine Xls-File zu öffnen geschied dann über die Methode _Open
gesetzt dem Fall deine ExcelApplikationsVariable lautet so wie in meier Methode
in der vorherigen Antwort von mir kommt bei dir
dann im ListBox-Click so was:if(excelApp != null) excelApp.Application.Workbooks._Open(listBox.items[listbox1.SelectedIndex].ToString(),.....);
So jetzt will ich aber mal an meinem eigene Kram weiterbasteln
-
Hier das sollte noch aufschlussreicher fuer Dich sein
// Excel-Interopmarionette // Projekktverweis auf "Microsoft Excel 10.0 Object Library" machen // using-Klausel machen // using DasExcel = Excel; // da man sonst zumindest bei mir Mehrdeutigkeitsverweis bekommt auf 'Application' // ich benutz .NET 1.1 DasExcel.Application excelApp = null; private void ExcelInteropRemote() { // Versuch eine vielleicht schon laufende Excel-Instanz zur Marionette zu machen // bedarf Verweis auf Excel-COM-Library und eines using aber nur so bei mir in .NET 1.1 // using DasExcel = Excel; // ansonsten wird Application ein mehrdeutiger Verweis try { object oApp = Marshal.GetActiveObject("Excel.Application"); excelApp = (Excel.Application) oApp; excelApp.Visible = true; } catch { // Marionette selbst aufmachen excelApp = new Excel.ApplicationClass(); excelApp.Visible = true; } } private void button2_Click(object sender, System.EventArgs e) { // "Missing.Value" durch using System.Reflection; if(excelApp != null) { excelApp.Application.Workbooks._Open("c:\\Mappe1.xls", Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value); } } private void button1_Click(object sender, System.EventArgs e) { if(excelApp != null) excelApp.Application.Quit(); }
So jetzt aber wirklich muss an meinem interessanten Kram auch noch vorankommen
Gruss sclearscreen
P.S.: Unter den Parametern die ich mit Mising.Value maskiert habe
sind noch andere z.b. fuer verschlüsselte/Passwortgeschüzte Excel-Dateien.
Aber das führt jetzt vom 100 in 10000000....
Und etwas Forschergeist will ich noch übrig lassen