Lo que comentas es normal y obvio; la función
Process.GetProcesses() como su nombre indica por si mismo tiene el propósito de devolver una colección de procesos en ejecución, no una colección de ventanas creadas por "X" proceso...
Aquí abajo te comparto un código de mi librería comercial
ElektroKit para obtener las ventanas abiertas del explorador de Windows:
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Gets a <see cref="IEnumerable(Of ShellBrowserWindow)"/> containing the opened windows explorer instances.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <returns>
''' A <see cref="IEnumerable(Of ShellBrowserWindow)"/> containing the opened windows explorer instances.
''' </returns>
''' ----------------------------------------------------------------------------------------------------
<DebuggerStepThrough>
Public Shared Iterator Function GetExplorerWindows() As IEnumerable(Of ShellBrowserWindow)
Dim shell As New Shell32.Shell
Try
For Each window As ShellBrowserWindow In DirectCast(shell.Windows, IShellWindows)
Select Case window.Document.GetType().Name
Case "__ComObject" ' Explorer Window. ShellWindowTypeConstants.SWC_EXPLORER
Yield window
' Case "HTMLDocumentClass" ' Internet Explorer Window. ShellWindowTypeConstants.SWC_BROWSER
' ' Do Nothing.
Case Else ' Other type of window.
' Do Nothing.
End Select
Next window
Catch ex As Exception
Throw ex
Finally
Marshal.FinalReleaseComObject(shell)
End Try
End Function
En C# el equivalente sería practicamente igual, pero con la sintaxis de C# claro está:
/// ----------------------------------------------------------------------------------------------------
/// <summary>
/// Gets a <see cref="IEnumerable{ShellBrowserWindow}"/> containing the opened windows explorer instances.
/// </summary>
/// ----------------------------------------------------------------------------------------------------
/// <returns>
/// A <see cref="IEnumerable{ShellBrowserWindow}"/> containing the opened windows explorer instances.
/// </returns>
/// ----------------------------------------------------------------------------------------------------
[DebuggerStepThrough]
public static IEnumerable<ShellBrowserWindow> GetExplorerWindows() {
Shell32
.Shell shell
= new Shell32
.Shell();
try {
foreach (ShellBrowserWindow window in (IShellWindows)shell.Windows()) {
switch (window.Document.GetType().Name) {
case "__ComObject": // Explorer Window. ShellWindowTypeConstants.SWC_EXPLORER
yield return window;
break;
// case "HTMLDocumentClass": // Internet Explorer Window. ShellWindowTypeConstants.SWC_BROWSER
// break;
default: // Other type of window.
break;
}
}
} finally {
Marshal.FinalReleaseComObject(shell);
}
}
La colección enumerable devuelta podrías iterarla de la siguiente forma que muestro aquí abajo. En este ejemplo busco la primera coincidencia de una ventana cuya ruta especificada en la barra de navegación sea "C:\", y cierro dicha ventana...
[STAThread]
static void Main(string[] args) {
IEnumerable<ShellBrowserWindow> explorerWindows = GetExplorerWindows();
foreach (ShellBrowserWindow Window in explorerWindows) {
ShellFolderView view = (ShellFolderView)Window.Document;
Folder2 folder = (Folder2)view.Folder;
string path = folder.Self.Path;
// Si la ruta en la barra de navegación es "C:\", cerramos esta ventana y salimos del búcle.
if (path.Equals(@"C:\", StringComparison.OrdinalIgnoreCase)) {
Window.Quit();
break;
}
}
Nótese que necesitas referenciar las librerías
Shell32.dll y
SHDocv.dll para poder utilizar el código mostrado. Y aparte, no te olvides de especificar la clase de atributo
STAThread como en el ejemplo, de lo contrario en C# tendrás errores de casting/conversión de tipos en tiempo de ejecución con las interfaces COM de
Shell32 /
SHDocVw.
Saludos.