2009-10-06 22 views
18

İlgili:
Should I include a command line mode in my applications?
How to grab parent process standard output?
Can a console application detect if it has been run from Explorer?Çift tıklatıldığında konsol Penceresi göstermeyen bir Konsol uygulaması oluşturmak mümkün mü?

Ben bir konsol uygulaması oluşturmak istiyorsanız, o normalde komut satırından çalışır.

Ancak, (a cmd.exe isteminden yürütülüyor aksine) Explorer içinden tıklandığında çift sonra bir konsol penceresini DEĞİL programı istiyorum.

Bunu önlemek istiyorsanız: Mümkün

alt text http://i36.tinypic.com/1088p5s.jpg

mi?

DÜZENLEME sanırım öyle sormak için başka bir yol, bir program çağrılan nasıl bilmek için mümkün - olmamasına bakmaksızın çift tıklayın veya komut satırından tarafından?

.NET, Windows'ta çalışıyorum.

DÜZENLEME 2:this Old New Thing blog post'dan iyi şeyler öğrendim. İşte şimdi biliyorum ...

Windows'ta, EXE dosyaları GUI veya GUI olmayan olarak işaretlenir. Csc.exe ile, bu /target:winexe veya /target:exe ile seçilir. İşlemdeki ilk komut yürütülmeden önce, Windows çekirdeği yürütme ortamını ayarlar. O anda, EXE GUI olarak işaretlenirse, çekirdek işlemi için stdin/stdout'u NULL olarak ayarlar ve eğer GUI değilse (komut satırı) çekirdek bir konsol oluşturur ve stdin/stdout'u bu işlem için ayarlar. konsol. Hiçbir Stdin/stdout'u (== /target:winexe) varsa

, süreci başlattığını, sonra beklemeksizin döner. Yani, bir cmd.exe'den bir gui uygulaması başlatırken, hemen cmd istemini geri alacaksınız. Bir stdin/stdout varsa ve cmd.exe'den çalıştırılırsa, ana cmd.exe işlem çıkışını bekler. onun ebeveynin konsoluna takmak için bir GUI uygulamasını kodu varsa, vb Console.WriteLine yapmak mümkün olacak Ama cmd.exe istemi aktif olduğu için

"acil dönüş" önemlidir. Kullanıcı yeni komutlar yazabilir, yeni bir işlem başlatabilir, vb. Diğer bir deyişle, bir winexe'dan, AttachConsole(-1) ile ana konsola bağlantı eklemek bir konsol uygulamasına "dönüştürmez". Bu noktada


Ben olarak exe tanımlamaktır, bu çift tıklandığında ise tek yolu onu kullanmak o cmd.exe çağrılır eğer bir uygulama konsolu kullanmasına izin ve DEĞİL düşünüyorum düzenli konsol exe ( /target:exe) ve uygunsa, başlangıçta pencereyi gizleyin. Hala kısaca görünen bir konsol penceresi olsun.

Hala explorer veya cmd.exe'den başlatılıp başlatılmadığını nasıl anlayacağımı henüz anlamadım.


Bir konsol penceresi göstermeyen bir konsol uygulama oluşturmak mümkün değildir

CEVAPLARI.

penceresini çok hızlı gizleyen bir konsol uygulaması oluşturmak mümkündür, ancak pencerenin hiç görünmediği kadar hızlı değil.

Şimdi

, bir konsol uygulaması explorer başlatıldı olup olmadığını belirlemek için, bazıları
çalışan konsola bakmak için önerilen (mgb's answer gelen ve KB article 99115) adres:

int left = Console.CursorLeft; 
    int top = Console.CursorTop; 
    bool ProcessWasRunFromExplorer = (left==0 && top==0); 

Bu eğer size söyler İşlem kendi konsolunda başlatıldı, ancak kaşif olup olmadığı değil. Explorer'da bir çift tıklama bunu yapar, ancak aynı zamanda bir uygulama içinden bir Start.Process() de aynı şeyi yapar.

Farklı olarak bu durumları tedavi etmek istiyorsanız, ana işlemin adını öğrenmek için kullanır:

System.Console.WriteLine("Process id: {0}", Process.GetCurrentProcess().Id); 
    string name = Process.GetCurrentProcess().ProcessName ; 
    System.Console.WriteLine("Process name: {0}", name); 
    PerformanceCounter pc = new PerformanceCounter("Process", "Creating Process Id", name); 
    Process p = Process.GetProcessById((int)pc.RawValue); 
    System.Console.WriteLine("Parent Process id: {0}", p.Id); 
    System.Console.WriteLine("Parent Process name: {0}", p.ProcessName); 

    // p.ProcessName == "cmd" or "Explorer" etc 

işlem başlatılır hızla sonra pencereyi gizlemek için, bunu kullanın:

private static readonly int SW_HIDE= 0; 

    [System.Runtime.InteropServices.DllImport("user32.dll")] 
    private static extern Boolean ShowWindow(IntPtr hWnd, Int32 nCmdShow); 

    .... 
    { 
    IntPtr myHandle = Process.GetCurrentProcess().MainWindowHandle; 
    ShowWindow(myHandle, SW_HIDE); 
    } 

Bir winexe (bir WinForms uygulaması) oluşturuyorsanız ve isteğe bağlı olarak AttachConsole(-1) ile uyumlu olarak ana konsola bağlarsanız, normal bir konsol uygulamasının eşdeğerini alamazsınız. Bir winexe için, ana işlem (cmd.exe gibi) bir GUI uygulamasını başlattıktan hemen sonra komut istemine geri döner. Diğer bir deyişle, yeni başlatılan işlem çıktı verirken komut istemi aktiftir ve giriş için hazırdır. Bu kafa karıştırıcıdır ve muhtemelen sadece winform uygulamalarının hata ayıklaması için kullanışlıdır.

Bu benim için çalıştı.

+0

Bunun yerine ne yapmak istersiniz? –

+0

Görünmez olmasını istiyorum. – Cheeso

+0

Programın kendi konsolunda başlatılıp başlatılmadığını belirleme testi yanlış. Komut satırında 'cls & program.exe 'girilmesi, programın kendi konsolunda başlatıldığını hatalı olarak belirtir. Aynı şeyi bir toplu iş dosyasından da yapabilirsiniz. Muhtemelen testi yenmek için başka yollar vardır. –

cevap

4

Sadece bir Windows Forms uygulaması olarak oluşturun, ancak bir GUI vermeyin. Ne yazık ki, komut satırından çalıştırıldığında herhangi bir konsol çıktısı almazsınız ... bu bir problem mi?

+0

Hmm, nasıl çalışacağımı biliyorum * bu *. Teşekkürler! – Cheeso

+0

Bunu biraz daha düşünerek, bunun işe yarayacağını düşünmüyorum. AttachConsole() 'da pinvoke kullanarak bir EXE uygulamasını ya da bir konsol uygulaması ya da bir WinForms uygulamasını nasıl çalıştıracağımı biliyorum. Ancak ne zaman bir konsol uygulaması veya Winforms uygulaması yapacağını bilmiyorum. Gezginin içinde çift tıklama ile ya da konsol penceresinden başlatılıp başlatılmadığını nasıl anlayacağımı bilmiyorum. – Cheeso

+0

Konsol görüntüleme modunu seçmek için neden bir komut satırı argümanı kullanmıyorsunuz? Bu şekilde Explorer'dan koşarken, bir tane olmayacak; Bir kısayol oluşturmazsanız ve argümanı burada eklemezseniz - konsolun hem konsol ile hem de konsolosuz olmadan başlamasına izin verin. – Clifford

0

Bu daha çok Hizmet gibi midir?

VEYA Windows Hakkında

Ne

görünür bir şekli yoktur Forms uygulaması? Görev Yöneticisi Süreçleri listesinde hala görünecektir.

5

Yani, yazdım araçlar olduğunu kontrol etmek olduğunu düşünüyorum. Zor kısım hangisinin açılacağını bulmaktı - bizim durumumuzda, CLI sürümü gerekli parametrelere sahipti, bu yüzden herhangi bir parametre olmasaydı GUI'yi açtım. Konsol oluşturulup oluşturulmadığını

private const int ATTACH_PARENT_PROCESS = -1; 
private const int ERROR_INVALID_HANDLE = 6; 
[DllImport("kernel32.dll", SetLastError = true)] 
static extern bool AttachConsole(int dwProcessId); 
[DllImport("kernel32.dll")] 
static extern bool AllocConsole(); 
[DllImport("kernel32.dll")] 
static extern bool FreeConsole(); 

private static bool StartConsole() 
{ 
    if (!AttachConsole(ATTACH_PARENT_PROCESS)) // try connecting to an existing console 
    { 
     if (Marshal.GetLastWin32Error() == ERROR_INVALID_HANDLE) // we don't have a console yet 
     { 
      if (!AllocConsole()) // couldn't create a new console, either 
       return false; 
     } 
     else 
      return false; // some other error 
    } 
    return true; 
} 

İade: bir konsol istemek yaptıysam Ardından, şuna benzer bir işlevi çağırmak. İşiniz bittiğinde FreeConsole() 'ı unutmayın!

Bizim örneğimizde, bir konsol oluşturmazsak, bir GUI oluştururuz. Yine de, bir konsol veya no UI oluşturmak çok kolay olurdu.

DÜZENLEME: Bu, yazmaya başladığım sırada orada olmayan düzenlemedeki soruyu kesinlikle yanıtlamadı elbette. Bunun dışında bizim hack sadece komut satırı parametreleri ile çağrılmış olup olmadığını kontrol ediyordu.

+0

Bu yararlıdır - bir konsol uygulaması oluşturmama veya çalışma zamanında oluşturmama izin verir. Önemli olan, konsolun mevcut olup olmadığını belirleme. Bence bu AttachConsole (-1) 'dir, ancak 0 döndürürse bile, mevcut değilken konsolu nasıl bastıracağımı bilmiyorum. Birkaç şey denemeliyim. Teşekkürler – Cheeso

0
Ben aracılığıyla her şeyi okumadım

, ancak bu (bir süre önce, daha fazla test gerekli) did:

DWORD proc[2],procsfound=GetConsoleProcessList(proc,ELEMS(proc)); 
if (procsfound>1) 
// I'm started as a command in cmd.exe 
else 
// started from explorer or other non-console parent 

ekli birden fazla proc var IFF, ben manipüle konsolu geri yüklemeniz gerekir Aksi takdirde değil. Yararlı olabilir, en azından sadeliğin kendisi. VS kodundan başlayan tek bir bağlı süreçler, komutumuzu çalıştıran karmaşayı temizlemek için şube aktif hale getirdi. Btw, kaşif veya diğer konsol dışı uygulamalardan başlatılan bir konsolun sıfır uzunluklu bir başlığı olacak mı?

İlgili konular