2012-06-01 6 views
7

Bir dosyayı açmak için Process.Start (string Filename) kullanan bir uygulamam var. Bu yöntem aşırı yüklenmesi, sistemin dosya adı uzantısına dayalı olarak uygun uygulamayı çağırmasına neden olur. Benim durumumda, genellikle bir WORD, PPT, PDF, JPG vb. Olacak. Bazı görüntülenebilir belge türü. Sonunda, işlemi başlatmam gerekiyor ve daha sonra uygulamada MainWindowHandle değeriyle bir şeyler yapmam gerekiyor.System.Diagnostics.Process.Start() tuhaf davranış

ben ikisini açıyorum, farklı yolları dönmek için Process.Start (string dosya) neden en az üç farklı durumlarda ... aşağıda birinci ve ikinci durumlarda

varsayalım buldum. Acrord32 çalışmıyor ve ben böyle bir şey yapmak : pdf dosyaları ...

Durum 1 (ancak aynı şey iki .ppt veya iki .doc dosyalarını iyi olarak açıyordu durumunda ne görünür).

Process p = Process.Start("yada.pdf"); 
p.WaitForInputIdle(); 
p.Refresh(); 

işler beklendiği gibi çalışır. P.MainWindowHandle değeri doğru şekilde doldurulur. Bu durumda sorun yok.

Durum 2: Şimdi, Process.Start() çağrısı sırasında, AcroRd32'nin önceden açılmış bir pdf dosyasında çalışan olduğunu varsayalım. Şimdi işler tuhaflaşıyor. için aşağıdaki kod (netlik için kaldırılmış bazı hata denetim mantığı), Process.Start() çağrısı çağrıldıktan sonra p.MainWindowHandle değeri sıfırdır ( penceresi oluşturulsa bile) ve p.MainWindowTitle ise boş. Sonra 1 saniye uyku ve tanıtıcı hala sıfırdır, ama mainWindowTitle artık (doldurulur bile ben uykudan sonra p.Referesh() çağrısı DEĞİL gerçi. < < < < "sahip iz tabloların her "yorumlarında zamanında basılır.

Process p = Process.Start("SomeFileName.pdf"); 
p.WaitForInputIdle(); 
p.Refresh(); 
if (p.MainWindowHandle == 0) 
    DebugTrace("MainWindowHandle is zero, why??"); //<<<< 
if (p.MainWindowTitle.Length == 0) 
    DebugTrace("MainWindowTitle is null");   //<<<< 
Thread.Sleep(1000); 
if (p.MainWindowHandle == 0) 
    DebugTrace("MainWindowHandle is still zero."); //<<<< 
if (p.MainWindowTitle.Length == 0) 
    DebugTrace("MainWindowTitle is null"); 
else 
    DebugTrace("MainWindowTitle: " + p.MainWindowTitle); //<<<< 

Bu Acrord32 koşu zaten olması ile ilgili bir şey olduğundan emin değilim, ama o üzerinde herhangi bir kontrolü var ve değeri elde gerekiyor /p.MainWindowHandle Herhangi bir fikir, bunun nasıl ele alınacağı hakkında bir fikir sahibi olabilirsiniz

Durum 3: Üçüncü durumda: bazı durumlarda, Process.Start(), dosyayı başarıyla açtığında bile null değerini döndürür. Bunu, .jpg dosyaları ile ilgili olarak buldum, ancak .jpg uzantısına atanan uygulamasına bağlı olduğundan eminim. Process.Start ("file.jpg"), uygulama "Windows Photo Viewer" ise, null değerini döndürür, ancak bu değeri "Paint" olarak değiştirirseniz, null döndürmez. Ne var ne yok? Ve o zaman tutamacını nasıl alabilirim?

Tamam, hepsi bitti, ayrıntı için üzgünüm, ama umarım ki durumları açıklarım (0) Çalışmaya çalışıyorum!

+1

Merak etme, MainWindowHandle ile ne ilgisi var? Belki daha iyi bir yol var! – banging

+0

Pencerenin konumunu/boyutunu izlemem gerekiyor ve şu anda pencere tanıtıcısını girdi olarak alan GetWindowRect() yöntemini kullanıyorum. Process.Start() sınırlamaları nedeniyle, etkin pencerenin dosya adını bilmesine ve zaman zaman işlem adını bilmesine dayanarak "tahmin etmem gerekiyor". İdeal olarak tahmin etmek istemem! :-) –

cevap

2

Pencerelerin acroRd32 ile yeni bir işlem başlattığından şüpheleniyorum, bu da verilen dosya yolu boyunca çalışan örneğe geçiyor ve sonra kapanıyor.

Bu, genellikle bir programın birden çok örneğini önlemek için yapılır ...

+0

Anladım ve aynı şeyin powerpoint, word vb. Ile gerçekleşeceğinden eminim ... Sorun şu ki bu kodda bu gibi durumlarda kullanılamayacak olan pencere tanıtıcısını almam gerekiyor. –

+0

AcroRd32'nin var olup olmadığını kontrol etmek için GetProcesses kullanın ve buradan ana tanıtıcıyı alın. Http://msdn.microsoft.com/en-us/library/system.diagnostics.process.mainwindowhandle.aspx – Schwarzie2478

+0

Bunu yapamıyorum çünkü gerçekten yapamıyorum Hangi sürecin başlatılacağını bilmiyorum. Yukarıdaki örnek olarak acroRd32 kullandım, ancak dosya uzantısına ne tür bir uygulama bağlanmış olursa olsun, bir word belgesi, powerpoint, jpeg olabilir. Yukarıda açık olmayan bir şey de, Process.Start() öğesine iletilen dizinin rasgele olmasıdır. –

0

MainWindowHandle'a Process.Start'ın geri döndüğüne güvenemezsiniz. Bahsettiğiniz gibi, dosya, çalışan bir uygulama tarafından açıldığında geri dönmez. Windows Vista'dan bu yana MS, belirli bir dosyada kilitleme işlemlerinizi gerçekleştirebilecek yeni bir API olan ReStart Manager'ı ekledi. https://msdn.microsoft.com/en-us/magazine/cc163450.aspx

Sorunumun nedeni, Process.Start's MainWindowHandle ve kilitleme tanıtıcısı ReStart yöneticisinin döndürmesiydi. MSDN dergisinden bir örnek kod var. https://github.com/andrewchaa/PopOpen/blob/master/Pop.Cs/InUseDetection.cs