2011-11-18 75 views
8

我可以很容易地得到使用資源管理器打開並選擇一個文件如下:如何設置現有的Explorer.exe實例來選擇文件?

string argument = @"/select, " + filePath; 
System.Diagnostics.Process.Start("explorer.exe", argument); 

但是當我到開放來的下一個文件,我將獲得Explorer的新實例。這可能會導致我們的用戶在密集的一天結束時打開數百個探索者。

我該如何獲得它重用已打開的資源管理器實例來選擇我想要的文件?

Visual Studio可以做到這一點,當你右鍵點擊一個標籤,並選擇打開包含文件夾...提供資源管理器已經打開在同一目錄。它如何能夠做到這一點?

+3

爲什麼你必須首先使用瀏覽器?你想達到什麼目的? – ChrisBint

+0

爲什麼不使用'System.Diagnostics.Process.Start(filePath)'?這樣就可以用指定的默認程序打開文件。 – Alex

+0

@ChrisBint我們的應用程序有客戶端。每個客戶都有一個存放各種文件的文件夾。我們希望在客戶端文件夾中打開瀏覽器,以便他們可以瀏覽/編輯/複製等...客戶端文檔。 –

回答

3

如何embedding the Explorer window into your application使用ExplorerBrowser對象?這樣,當您想要顯示不同的文件夾時,您可以通過在另一個文件夾上調用IExplorerBrowser::BrowseToObject來繼續重用窗口。

試圖重新導航現有的資源管理器窗口是有問題的,因爲您不知道用戶在沒有查找時用該窗口做了什麼。也許他們使用「文件夾」窗格轉到其他文件夾,然後boom您只需將該文件夾從其下拉出並將其發送到其他位置。或者他們可能關閉它!打開一個新的資源管理器窗口是一種即發即忘型的事情。如果你想保持對窗口的控制,那麼你需要進行更明確的控制(例如通過上面的ExplorerBrowser)。

+0

Windows本身使用這種重複使用打開的資源管理器窗口的行爲。例如,選擇一個文件夾,然後按下Ctrl + Enter在新窗口中打開它。如果您再次執行該操作,則不會打開新的窗口實例。 –

+0

這與重新導航現有窗口不一樣。 –

+0

好,然後使用快捷方式(Windows 7)中的上下文菜單,然後單擊「查找目標」或類似的(我有西班牙語版本)。如果目標文件位於打開的窗口中,則Windows會重新使用它。 –

0

您是否嘗試過獲得Process類的實例並始終使用它來調用Start()方法?

Process myProcess = new Process(); 
string argument = @"/select, " + filePath; 

myProcess.StartInfo.FileName = argument; 
myProcess.Start(); 
+0

這個工作,如果它作爲一個呼叫的相同的路徑。在不同的路徑上打開一個新窗口。 – Alex

+0

根據[文檔](http://msdn.microsoft.com/en-us/library/system.diagnostics.process.aspx),'Start()'將「啓動(或重新使用)流程資源」。這意味着你可以改變'myProcess.StartInfo.FileName'的值並再次調用'Start()'? – Widor

+1

@Widor這不是一個答案,而是一個問題。沒有確認它是否可以回答問題,這是一個純粹的猜測。 – Marek

0

另一種方法是Win32 API方式。

StringBuilder sb = new StringBuilder(@"C:\temp\"); 
hWnd = (...) // get Handle of the Explorer's address field. 
SendMessage(hWnd, WM_SETTEXT, new IntPtr(sb.ToString().Length), sb) 

// Set the focus to the address field

SendMessage(hWnd, WM_SETFOCUS, IntPtr.Zero, null) 
// Simulate Enter key 
SendMessage(hWnd, WM_KEYDOWN, new IntPtr(VK_RETURN), null) 
+2

沒有便捷的方式獲取地址字段,並且您無法通過發送消息可靠地模擬輸入。 –

+1

您可以枚舉瀏覽器進程的所有子窗口,並通過檢查CLASS找到地址字段。看看Spy ++。 – Alex

+3

狩獵特定CLASS是不便攜的。多年來,地址欄的類名已發生變化,未來可能會再次發生變化。 –

1

晚了一點,但如果您想要在瀏覽器窗口中打開的文件夾中選擇一個或多個文件,可以使用shell32方法SHOpenFolderAndSelectItems。該方法重用現有窗口(如果有),否則打開一個新窗口。

[DllImport("shell32.dll")] 
private static extern int SHOpenFolderAndSelectItems(IntPtr pidlFolder, uint cidl, [MarshalAs(UnmanagedType.LPArray)] IntPtr[] apidl, uint dwFlags); 

[DllImport("shell32.dll")] 
private static extern void SHParseDisplayName([MarshalAs(UnmanagedType.LPWStr)] string name, IntPtr bindingContext, out IntPtr pidl, uint sfgaoIn, out uint psfgaoOut); 

public static void ShowFileInExplorer(string folderPath, string filePath) 
{ 
    Shell32.SHParseDisplayName(Path.GetFullPath(folderPath), IntPtr.Zero, out IntPtr folder, 0, out uint psfgaoOut); 

    if (folder == IntPtr.Zero) 
    { 
     return; 
    } 

    Shell32.SHParseDisplayName(Path.GetFullPath(filePath), IntPtr.Zero, out IntPtr file, 0, out psfgaoOut); 

    if (file != IntPtr.Zero) 
    { 
     IntPtr[] files = { file }; 

     Shell32.SHOpenFolderAndSelectItems(folder, (uint)files.Length, files, 0); 
     Marshal.FreeCoTaskMem(file); 
    } 

    Marshal.FreeCoTaskMem(folder); 
} 

本示例僅選擇一個文件,但可以輕鬆擴展以選擇多個文件。