This just opens all drawing files in solidworks and saves as a *.pdf
file. I just wanted to to get a second set of eyes on this before I let it go on the actual drawings database (i.e. all our files) and hopefully make sure it won't encounter any errors.
using SolidWorks.Interop.sldworks;
using SolidWorks.Interop.swconst;
using System.Runtime.InteropServices;
using System;
using System.IO;
namespace PDF.csproj
{
public partial class SolidWorksMacro
{
public void Main()
{
string pdfPath;
string Path = "C:\\Users\\SAFEROADS201\\Desktop\01円-VMS Trailer";
string txtPath = Path + "\\UpdatedPDFs.txt";
string Date = DateTime.Now.ToShortDateString();
string[] drwPaths = System.IO.Directory.GetFiles(Path, "*.slddrw", SearchOption.AllDirectories);
foreach (string s in drwPaths)
{
if (!s.Contains("~$"))
{
ModelDoc2 swDoc = null;
int longstatus = 0;
int longwarnings = 0;
pdfPath = s;
pdfPath = pdfPath.Replace("Drawings", "PDFs").Replace("SLDDRW", "PDF");
(new FileInfo(pdfPath)).Directory.Create();
swDoc = ((ModelDoc2)(swApp.OpenDoc6(s, 3, 0, "", ref longstatus, ref longwarnings)));
longstatus = swDoc.SaveAs3(pdfPath, 0, 0);
swDoc = null;
swApp.CloseAllDocuments(true);
}
}
System.IO.File.WriteAllText(txtPath, Date);
}
/// <summary>
/// The SldWorks swApp variable is pre-assigned for you.
/// </summary>
public SldWorks swApp;
}
}
1 Answer 1
Naming
Also the naming guidlines doesn't explictly mention variable local to a method, you should name them using
camelCase
casing.Naming methods, properties and variables in a meaningful way will help you or Mr.Maintainer to faster grasp what a variable/method/class is about.
Shortening of names like
foreach (string s in drwPaths)
should be avoided.
General
If the right side type of an assignment is obvious one should use
var
likevar path = "C:\\Users\\SAFEROADS201\\Desktop\01円-VMS Trailer";
By using guard conditions you can save horizontal spacing which improves readability of the code.
By extracting the algorithm to a method in a separate class you can reuse it.
Filepaths should be composed using the
System.IO.Path.Combine()
method.If you are dealing with a large amount of files you should prefer
Directory.EnumerateFiles()
overDirectory.GetFiles()
.
From the documentation ofGetFiles()
:The EnumerateFiles and GetFiles methods differ as follows: When you use EnumerateFiles, you can start enumerating the collection of names before the whole collection is returned; when you use GetFiles, you must wait for the whole array of names to be returned before you can access the array. Therefore, when you are working with many files and directories, EnumerateFiles can be more efficient.
variables should be declared as near as possible to their usage.
strings, especially strings which represents filepaths should be marked as
verbatim string literal
to ignore escape sequences. See this SO answer
Refactoring
Let us start by introducing a new class called SolidWorkFileConverter
, add a constructor and add a method named ToPdf()
public class SolidWorkFileConverter
{
private SldWorks swApplication;
public SolidWorkFileConverter(SldWorks swApp)
{
swApplication = swApp;
}
public void ToPdf(string searchPath, string logFileName)
{
var logFileDestionation = System.IO.Path.Combine(searchPath, logFileName);
var currentDate = DateTime.Now;
var drawingFiles = System.IO.Directory.EnumerateFiles(Path, "*.slddrw", SearchOption.AllDirectories)
.Where(file => !file.Contains("~$"));
foreach (var drawingFile in drawingFiles)
{
ToPdf(drawingFile);
}
WriteToLog(logFileDestination, currentDate);
}
public void ToPdf(string drawingFile)
{
string destinationFileName = ComposeDestinationFileName(drawingFile);
CreateDestinationDirectory(destinationFileName);
int state = 0;
int warningState = 0;
ModelDoc2 swDoc = (ModelDoc2)(swApplication.OpenDoc6(s, 3, 0, "", ref state, ref warningState));
state = swDoc.SaveAs3(pdfPath, 0, 0);
swDoc = null;
swApplication.CloseAllDocuments(true);
}
private string ComposeDestinationFileName(string sourceFileName)
{
return sourceFileName.Replace("Drawings", "PDFs").Replace("SLDDRW", "PDF");
}
private void CreateDestinationDirectory(string destinationFileName)
{
string directoryName = System.IO.Path.GetDirectoryName(destinationFileName);
System.IO.Directory.CreateDirectory(directoryName);
}
private void WriteToLog(string logFileDestination, DateTime currentDate)
{
System.IO.File.WriteAllText(logFileDestination, currentDate.ToShortDateString());
}
}
this can now be called by your main()
method (or used anywhere) like
string searchPath = @"C:\Users\SAFEROADS201\Desktop01円-VMS Trailer";
string logFileName = System.IO.Path.Combine(searchPath , "UpdatedPDFs.txt");
SolidWorkFileConverter converter = new SolidWorkFileConverter(swApp);
converter.ToPdf(searchPath, logFileName);