2

I'm writing a script in Siemens NX using vb.net, which helps export drawing files. The file will be exported into a folder, that is kind of bothersome to manually navigate to, so I want to open said folder up to the user after the export.

The target folder is in a plm safe, so the file needs to be checked in in order to be used by other people.

Process.Start(targetfolder) doesn't work, because the folder gets opened "dumb" without any of the plm safe functionality.

Process.Start("explorer.exe", targetfolder) opens the folder using the proper safe environment, however it will open a second folder when I run it again. Ideally I would like the folder to only become active if it's already opened.

I found that I could use

<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
    Private Function FindWindow(ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
    End Function

...

If FindWindow(vbNullString, IO.Path.GetFileName(targetfolder)) = 0 Then
            Process.Start("explorer.exe", targetfolder)
        Else
            AppActivate(IO.Path.GetFileName(targetfolder))
        End If

In order to only open a new window if there isn't one already. However, this also doesn't work reliably, because IO.Path.GetFileName(targetfolder) returns only the folder's name without the entire path. This means that if the user has a folder opened, that has the same name as the target folder but sits in a different spot FindWindow(vbNullString, IO.Path.GetFileName(targetfolder)) will find the other folder to be opened and won't open the target folder. It essentially can't differentiate the two. Additionally, AppActivate(IO.Path.GetFileName(targetfolder)) doesn't work if there are two folders of the same name opened.

Another thing I found was that you cannot rename a directory using FileSystem.Rename() while a child folder of the target folder is opened. I could use this to check if the target folder is opened, by trying to rename the parent folder, however this will create many many false positives.

I am now officially out of ideas. I also cannot use the plm safe's API, because the NX-script doesn't allow the use of "foreign" dll files, such as the plm library.

How do I check if a specific path is already opened in an explorer window?

  • Process.Start returns the Process that was started, and that has a unique ID. You could store that ID, and then check later if that process id was still active maybe? – Slugsie Jul 22 '21 at 09:48
  • @Slugsie unfortunately, I can't really store stuff as it's a macro and all objects that are created by it will be destroyed when it's finished. They will not persist until the macro is run again. – Maximilian Müller Jul 22 '21 at 11:38
  • 1
    Using UI Automation or Win32 functions calls, you can get the inner `ToolbarWindow32` control of the `Breadcrumb Parent` container. The `Name` (UI Automation) of `Text` (Win32) is the full path of the folder currently shown. -- You can also use Shell interfaces to get there, but it's probably more *complicated* in this context. – Jimi Jul 22 '21 at 13:19

1 Answers1

1

Taken from here, you could do something along those lines:

Private Function isPathOpenedInExplorer(myPath As String) As Boolean
    Dim shellWindows As SHDocVw.ShellWindows = New SHDocVw.ShellWindows()
    Dim filename As String

    For Each ie As SHDocVw.InternetExplorer In shellWindows
        filename = Path.GetFileNameWithoutExtension(ie.FullName).ToLower()
        If filename.Equals("explorer") Then
            If myPath = ie.LocationURL.Remove(0, 8).Replace("/", "\").Replace("%20", " ") Then
                Return True ' Found
            End If
        End If
    Next

    Return False 'Not Found
End Function

don't forget to Imports System.IO and Add reference to 'SHDocVw'

Giorgos Xou
  • 1,461
  • 1
  • 13
  • 32