static int Main(string[] args)
        {
            Options commandLineOptions = new Options();
            bool    parseErrorsOccured = false;

            CommandLine.Parser.Default.ParseArguments <Options>(args)
            .WithParsed <Options>(opts => commandLineOptions      = opts)
            .WithNotParsed <Options>((errs) => parseErrorsOccured = true);

            if (parseErrorsOccured)
            {
                //Console.WriteLine("some parse errors occured. ahoy.");
                return(1);
            }



            //*****parse the command-line arguments*****
            //for now, I will simply hard code these values.
            String nameOfSheetsetFile            = commandLineOptions.SheetSetFile;
            String nameOfPdfOutputFile           = commandLineOptions.OutputPdfFile;
            String baseName                      = System.IO.Path.GetTempFileName();
            String nameOfTheTemporaryDsdFile     = baseName + ".dsd";
            String nameOfTheTemporaryPlotLogFile = baseName + "-plot" + ".log";

            //TO DO: parse and verify the real command-line arguments, compose a help message.

            //*****read the sheetset file and construct a dsd file accordingly*****
            IAcSmSheetSetMgr sheetSetMgr;
            IAcSmDatabase    sheetdb;
            IAcSmSheetSet    sheetSet;

            Console.WriteLine("Getting the AutoCAD aplication object...");

            IAcadApplication acad;

            acad         = new AcadApplication();
            acad.Visible = false;
            // to do: figure out how to instantiate acad in such a way that no flashing windows appear.  Even when we set acad.Visibile = false,
            // the layer manager window and other accessory AutoCAD windows sometimes appear.
            //I want to run AutoCAD fully as a background process.
            // would it make sense to use the special command-line version of AutoCAD for this instead of the COM object?  (acconsole.exe, I think)
            String acadProgramDirectory = System.IO.Path.GetDirectoryName(acad.FullName);

            Console.WriteLine("acad.FullName: " + acad.FullName);
            Console.WriteLine("acadProgramDirectory: " + acadProgramDirectory);

            Environment.SetEnvironmentVariable("PATH", Environment.GetEnvironmentVariable("PATH") + ";" + acadProgramDirectory);
            //SetDllDirectory(dllDirectory);

            //Console.WriteLine("Directory.GetCurrentDirectory(): " + Directory.GetCurrentDirectory());
            //Directory.SetCurrentDirectory(dllDirectory);
            //Console.WriteLine("Directory.GetCurrentDirectory(): " + Directory.GetCurrentDirectory());
            //IAcadApplication acad;
            //acad = new AcadApplication();
            Console.WriteLine("checkpoint -2");

            // it seems that we have to arrange to have the following dlls in the same directory as the acad-sheetset-to-pdf executable in order to succesfully create
            // an instance of the AcSmSheetSetMgr object, below.
            // acpal.dll
            // acui24res.dll
            // adui24res.dll
            // anavRes.dll

            //Even if we run executable with the initial working directory being the autocad install directory (which is the primary residence of those dlls), we still get errors about not being able to find entry points.

            int libIdOfAcpal = 0;

            //int libIdOfAcui24res = 0;
            //int libIdOfAdui24res = 0;
            //int libIdOfAnavRes = 0;

            libIdOfAcpal = LoadLibrary(acadProgramDirectory + @"\" + "acpal.dll");
            //libIdOfAcpal = LoadLibrary("acpal.dll");
            // for reasons that I do not fully understand, manually loading acpal.dll with the above call to LoadLibrary will prevent the below "new AcSmSheetSetMgr()" statement from throwing an error abot not being able
            // to find dlls.

            //libIdOfAcui24res = LoadLibrary(dllDirectory + @"\" + "acui24res.dll");
            //libIdOfAdui24res = LoadLibrary(dllDirectory + @"\" + "adui24res.dll");
            //libIdOfAnavRes = LoadLibrary(dllDirectory + @"\" + "anavRes.dll");

            Console.WriteLine("libIdOfAcpal: " + libIdOfAcpal);
            //Console.WriteLine("libIdOfAcui24res: " + libIdOfAcui24res);
            //Console.WriteLine("libIdOfAdui24res: " + libIdOfAdui24res);
            //Console.WriteLine("libIdOfAnavRes: " + libIdOfAnavRes);


            sheetSetMgr = new AcSmSheetSetMgr();
            Console.WriteLine("attempting to open " + nameOfSheetsetFile);
            //Environment.CurrentDirectory = @"C:\Program Files\Autodesk\AutoCAD 2019";
            sheetdb = sheetSetMgr.OpenDatabase(nameOfSheetsetFile, bFailIfAlreadyOpen: false);
            Console.WriteLine("checkpoint -1");
            String nameOfDwgFileContainingThePageSetup;
            String nameOfThePageSetup;

            //IAcadApplication acad;
            //acad = new AcadApplication();

            if (sheetdb.GetLockStatus() == 0)
            {
                sheetdb.LockDb(sheetdb);
            }                                                              //it may not be necessary to lock the sheetset, because I am only reading from it, not writing to it.
            sheetSet = sheetdb.GetSheetSet();
            if (sheetdb.GetLockStatus() != 0)
            {
                sheetdb.UnlockDb(sheetdb);
            }
            //read the page setup override information from the sheet set.
            nameOfDwgFileContainingThePageSetup = sheetSet.GetAltPageSetups().ResolveFileName();

            Console.WriteLine("checkpoint 0");
            IAcSmNamedAcDbObjectReference myNamedAcDbObjectReference;

            myNamedAcDbObjectReference = sheetSet.GetDefAltPageSetup();
            //nameOfThePageSetup = myNamedAcDbObjectReference.GetName();
            // the above is not working because sheetSet.GetDefAltPageSetup() returns null.
            // I suspect that sheetSet.GetDefAltPageSetup() only returns something when
            // this code is being run within the Autocad process.
            //as a work-around, we might have to open the dwg file containing the page setup, and read out the page setup names from it.
            Console.WriteLine("checkpoint 1");

            acad.Visible = false;
            Console.WriteLine("checkpoint 2");
            IAcadDocument documentContainingThePageSetup = acad.Documents.Open(Name: nameOfDwgFileContainingThePageSetup, ReadOnly: true);

            while (!AcadIsAvailableAndQuiescent(acad))
            {
                Console.WriteLine("waiting for autoCAD to become available and quiescent.");
            }

            Console.WriteLine("documentContainingThePageSetup.Name: " + documentContainingThePageSetup.Name);                                         //             documentContainingThePageSetup.Name

            Console.WriteLine("documentContainingThePageSetup.PlotConfigurations.Count: " + documentContainingThePageSetup.PlotConfigurations.Count); //             documentContainingThePageSetup.PlotConfigurations.Count


            foreach (IAcadPlotConfiguration thisPlotConfiguration in documentContainingThePageSetup.PlotConfigurations)
            {
                Console.WriteLine("found a PlotConfiguration: " + thisPlotConfiguration.Name);
            }
            nameOfThePageSetup = documentContainingThePageSetup.PlotConfigurations.Item(0).Name;
            documentContainingThePageSetup.Close(SaveChanges: false);
            Console.WriteLine("nameOfDwgFileContainingThePageSetup: " + nameOfDwgFileContainingThePageSetup);
            Console.WriteLine("nameOfThePageSetup: " + nameOfThePageSetup);

            string dsdContent = "";

            dsdContent +=
                "[DWF6Version]" + "\r\n" +
                "Ver=1" + "\r\n" +
                "[DWF6MinorVersion]" + "\r\n" +
                "MinorVer=1" + "\r\n";

            IAcSmEnumComponent myAcSmEnumComponent = sheetSet.GetSheetEnumerator();
            IAcSmComponent     thisAcSmComponent;
            IAcSmSheet         thisSheet;

            while ((thisAcSmComponent = myAcSmEnumComponent.Next()) != null)
            {
                Console.WriteLine(thisAcSmComponent.GetObjectId().GetPersistObject().GetTypeName());
                thisSheet = (IAcSmSheet)thisAcSmComponent.GetObjectId().GetPersistObject();
                Console.WriteLine("thisSheet.GetName(): " + thisSheet.GetName());                                         //                 thisSheet.GetName()
                Console.WriteLine("thisSheet.GetLayout().GetName(): " + thisSheet.GetLayout().GetName());                 //                 thisSheet.GetLayout().GetName()
                Console.WriteLine("thisSheet.GetLayout().ResolveFileName(): " + thisSheet.GetLayout().ResolveFileName()); //                 thisSheet.GetLayout().ResolveFileName()
                Console.WriteLine("thisSheet.GetLayout().GetFileName(): " + thisSheet.GetLayout().GetFileName());         //                 thisSheet.GetLayout().GetFileName()

                dsdContent +=
                    "[DWF6Sheet:" + thisSheet.GetName() + "]" + "\r\n" +
                    "DWG=" + thisSheet.GetLayout().ResolveFileName() + "\r\n" +
                    "Layout=" + thisSheet.GetLayout().GetName() + "\r\n" +
                    "Setup=" + nameOfThePageSetup + "|" + nameOfDwgFileContainingThePageSetup + "\r\n" +
                    "OriginalSheetPath=" + thisSheet.GetLayout().ResolveFileName() + "\r\n" +
                    "Has Plot Port=" + "0" + "\r\n" +
                    "Has3DDWF=" + "0" + "\r\n";
            }

            dsdContent +=
                "[Target]" + "\r\n" +
                "Type=6" + "\r\n" +
                "DWF=" + nameOfPdfOutputFile + "\r\n" +
                "OUT=" + System.IO.Path.GetDirectoryName(nameOfPdfOutputFile) /*+ System.IO.Path.DirectorySeparatorChar*/ + "\r\n" +
                "PWD=" + "" + "\r\n" +
                "[PdfOptions]" + "\r\n" +
                "IncludeHyperlinks=FALSE" + "\r\n" +
                "CreateBookmarks=FALSE" + "\r\n" +
                "CaptureFontsInDrawing=TRUE" + "\r\n" +
                "ConvertTextToGeometry=FALSE" + "\r\n" +
                "VectorResolution=600" + "\r\n" +
                "RasterResolution=400" + "\r\n" +
                "[AutoCAD Block Data]" + "\r\n" +
                "IncludeBlockInfo=0" + "\r\n" +
                "BlockTmplFilePath=" + "\r\n" +
                "[SheetSet Properties]" + "\r\n" +
                "IsSheetSet=TRUE" + "\r\n" +
                "IsHomogeneous=FALSE" + "\r\n" +
                "SheetSet Name=" + sheetSet.GetName() + "\r\n" +
                "NoOfCopies=1" + "\r\n" +
                "PlotStampOn=FALSE" + "\r\n" +
                "ViewFile=FALSE" + "\r\n" +
                "JobID=0" + "\r\n" +
                "SelectionSetName=" + "\r\n" +
                "AcadProfile=" + "\r\n" +
                "CategoryName=" + "\r\n" +
                "LogFilePath=" + nameOfTheTemporaryPlotLogFile + "\r\n" +
                "IncludeLayer=FALSE" + "\r\n" +
                "LineMerge=FALSE" + "\r\n" +
                "CurrentPrecision=" + "\r\n" +
                "PromptForDwfName=FALSE" + "\r\n" +
                "PwdProtectPublishedDWF=FALSE" + "\r\n" +
                "PromptForPwd=FALSE" + "\r\n" +
                "RepublishingMarkups=FALSE" + "\r\n" +
                "DSTPath=" + nameOfSheetsetFile + "\r\n" +
                "PublishSheetSetMetadata=FALSE" + "\r\n" +
                "PublishSheetMetadata=FALSE" + "\r\n" +
                "3DDWFOptions=0 0" + "\r\n" + "\r\n" +
                "";

            System.IO.File.WriteAllText(path: nameOfTheTemporaryDsdFile, contents: dsdContent);

            Console.WriteLine(nameOfTheTemporaryDsdFile);

            if (sheetdb.GetLockStatus() != 0)
            {
                sheetdb.UnlockDb(sheetdb);
            }
            IAcadDocument workingDocument = acad.Documents.Add();

            while (acad.GetAcadState().IsQuiescent == false)
            {
                Console.WriteLine("waiting for autoCAD to become quiescent.");
            }
            workingDocument.SetVariable("FILEDIA", 0);
            workingDocument.SendCommand("-PUBLISH" + "\n" + nameOfTheTemporaryDsdFile + "\n");


            try
            {
                //make a copy of the log file so that we can inspect the log file even after the clean-up behavior built into AutoCAD's publish routine has deleted the original log file.
                System.IO.File.Copy(nameOfTheTemporaryPlotLogFile, baseName + "2" + "-plot" + ".log", overwrite: true);
                //Actually, the above attempt to copy does not seem to result in the expected output log file.  However, it does seem to result in having a csv version of the log file left behind in the temp folder.
            }
            catch (Exception)
            {
                Console.WriteLine("Attempted and failed to make a copy of the temporary plot log file. " + nameOfTheTemporaryPlotLogFile);
                //throw;
            }


            workingDocument.Close(SaveChanges: false);
            while (acad.GetAcadState().IsQuiescent == false)
            {
                Console.WriteLine("waiting for autoCAD to become quiescent.");
            }
            // Keep the console window open
            //Console.WriteLine("Press any key to exit."); Console.ReadKey();
            acad.Quit();

            if (libIdOfAcpal > 0)
            {
                FreeLibrary(libIdOfAcpal);
            }
            //if (libIdOfAcui24res > 0) { FreeLibrary(libIdOfAcui24res); }
            //if (libIdOfAdui24res > 0) { FreeLibrary(libIdOfAdui24res); }
            //if (libIdOfAnavRes > 0) { FreeLibrary(libIdOfAnavRes); }



            return(0);
        }
Exemplo n.º 2
0
        static int Main(string[] args)
        {
            Options commandLineOptions = new Options();
            bool    parseErrorsOccured = false;

            CommandLine.Parser.Default.ParseArguments <Options>(args)
            .WithParsed <Options>(opts => commandLineOptions      = opts)
            .WithNotParsed <Options>((errs) => parseErrorsOccured = true);

            if (parseErrorsOccured)
            {
                //Console.WriteLine("some parse errors occured. ahoy.");
                return(1);
            }



            //*****parse the command-line arguments*****
            //for now, I will simply hard code these values.
            String nameOfSheetsetFile            = commandLineOptions.SheetSetFile;
            String nameOfPdfOutputFile           = commandLineOptions.OutputPdfFile;
            String baseName                      = System.IO.Path.GetTempFileName();
            String nameOfTheTemporaryDsdFile     = baseName + ".dsd";
            String nameOfTheTemporaryPlotLogFile = baseName + "-plot" + ".log";

            //TO DO: parse and verify the real command-line arguments, compose a help message.

            //*****read the sheetset file and construct a dsd file accordingly*****
            IAcSmSheetSetMgr sheetSetMgr;
            IAcSmDatabase    sheetdb;
            IAcSmSheetSet    sheetSet;

            sheetSetMgr = new AcSmSheetSetMgr();
            Console.WriteLine("attempting to open " + nameOfSheetsetFile);
            Environment.CurrentDirectory = "C:\\Program Files\\Autodesk\\AutoCAD 2019";
            sheetdb = sheetSetMgr.OpenDatabase(nameOfSheetsetFile, bFailIfAlreadyOpen: false);
            Console.WriteLine("checkpoint -1");
            String           nameOfDwgFileContainingThePageSetup;
            String           nameOfThePageSetup;
            IAcadApplication acad;

            acad = new AcadApplication();

            if (sheetdb.GetLockStatus() == 0)
            {
                sheetdb.LockDb(sheetdb);
            }                                                              //it may not be necessary to lock the sheetset, because I am only reading from it, not writing to it.
            sheetSet = sheetdb.GetSheetSet();
            if (sheetdb.GetLockStatus() != 0)
            {
                sheetdb.UnlockDb(sheetdb);
            }
            //read the page setup override information from the sheet set.
            nameOfDwgFileContainingThePageSetup = sheetSet.GetAltPageSetups().ResolveFileName();

            Console.WriteLine("checkpoint 0");
            IAcSmNamedAcDbObjectReference myNamedAcDbObjectReference;

            myNamedAcDbObjectReference = sheetSet.GetDefAltPageSetup();
            //nameOfThePageSetup = myNamedAcDbObjectReference.GetName();
            // the above is not working because sheetSet.GetDefAltPageSetup() returns null.
            // I suspect that sheetSet.GetDefAltPageSetup() only returns something when
            // this code is being run within the Autocad process.
            //as a work-around, we might have to open the dwg file containing the page setup, and read out the page setup names from it.
            Console.WriteLine("checkpoint 1");
            acad.Visible = false;
            Console.WriteLine("checkpoint 2");
            IAcadDocument documentContainingThePageSetup = acad.Documents.Open(Name: nameOfDwgFileContainingThePageSetup, ReadOnly: true);

            while (acad.GetAcadState().IsQuiescent == false)
            {
                Console.WriteLine("waiting for autoCAD to become quiescent.");
            }

            Console.WriteLine("documentContainingThePageSetup.Name: " + documentContainingThePageSetup.Name);                                         //             documentContainingThePageSetup.Name

            Console.WriteLine("documentContainingThePageSetup.PlotConfigurations.Count: " + documentContainingThePageSetup.PlotConfigurations.Count); //             documentContainingThePageSetup.PlotConfigurations.Count


            foreach (IAcadPlotConfiguration thisPlotConfiguration in documentContainingThePageSetup.PlotConfigurations)
            {
                Console.WriteLine("found a PlotConfiguration: " + thisPlotConfiguration.Name);
            }
            nameOfThePageSetup = documentContainingThePageSetup.PlotConfigurations.Item(0).Name;
            documentContainingThePageSetup.Close(SaveChanges: false);
            Console.WriteLine("nameOfDwgFileContainingThePageSetup: " + nameOfDwgFileContainingThePageSetup);
            Console.WriteLine("nameOfThePageSetup: " + nameOfThePageSetup);

            string dsdContent = "";

            dsdContent +=
                "[DWF6Version]" + "\r\n" +
                "Ver=1" + "\r\n" +
                "[DWF6MinorVersion]" + "\r\n" +
                "MinorVer=1" + "\r\n";

            IAcSmEnumComponent myAcSmEnumComponent = sheetSet.GetSheetEnumerator();
            IAcSmComponent     thisAcSmComponent;
            IAcSmSheet         thisSheet;

            while ((thisAcSmComponent = myAcSmEnumComponent.Next()) != null)
            {
                Console.WriteLine(thisAcSmComponent.GetObjectId().GetPersistObject().GetTypeName());
                thisSheet = (IAcSmSheet)thisAcSmComponent.GetObjectId().GetPersistObject();
                Console.WriteLine("thisSheet.GetName(): " + thisSheet.GetName());                                         //                 thisSheet.GetName()
                Console.WriteLine("thisSheet.GetLayout().GetName(): " + thisSheet.GetLayout().GetName());                 //                 thisSheet.GetLayout().GetName()
                Console.WriteLine("thisSheet.GetLayout().ResolveFileName(): " + thisSheet.GetLayout().ResolveFileName()); //                 thisSheet.GetLayout().ResolveFileName()
                Console.WriteLine("thisSheet.GetLayout().GetFileName(): " + thisSheet.GetLayout().GetFileName());         //                 thisSheet.GetLayout().GetFileName()

                dsdContent +=
                    "[DWF6Sheet:" + thisSheet.GetName() + "]" + "\r\n" +
                    "DWG=" + thisSheet.GetLayout().ResolveFileName() + "\r\n" +
                    "Layout=" + thisSheet.GetLayout().GetName() + "\r\n" +
                    "Setup=" + nameOfThePageSetup + "|" + nameOfDwgFileContainingThePageSetup + "\r\n" +
                    "OriginalSheetPath=" + thisSheet.GetLayout().ResolveFileName() + "\r\n" +
                    "Has Plot Port=" + "0" + "\r\n" +
                    "Has3DDWF=" + "0" + "\r\n";
            }

            dsdContent +=
                "[Target]" + "\r\n" +
                "Type=6" + "\r\n" +
                "DWF=" + nameOfPdfOutputFile + "\r\n" +
                "OUT=" + System.IO.Path.GetDirectoryName(nameOfPdfOutputFile) /*+ System.IO.Path.DirectorySeparatorChar*/ + "\r\n" +
                "PWD=" + "" + "\r\n" +
                "[PdfOptions]" + "\r\n" +
                "IncludeHyperlinks=FALSE" + "\r\n" +
                "CreateBookmarks=FALSE" + "\r\n" +
                "CaptureFontsInDrawing=TRUE" + "\r\n" +
                "ConvertTextToGeometry=FALSE" + "\r\n" +
                "VectorResolution=600" + "\r\n" +
                "RasterResolution=400" + "\r\n" +
                "[AutoCAD Block Data]" + "\r\n" +
                "IncludeBlockInfo=0" + "\r\n" +
                "BlockTmplFilePath=" + "\r\n" +
                "[SheetSet Properties]" + "\r\n" +
                "IsSheetSet=TRUE" + "\r\n" +
                "IsHomogeneous=FALSE" + "\r\n" +
                "SheetSet Name=" + sheetSet.GetName() + "\r\n" +
                "NoOfCopies=1" + "\r\n" +
                "PlotStampOn=FALSE" + "\r\n" +
                "ViewFile=FALSE" + "\r\n" +
                "JobID=0" + "\r\n" +
                "SelectionSetName=" + "\r\n" +
                "AcadProfile=" + "\r\n" +
                "CategoryName=" + "\r\n" +
                "LogFilePath=" + nameOfTheTemporaryPlotLogFile + "\r\n" +
                "IncludeLayer=FALSE" + "\r\n" +
                "LineMerge=FALSE" + "\r\n" +
                "CurrentPrecision=" + "\r\n" +
                "PromptForDwfName=FALSE" + "\r\n" +
                "PwdProtectPublishedDWF=FALSE" + "\r\n" +
                "PromptForPwd=FALSE" + "\r\n" +
                "RepublishingMarkups=FALSE" + "\r\n" +
                "DSTPath=" + nameOfSheetsetFile + "\r\n" +
                "PublishSheetSetMetadata=FALSE" + "\r\n" +
                "PublishSheetMetadata=FALSE" + "\r\n" +
                "3DDWFOptions=0 0" + "\r\n" + "\r\n" +
                "";

            System.IO.File.WriteAllText(path: nameOfTheTemporaryDsdFile, contents: dsdContent);

            Console.WriteLine(nameOfTheTemporaryDsdFile);

            if (sheetdb.GetLockStatus() != 0)
            {
                sheetdb.UnlockDb(sheetdb);
            }
            IAcadDocument workingDocument = acad.Documents.Add();

            while (acad.GetAcadState().IsQuiescent == false)
            {
                Console.WriteLine("waiting for autoCAD to become quiescent.");
            }
            workingDocument.SetVariable("FILEDIA", 0);
            workingDocument.SendCommand("-PUBLISH" + "\n" + nameOfTheTemporaryDsdFile + "\n");
            //make a copy of the log file so that we can inspect the log file even after the clean-up behavior built into AutoCAD's publish routine has deleted the original log file.
            System.IO.File.Copy(nameOfTheTemporaryPlotLogFile, baseName + "2" + "-plot" + ".log", overwrite: true);
            //Actually, the above attempt to copy does not seem to result in the expected output log file.  However, it does seem to result in having a csv version of the log file left behind in the temp folder.

            workingDocument.Close(SaveChanges: false);
            while (acad.GetAcadState().IsQuiescent == false)
            {
                Console.WriteLine("waiting for autoCAD to become quiescent.");
            }
            // Keep the console window open
            //Console.WriteLine("Press any key to exit."); Console.ReadKey();
            acad.Quit();

            return(0);
        }