2012-12-30 61 views
2

我開發一個桌面應用程序(C#4.0的WinForms),其中的一個要求是,該方案可以打開一次以上。但是,我不希望用戶能夠多次打開一個給定的文檔(壞事情可能會發生)。打開文件僅一次的程序(如微軟Word)在C#4.0的Winform

基本上我希望它的功能類似於MS Word(至少是新版本),如果你試圖打開一個已經打開的文檔,它將把你帶到已經打開該文檔的程序的實例。

我花了我大部分時間做網站開發,所以可能有一些簡單的解決方案,我只是不知道。

所以我真的有兩個不同的需求。

1)保持打開文件不止一次 2)如果他們試圖再次打開它,請將實例放在前面。

有一對夫婦的我能​​想到的處理#1的方式,但我很好奇的人們是如何解決等這個問題。

我實際上並不知道從哪裏開始嘗試讓#2工作,而無需使某些主窗體/進程保持打開狀態並創建子程序。 IE創建另一個實際控制當前程序主窗體的打開和關閉的窗體,因此它比實際的多窗體驗更像是「標籤」體驗。更像是一個老式的MDI(它仍然會留下問題#1)。

任何幫助在這裏(網站閱讀,名稱空間看,等...)將不勝感激。

編輯 -我看到這已被標記爲重複,並且「重複」位於頁面頂部。我的一個要求是,該程序必須能夠多次打開。你們甚至讀過這篇文章嗎?有人可以進來投票重新提出這個問題嗎?

進一步編輯 -我去與互斥想法保持程序從多次打開同一個文檔。我從來沒有找到一個簡單的方法來找出程序的哪個實例將文檔打開並將它放在前面,所以我現在放棄了,只是彈出一個消息框告訴它它已經打開。命名管道似乎有點矯枉過正,因爲它不完全是我想要做的,並且會涉及很多開銷(並且WCF並不是世界上最簡單的東西),所以需要進一步的幫助。

+0

@HansPassant,我不認爲這是關於「如何創建單實例應用程序」的問題 - 「程序可以打開多個時間「,對我而言,由於某種原因,EXE的多個實例必須同時運行。 –

+0

Word是一個具有OP描述的所有行爲的單實例應用程序。不知道你在說什麼。 –

+0

閱讀Word如何通過使用[運行對象表](http://msdn.microsoft.com/zh-cn/library/aa911889.aspx)來實際執行它可能很有趣/有教育意義。有一些問題談論從C#中使用它,像 - http://stackoverflow.com/questions/8215203/problems-accessing-the-running-object-table。據我所知,沒有內置的C#/ CLR使用方法,它也是很早以前設計的,以解決這個問題。 –

回答

1

您正在詢問有關互斥。在Windows中,您可以創建MUTEX(互斥標誌),因此即使該進程的第二個實例打開,它也會嘗試創建互斥鎖,然後失敗。互斥體是OS範圍內的全球變量(有點),用於IPC /協調。

另一種方法是 - 創建一個帶有類名的窗口(class in windows API,不像C#或C++),它嵌入了文檔名並使用FindWindow()函數先查看這個窗口是否已經打開。然後你可以通過SendMessage(HWND)發送一條消息給它,讓用戶點擊Explorer「myfile.doc」並且它已經打開 - 你只需把它放在前面。 要看的API(從我的大腦內存中,我如何記住這些東西?):

CreateMutex()/OpenMutex() 
FindWindow()/CreateWindow() 
SendMessage()/PostMessage() 
ShowWindow()/ SetWindowPosition()/BringWinToTop() 
+0

這似乎很有希望,但如果程序在Mutex發佈之前崩潰,則不會在用戶重新啓動計算機之前該文件是不可打開的? – Benji

+0

不,互斥量將被操作系統回滾。我建議你使用Window名稱/類並使用FindWindow/SendMessage方法。 (hwnd = FindWindow(「您的應用程序窗口是唯一的」)!= 0)BringToFront(hwnd);返回。換句話說,第二個實例開始找到第一個,將它放在前面並退出該過程。 –

+0

這絕對是我想要防止文件被我的程序打開一次以上的方式,但我不確定我如何使用其他任何其他東西。我在CreateWindow上閱讀了MSDN的內容,但是我確實知道如何在C#程序中使用它們。 – Benji

1

我懷疑有幾十個方法可以解決這個,但這裏是我會怎麼處理它:

只有應用程序的一個實例,並在打開每個請求的文件應用程序中的一個新窗口。

由於隨後打開的文檔將導致創建新實例,但您可以設置應用程序第一個實例創建的進程間通信機制(例如命名管道),因此需要一點協調實例檢查。

如果他們發現IPC存在,他們會將所請求的文件名傳遞給第一個應用程序實例(它將打開指定的文件),然後終止。

下面是微軟命名管道用法的好文章:How to: Use Named Pipes for Network Interprocess Communication

+0

如果我帶着一個主人形式產生孩子形式的想法,那麼爲什麼我需要在孩子之間進行溝通?真的讓主人打開和關閉孩子並且以這種方式可以查看(或存儲)他們的屬性會不會更容易?僅僅使用事件或公共方法來完成它而不是命名管道更容易? – Benji

+0

問題是,如果您將文件擴展名與應用程序相關聯,並且用戶在應用程序上雙擊,我相信Windows會使用命令行參數生成應用程序的新實例(即用戶選擇的文件的名稱) 。如果所有文件的打開都完全在您的應用程序的控制下執行,那麼顯然不需要IPC。 –

+0

啊。我還沒有真正註冊文件擴展名與Windows允許雙擊打開,但正在考慮它。需要思考的東西。 – Benji

相關問題