Dokument aus webpage mit Process.Start() öffnen



  • Hallo

    ich hatte den Thread zuerst in C# und .Net, glaube aber dass er hier besser aufgehoben ist. Ich habe eine Webseite in ASP.Net geschrieben und verlinke dort Dokumente (word, .pdf), die der Seitenbenutzer auf Wunsch öffnen kann. Diese Dokumente sollen dann mit ihren jeweiligen Applikationen geöffnet werden (also Word, oder Acrobat). Die Webseite ist auf einem Server hinterlegt ebenso wie die Dateien, die verlinkt sind. Bisher hatte ich das alles lokal bei mir auf dem Rechner und da funktioniert die Methode Process.Start(C:\Meine Dokumente\Dokument.pdf) ohne Probleme. Wenn ich jetzt aber versuche das ganze vom Server zu starten, passiert nichts. Das Dokument wird nicht geöffnet. Gibt es eine Möglichkeit das Dokument beim Client auf dem Rechner zu öffnen und nicht auf dem Server? Oder muss ich etwas anderes als Process.Start() benutzen?

    Danke für eure Hilfe!



  • Glaubst du allen Ernstes, es wäre eine gute Sache, wenn Webseiten einfach Programme auf den Client-PCs ausführen könnten? Das geht aus sehr gutem Grund nicht!

    Verlinke einfach auf die Datei, dann sollte der Browser einen Dialog mit den Optionen "Speichern" oder "Öffnen" anbieten, wenn der Benuzter darauf klickt. Mehr ist nicht drin, und das ist gut so 😉



  • O.k., bei näherem Nachdenken muss ich dir natürlich recht geben, wäre mehr als ungeschickt wenn man einfach ein Programm beim Client öffnen könnte.

    Wie mache ich das in C#, dass ich den Dialog öffnen/speichern anzeigen kann? Gibt es da schon etwas vorgesehenes?



  • Der Trick dabei ist, dass die Webseite dann die Datei, die geoeffnet werden soll, selbst zurueckgeben muss, inkl. MIME-Typ usw. Dann sucht der Browser entsprechend ein Programm fuer diesen Typ und bietet dir im Regelfall als Benutzer diese Moeglichkeiten: Speicher, Oeffnen, Abbrechen...



  • Hmm, o.k., und wie mache ich sowas? Ich bin noch nicht so ganz bewandert mit Webprogrammierung. Wäre super wenn du mir da sagen könntest nach was ich suchen muss.



  • Also, ich habe folgenden Code im Internet gefunden:

    private void DownloadFile(string fname, bool forceDownload)
            {
    
                string path = MapPath(fname);
                string name = Path.GetFileName(path);
                string ext = Path.GetExtension(path);
                string type = "";
                // set known types based on file extension  
                if (ext != null)
                {
                    switch (ext.ToLower())
                    {
                        case ".htm":
                        case ".html":
                            type = "text/HTML";
                            break;
    
                        case ".txt":
                            type = "text/plain";
                            break;
    
                        case ".doc":
                        case ".rtf":
                            type = "Application/msword";
                            break;
                        case ".pdf":
                            type = "Application/pdf";
                            break;
                    }
                }
                if (forceDownload)
                {
                    Response.AppendHeader("content-disposition",
                        "attachment; filename=" + name);
                }
                if (type != "")
                        Response.ContentType = type;
                //Response.ContentType = "application/x-msdownload";
                Response.WriteFile(path);
                Response.End();
            }
    

    Das funktioniert auch erstaunlicherweise ganz gut, nur bekomme ich beim öffnen meiner .pdf Dateien eine Fehlermeldung von Adobe, dass die Datei nicht gelesen werden kann:

    Acrobat konnte die Datei nicht öffnen, da der Dateityp nicht unterstützt wird oder die Datei beschädigt ist
    

    Öffne ich die Dateien des Servers aber von meinen Rechner aus direkt, nicht über die Webpage, dann kann ich die Dateien problemlos öffnen. Woran liegt das?



  • Bei näherer Betrachtung der heruntergeladenen Datei konnte ich feststellen, dass in dem heruntergeladenen .pdf Dokument der Code der Seite steht, von der der DokumentDownload-Code ausgeführt wird. Wie kann ich verhindern dass der Code in das .pdf Dokument geschrieben wird und einfach nur das Dokument gedownloaded oder geöffnet wird? Habe schon versucht den Download-Code als Klasse auszugliedern, allerdings muss ich dann auch wieder die Page übergeben von der ich den Code aufrufen möchte und wieder habe ich den Code in meiner .pdf Datei stehen.

    Hilfe!



  • Wie kann ich verhindern dass der Code in das .pdf Dokument geschrieben wird und einfach nur das Dokument gedownloaded oder geöffnet wird?

    Du musst einfach nur verhindern, dass im Response Objekt vor der Zeile

    Response.WriteFile(path);
    

    irgendein Content drinnen steht (Headers/Settings ala content-disposition sind OK).
    Und das machst du, indem du im entsprechenden .aspx File einfach sofort mit "<%" losstartest:
    (Natürlich darf auch der C# Code der vor DownloadFile() läuft nichts in das Response-Objekt schreiben)

    <% // wichtig dass hier nichtmal ein Space vor dem <% kommt, also wirklich *nichts* davorsteht
    ...
    DownloadFile(...);
    
    // ob nach dem %> nochwas kommt, ist nicht wichtig, wenn du, wie in deinem Beispiel, die Response explizit mit Response.End abschliesst.
    %>
    

    Alles was vor dem "<%" würde sonst VOR dem eigentlichen File in das Response-Objekt geschrieben. Wenn's ein Textfile ist stört das natürlich weniger, aber wenns ein Binärfile ist (BMP, JPG, PDF, ...), dann macht dir das natürlich das File kaputt. Wäre wie wenn du ein .PDF File im Texteditor (Notepad) aufmachst, und vorne ein paar Zeilen Text mit dranschreibst.
    Ein einziges Leerzeichen oder Newline reicht da schon.



  • Hallo hustbaer, vielen Dank für deine Antwort. Leider weiß ich nicht so recht wie ich das umsetzen soll. Mein DownloadFile() Code steht in einer .cs Datei zur entsprechenden .aspx Page. Die .aspx Page fängt so an:

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="PIMS.aspx.cs" Inherits="PIMSWebaccess.PIMS" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head runat="server">
        <title>PIMS Webaccess</title>
        <style type="text/css">
    ....
    

    Sprich mein DownloadFile() steht nicht direkt in der .aspx Page und daher weiss ich nicht, wie ich verhindern soll dass vor dem Aufruf DownloadFile() nichts im Response-Objekt drin steht, wenn ich doch DownloadFile() gar nicht in der .aspx Datei stehen habe und aufrufe, sondern sich das ganze Geschehen in der entsprechenden PIMS.aspx.cs Datei abspielt.



  • Juhu, der erste Teil ist geschafft. Ich habe jetzt den Code-Teil in eine eigene aspx-Seite geschrieben und auf diese verlinkt. Jetzt öffnet er mir wenigstens meine .pdf's sauber. Aber jetzt habe ich das Problem dass er mir, wenn ich einmal etwas in meiner Listbox angeklickt habe, immer den Download einleiten will. Wie kann ich das Auswählen in der Listbox wieder zurücksetzen? Ich habe es schon mit Listbox.SelectedItem = -1 versucht, aber das macht gar nichts, der Link ist immer noch ausgewählt.


Anmelden zum Antworten