WaitForExit dla programów typu MS Word - proces już rozpoczęty.

Odpowiedz Nowy wątek
2011-10-01 14:24
0

Chce w mojej aplikacji otworzyć plik "*.rtf", a następnie poczekać aż zostanie on zamknięty. Nie zawsze, choć jednak zazwyczaj użytkownik ma MS Worda i tu jest problem. Poniższy kod działa, pod warunkiem, że proces "WINWORD" nie jest jeszcze uruchomiony. Gdy jest, to po wywołaniu metody Process.Start() otwiera się tylko nowe okno Worda, a większość danych z obiektu Process 'p' jest pusta. Nie można 'czekać' aż się zakończy, bo wywala exceptiona. Jak sobie z tym poradzić? Proszę o pomoc.

            Process p = new Process();
            p.StartInfo.FileName = @"C:\Users\UserName\Desktop\MyFile.rtf";
            p.Start();
            string name = p.ProcessName;
            p.WaitForExit();
            Console.WriteLine(name + " has exited");
            Console.ReadKey();
edytowany 1x, ostatnio: Jakub Baran, 2011-10-01 14:24

Pozostało 580 znaków

2011-10-01 14:46
1

A próbowałeś uruchomić WINWORD.EXE, podając w argumentach ścieżkę do pliku .rtf?

Prawie działa, ale jest dużo 'ale'. Po pierwsze musiałbym wiedzieć, że Word jest na komputerze. Po drugie, chce dać możliwość otwarcia nie tylko przez Worda. Po trzecie, aplikacja wtedy czeka na zamknięcie procesu - z mojego postu wynika, że tego oczekiwałem, ale teraz zrozumiałem, że ja chce czekać na zamknięcie okna - konkretnego pliku, bo dlaczego kazać użytkownikowi zamknąć jakąś niezależną pracę? Dzięki za zainteresowanie. - Jakub Baran 2011-10-01 14:59

Pozostało 580 znaków

2011-10-01 14:50
1

A zastanów się, jaki proces właściwie reprezentuje twój proces p? Skąd twój program w ogóle ma wiedzieć, że chodzi ci o Worda?
Tworzysz obiekt, super, ale może tak użyj metody GetProcessByName, żeby przypisać go do procesu Worda?

Fakt, dalej nie będzie działało, gdy Word będzie wyłaczony. Wtedy sprawdź, czy dostałeś ten proces czy też nie i jeśli nie, to go odpal... przez zwykłe ShellExecute.

edytowany 1x, ostatnio: aurel, 2011-10-01 14:51
Rozwiązanie ciekawe, tylko widzę dwa problemy. Po pierwsze, ograniczam się tylko do Worda. Druga rzecz to fakt, że jeżeli użytkownik pracuje na jakimś pliku w wordzie, potem odpali mój program, to mój program nie powinien czekać aż zamknie się cały process. Felernie by wtedy działał. Teraz widzę, że całe moje rozwiązanie jest bezsensu ;/. Dzięki za pomoc. - Jakub Baran 2011-10-01 15:05

Pozostało 580 znaków

2011-10-01 15:08
0

Czytając powyższe komentarze, uznałem, że mój sposób na oczekiwanie jest bezsensu. Z jednej strony chce dać możliwość otwarcia w kilku programach tego pliku *.rtf, zależnie co tam użytkownik ma na dysku. Z drugiej jednak, trzeba by obsłużyć to, że gdy aplikacja jest taka jak Word, to należy czekać na zamknięcie okna, a nie całego procesu. Jak sobie z tym poradzić?

edytowany 1x, ostatnio: Jakub Baran, 2011-10-01 15:09

Pozostało 580 znaków

2011-10-01 16:02

Według mnie masz dwa podejścia: wykorzystanie Microsoft.Office.Interop.Word, dzięki czemu dostajesz szerszą kontrolę nad tym co się dzieje po stronie Worda, albo zaprzyjaźnienie się z VBA.
W obu przypadkach - musisz jakoś wyróżnić "twoje" dokumenty od tych użytkownika. Najprościej - nazywaj je jakoś specjalnie, z przedrostkiem czy coś. Jeśli po stronie VBA, to zmodyfikuj szablon normal.dot, tak by na event zamknięcia dokumentu sprawdzał jego nazwę i jeśli to twój to coś tam robił.

Jeżeli jednak chcesz, żeby twój dokument mógł być otwierany w różnych programach... to cóż, czeka cię większa jazda :P Musisz wiedzieć w jakim programie będzie to otwierane. Musisz zastosować oddzielny kod dla MS Office i oddzielny dla innych Office'ów. Według mnie gra niewarta świeczki, dużo prościej narzucić Worda, ewentualnie Wordpada.

Pozostało 580 znaków

2011-10-01 20:12
1

Chyba czegoś nie rozumiem. Chcemy monitorować plik czy program z niego korzystający? Bo jeśli to pierwsze, to moim zdaniem wystarczy taki prościutki kod:

using System;
using System.IO;
using System.Timers;

namespace DocumentWatcher
{
    class Program
    {
        static string filePath = @"D:\Users\Dawid\Pulpit\Dupa.docx";
        static Timer timer = new Timer(1000);

        static void Main(string[] args)
        {
            timer = new Timer(1000);
            timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
            timer.Enabled = true;

            Console.WriteLine("Naciśnij ENTER aby zakończyć");
            Console.ReadLine();
        }

        static void timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            try
            {
                using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.None))
                {
                    Console.WriteLine("Plik wolny");
                }
            }
            catch (IOException)
            {
                Console.WriteLine("Plik zajęty");
            }
        }

    }
}

"HUMAN BEINGS MAKE LIFE SO INTERESTING. DO YOU KNOW, THAT IN A UNIVERSE SO FULL OF WONDERS, THEY HAVE MANAGED TO INVENT BOREDOM."
Temat, jak i moje rozumowanie się rozwinęło, tak że raz to, a raz to ;]. Rozwiązanie mi się podoba i teraz widzę, że faktycznie o coś takiego mi chodziło. Genialne w swojej prostocie :). Dzięki. - Jakub Baran 2011-10-01 23:05

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0