问题:
在我的Windows文件服务器上,我有大约1,000,000个SolidWorks文件,这些文件在自定义选项卡下的文件属性中有元数据(请参见下图),我想将其导出到单个CSV文件中。
这些文件位于文件夹的子树中,并与其他文件类型混合使用。
解决方案:
需要一个脚本来仅定位文件夹子树中的特定文件类型(扩展),将元数据从自定义选项卡导出到CSV文件,然后我可以清理并将数据导入SQL数据库。
我不确定实现这一目标的最佳方法我正在考虑PowerShell,任何帮助都会非常感激。
答案 0 :(得分:2)
如果您使用的是.NET语言(如C#或Visual Basic),则可以使用SolidWorks API和文档管理器库(您需要获得许可证,从客户门户网站免费获取许可证)以提取此信息无需打开文件。这很快。至于只查看某些文件,那就是直接使用.NET IO.Path.GetExtension。
以下是我认为您正在寻找的工作示例。
您将需要SolidWorks API SDK上的Document Manager dll,它包含在安装介质中。然后你可以引用SolidWorks.Interop.swdocumentmgr.dll。
您还需要一个文档管理器序列号,您可以通过SolidWorks客户门户网站免费索取SolidWorks订购号。获得该号码后,将下面的lic字符串值替换为引号中的整个序列号。
要定义要从SolidWorks文件中读取的自定义属性,只需更改列表propertiesToRead以包含您需要检索的任何值。这些不区分大小写。
您运行此程序,系统将提示您输入目录路径。这也是创建Output.csv文件的地方。
底部是样本结果的屏幕截图。
using SolidWorks.Interop.swdocumentmgr;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace WriteProperties
{
class Program
{
static ISwDMApplication4 docManager;
static List<string> propertiesToRead = new List<string>() { "Number", "Description", "Revision", "Material", "Finish", "Weight" };
const string lic = "YOU CAN GET THIS NUMBER FROM THE CUSTOMER PORTAL WITH YOUR SOLIDWORKS SUBSCRIPTION AT NO COST";
static char[] charactersToQuote = { ',', '"', '\n' };
const string QUOTE = "\"";
const string QUOTEFORMATTED = "\"\"";
static void Main(string[] args)
{
string directoryPath = GetDirectory(args);
if (string.IsNullOrEmpty(directoryPath)) return;
if (!LoadDocManager()) return;
string outputPath = Path.Combine(directoryPath, "Output.csv");
StringBuilder sb = new StringBuilder();
sb.AppendLine("File Name," + string.Join(",", propertiesToRead));
int counter = 0;
foreach (string filePath in Directory.EnumerateFiles(directoryPath, "*.sld*", SearchOption.AllDirectories))
{
SwDMDocument21 dmDocument = GetDocument(filePath);
if (dmDocument == null) continue;
WriteProperties(sb, dmDocument, filePath);
counter++;
}
File.WriteAllText(outputPath, sb.ToString());
Console.WriteLine("{0} files read and saved to {1}", counter, outputPath);
Console.ReadLine();
}
static string GetDirectory(string[] args)
{
if (args != null && args.Count() > 0 && Directory.Exists(args[0])) return args[0];
Console.WriteLine("Directory to read:");
string filePath = Console.ReadLine();
if (Directory.Exists(filePath)) return filePath;
Console.WriteLine("Directory does not exists: {0}", filePath);
return string.Empty;
}
static bool LoadDocManager()
{
if (docManager != null) return true;
try
{
SwDMClassFactory factory = new SwDMClassFactory();
if (factory == null) throw new NullReferenceException(nameof(SwDMClassFactory));
docManager = (SwDMApplication4)factory.GetApplication(lic);
if (docManager == null) throw new NullReferenceException(nameof(SwDMApplication4));
return true;
}
catch (Exception ex)
{
Console.WriteLine("Document Manager failed to load: {0}", ex.Message);
Console.ReadLine();
return false;
}
}
static SwDMDocument21 GetDocument(string filePath)
{
SwDmDocumentType documentType = GetDocType(filePath);
if (documentType == SwDmDocumentType.swDmDocumentUnknown) return null;
SwDmDocumentOpenError result = SwDmDocumentOpenError.swDmDocumentOpenErrorNone;
SwDMDocument21 dmDocument = (SwDMDocument21)docManager.GetDocument(filePath, documentType, true, out result);
if (result == SwDmDocumentOpenError.swDmDocumentOpenErrorNone || result == SwDmDocumentOpenError.swDmDocumentOpenErrorFileReadOnly) return dmDocument;
if (dmDocument != null) dmDocument.CloseDoc();
return null;
}
static SwDmDocumentType GetDocType(string filePath)
{
if (filePath.Contains("~$")) return SwDmDocumentType.swDmDocumentUnknown;
switch (Path.GetExtension(filePath).ToLower())
{
case ".sldprt": return SwDmDocumentType.swDmDocumentPart;
case ".sldasm": return SwDmDocumentType.swDmDocumentAssembly;
case ".slddrw": return SwDmDocumentType.swDmDocumentDrawing;
default: return SwDmDocumentType.swDmDocumentUnknown;
}
}
static void WriteProperties(StringBuilder sb, SwDMDocument21 dmDocument, string filePath)
{
Console.WriteLine("Reading {0}", filePath);
List<string> propertiesInFile = new List<string>();
if (dmDocument.GetCustomPropertyCount() > 0) propertiesInFile.AddRange(dmDocument.GetCustomPropertyNames());
string csvLine = filePath;
foreach (string property in propertiesToRead)
{
string propertyValue = "";
if (propertiesInFile.Any(s => string.Compare(s, property, true) == 0))
{
SwDmCustomInfoType propertyType = SwDmCustomInfoType.swDmCustomInfoText;
string resolvedValue;
propertyValue = dmDocument.GetCustomPropertyValues(property, out propertyType, out resolvedValue);
}
csvLine = csvLine + "," + FixChars(propertyValue);
}
sb.AppendLine(csvLine);
dmDocument.CloseDoc();
}
static string FixChars(string s)
{
if (s.Contains(QUOTE)) s = s.Replace(QUOTE, QUOTEFORMATTED);
if (s.IndexOfAny(charactersToQuote) > -1) s = QUOTE + s + QUOTE;
return s;
}
}
}