如何获取SolidWorks EPDM Vault中选中文件名?现有代码失效
问题分析:SolidWorks EPDM Vault文件夹无法获取选中文件名
你的代码在普通Windows文件夹里能正常抓取选中的文件名,但碰到C盘里的SolidWorks EPDM Vault文件夹就彻底失效——返回空白还没报错,核心原因很明确:EPDM的Vault窗口是定制化的Shell扩展窗口,根本不是标准的Windows Explorer窗口,你依赖的IShellFolderViewDual/ShellFolderView这类标准Shell接口,对它完全不起作用。
原代码的逻辑是遍历系统里的Shell窗口,用标准接口读取选中项,但EPDM的Vault窗口只是长得像资源管理器,底层是基于EPDM自己的扩展实现的,完全不兼容这些标准接口的访问方式。
解决方案1:用EPDM官方API直接获取(最可靠)
这是最稳妥的办法,直接调用EPDM提供的API来访问Vault内的内容,毕竟官方接口肯定适配自家的窗口:
首先得在你的项目里添加SolidWorks EPDM的COM组件引用(通常叫EdmLib,在COM选项卡能找到),然后替换/补充代码如下:
Imports EdmLib Imports System.Runtime.InteropServices Imports Shell32 Imports SHDocVw Imports System.IO Public Class Form1 ' 新增:用EPDM API获取Vault选中项 Private Function GetEPDMSelectedFiles() As String() Dim selectedFiles As New List(Of String) Dim vault As IEdmVault5 = New EdmVault5() Try ' 获取当前激活的Vault浏览器窗口 Dim frame As IEdmFrame5 = vault.GetExplorerFrame(Nothing) If frame IsNot Nothing Then Dim currentView As IEdmView5 = frame.CurrentView Dim selectedItems As Array = currentView.GetSelectedItems() ' 遍历选中的Vault文件/文件夹 For Each item As IEdmItem5 In selectedItems selectedFiles.Add(item.Name) Next End If Catch ex As Exception MessageBox.Show("获取EPDM选中项失败:" & ex.Message) End Try Return selectedFiles.ToArray() End Function Private Sub btntest_Click(sender As Object, e As EventArgs) Handles btntest.Click ' 优先尝试EPDM的获取逻辑 Dim epdmFiles = GetEPDMSelectedFiles() If epdmFiles.Length > 0 Then Label1.Text = String.Join(".", epdmFiles) Return End If ' fallback到原来的普通资源管理器逻辑 Dim explorerFiles = GetExplorerSelectedFiles() Label1.Text = String.Join(".", explorerFiles) End Sub ' 保留你原来的普通文件夹获取函数 Private Function GetExplorerSelectedFiles() As String() Dim ExplorerFiles As New List(Of String) Dim exShell As New Shell For Each window As ShellBrowserWindow In DirectCast(exShell.Windows, IShellWindows) If TryCast(window.Document, IShellFolderViewDual) IsNot Nothing Then For Each fi As FolderItem In DirectCast(window.Document, IShellFolderViewDual).SelectedItems ExplorerFiles.Add(fi.Name) Next ElseIf TryCast(window.Document, ShellFolderView) IsNot Nothing Then For Each fi As FolderItem In DirectCast(window.Document, ShellFolderView).SelectedItems ExplorerFiles.Add(fi.Name) Next End If Next Return ExplorerFiles.ToArray End Function End Class
注意点:
- 确保运行程序的账号已经登录到EPDM Vault,并且有对应文件夹的访问权限;
- 不同版本的EPDM,API接口可能略有差异,要是遇到编译报错,可以尝试引用更高版本的
EdmLib。
解决方案2:UI自动化(无EPDM权限/API的备选)
如果没法引用EPDM的API,也可以用Windows UI自动化来“模拟”读取Vault窗口的选中项,缺点是EPDM版本更新可能会导致UI结构变化,需要微调:
Imports System.Windows.Automation Imports System.Linq Imports Shell32 Imports SHDocVw Imports System.IO Public Class Form1 ' 新增:用UI自动化获取EPDM选中项 Private Function GetEPDMSelectedFilesViaUIA() As String() Dim selectedFiles As New List(Of String) ' 遍历所有窗口,找到标题带"Vault"的EPDM窗口(根据你的实际Vault名称调整) Dim allWindows = AutomationElement.RootElement.FindAll(TreeScope.Children, New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Window)) For Each window As AutomationElement In allWindows Dim windowTitle = window.Current.Name If windowTitle.Contains("Vault") Then ' 定位Vault里的文件列表控件(通常是DataGrid类型) Dim fileList = window.FindFirst(TreeScope.Descendants, New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.DataGrid)) If fileList IsNot Nothing Then ' 获取选中项的选择模式 Dim selectionPattern = DirectCast(fileList.GetCurrentPattern(SelectionPattern.Pattern), SelectionPattern) For Each selectedItem As AutomationElement In selectionPattern.Current.GetSelection() Dim fileName = selectedItem.Current.Name If Not String.IsNullOrEmpty(fileName) Then selectedFiles.Add(fileName) End If Next End If End If Next Return selectedFiles.ToArray() End Function Private Sub btntest_Click(sender As Object, e As EventArgs) Handles btntest.Click ' 优先尝试UI自动化获取EPDM项 Dim epdmFiles = GetEPDMSelectedFilesViaUIA() If epdmFiles.Length > 0 Then Label1.Text = String.Join(".", epdmFiles) Return End If ' fallback到普通资源管理器逻辑 Dim explorerFiles = GetExplorerSelectedFiles() Label1.Text = String.Join(".", explorerFiles) End Sub ' 保留原有的普通文件夹获取函数 Private Function GetExplorerSelectedFiles() As String() Dim ExplorerFiles As New List(Of String) Dim exShell As New Shell For Each window As ShellBrowserWindow In DirectCast(exShell.Windows, IShellWindows) If TryCast(window.Document, IShellFolderViewDual) IsNot Nothing Then For Each fi As FolderItem In DirectCast(window.Document, IShellFolderViewDual).SelectedItems ExplorerFiles.Add(fi.Name) Next ElseIf TryCast(window.Document, ShellFolderView) IsNot Nothing Then For Each fi As FolderItem In DirectCast(window.Document, ShellFolderView).SelectedItems ExplorerFiles.Add(fi.Name) Next End If Next Return ExplorerFiles.ToArray End Function End Class
注意点:
- 需要添加
UIAutomationClient和UIAutomationTypes两个引用; - 要是你的EPDM窗口标题不含"Vault",得修改判断逻辑;如果文件列表控件不是DataGrid,也要调整控件类型的判断。
内容的提问来源于stack exchange,提问作者fourie
相关产品推荐
相关产品推荐

