Best way to run custom scripts on multiple files

Best way to run custom scripts on multiple files

ottosson_mathias
Advocate Advocate
3,413 Views
9 Replies
Message 1 of 10

Best way to run custom scripts on multiple files

ottosson_mathias
Advocate
Advocate

I've seen applications like ScriptPro or AutoScript and I would like to try to write a similar application that can run scripts (as well as lisp scripts) on multiple files in AutoCAD.

 

What's the best way to approach this problem?

Let's say I write a purge script that I want to run on some files:

 

 

PURGE A * N
QSAVE

 


My files:

myFile1.dwg
myFile2.dwg
myFile3.dwg

 

 

Should I write a .NET application that generates a "starter script" that opens all the files and runs the generated purge script?

 

 

OPEN "c:/project/myFile1.dwg"
SCRIPT "c:/temp/genScript.scr"
CLOSE N OPEN "c:/project/myFile2.dwg" SCRIPT "c:/temp/genScript.scr" CLOSE N
OPEN "c:/project/myFile3.dwg" SCRIPT "c:/temp/genScript.scr"
CLOSE N

 

and then invoke it by starting an AutoCAD process with the -b parameter:

 

 

 

C:\Program Files\Autodesk\AutoCAD 2018\acad.exe -b C:\temp\starterScript.scr

 

 

Are there a more sophisticated way to solve this somehow?

 

I don't know how this method holds up if you want to run a lisp script in the same fashion for example.

 

Is it better to write a plugin that runs single lines with the SendStringToExecute command.

 

Anybody knows how other applications have approached this problem?

 

Thanks!

0 Likes
3,414 Views
9 Replies
Replies (9)
Message 2 of 10

_gile
Consultant
Consultant
0 Likes
Message 3 of 10

ottosson_mathias
Advocate
Advocate

Accoreconsole is unfortunately very limited and won't work for my needs. It does not support any third party add-ons, or Express tools (which enabled diesel scripts). I need to be able to run the scripts in AutoCAD for this to work.

0 Likes
Message 4 of 10

ottosson_mathias
Advocate
Advocate

Nobody who's got any suggestions? I've been struggling with this issue for a while now and I'm not closer to a solution yet...

 

I would prefer to use an add-in that handles the script somehow.

 

I've tried using the `Document.SendStringToExecute` command, but since it is async it's awkward to work with, and I don't know any good way of using it even though it feels like it could be the solution somehow.

0 Likes
Message 5 of 10

Ed__Jobe
Mentor
Mentor

@ottosson_mathias wrote:

Nobody who's got any suggestions?


Just curious, why not use ScriptPro? Why reinvent the wheel?

Ed


Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
How to post your code.

EESignature

Message 6 of 10

jabowabo
Mentor
Mentor

This is the way I do it - which is likely not the 'Best' way but I haven't discovered that one yet😉.

 

      public static void RunMacro(string dwgFile, string macro)
        {
            macro = macro.Replace(Environment.NewLine, "\n");
            bool dwgIsOpen = false;

            DocumentCollection docs = AcadApp.DocumentManager;

            // Check if dwg is open
            foreach (Document d in docs)
            {
                if (d.Database.Filename == dwgFile)
                {
                    dwgIsOpen = true;

                    if (docs.MdiActiveDocument != d)
                        docs.MdiActiveDocument = d;

                    SendMacroToExecute(macro);
                    break;
                }
            }

            // If the dwg is not open then open it
            if (dwgIsOpen == false)
            {
                if (File.Exists(dwgFile))
                {
                    docs.Open(dwgFile, false);
                    SendMacroToExecute(macro);
                }
                else
                {
                    System.Windows.MessageBox.Show("File " + dwgFile + " does not exist.");
                }
            }
        }

        private static void SendMacroToExecute(string macro)
        {
            // send the macro text
            Document doc = AcadApp.DocumentManager.MdiActiveDocument;
            doc.SendStringToExecute(macro, true, false, true);
        }

And the calling code:

string scrText = macroTextBox.Text;
List<string> dwgFiles = macroFilesListBox.Items.Cast<String>().ToList();

foreach (string dwgFile in dwgFiles)
{
  CommandTools.RunMacro(dwgFile, scrText);
}

 

In this usage case I have a text box with the macro commands and a list box with the dwg file names:

1.PNG

 

 

Message 7 of 10

ottosson_mathias
Advocate
Advocate

I'm working on an application that does more than just scripting and that is very customized to our work flow. Scripting is an essential tool and I want to include it in the application to not have to install yet another one to just run scripts. I also would like to be able to fetch the command window output for each file to be able to process and present it in my application.

0 Likes
Message 8 of 10

ottosson_mathias
Advocate
Advocate

Thanks @jabowabo! That's a bit like I have experimented with it as well. But won't all the files be opened at the same time when you do it like that since SendStringToExecute runs asynchronously?

 

Your code basically does:

            var script = "-purge\na\n*\nn\nqsave\nclose\n";

            var fileList = new List<string>()
            {
                "c:\\test\\1.dwg",
                "c:\\test\\2.dwg",
                "c:\\test\\3.dwg"
            };

            fileList.ForEach(file =>
            {
                var openDocument = DocumentCollectionExtension.Open(Application.DocumentManager, file, false);
                openDocument.SendStringToExecute(script, true, false, true);
            });

which for me is fast enough to open all the files before the scripts have finished...

 

I would like to be able to run some code after the script finishes if it's possible to be able to control when to run the next file. Do you know any way of getting the script to run synchronously or to know when the script finishes somehow?

0 Likes
Message 9 of 10

jabowabo
Mentor
Mentor

@ottosson_mathias wrote:

Thanks @jabowabo! That's a bit like I have experimented with it as well. But won't all the files be opened at the same time when you do it like that since SendStringToExecute runs asynchronously?


Yes, and it's annoying. I've tried getting around it but haven't been successful.

0 Likes
Message 10 of 10

ottosson_mathias
Advocate
Advocate

@jabowaboyes, super annoying!

 

You'd think it would be a good idea to use the BeginDocumentClose event, but the document is still open when this event fires... And I haven't gotten the CloseWillStart event to fire when closing the documents, and I don't think that will work any better anyway, so... back at square one!

 

I've seen other applications do this, so it shouldn't be impossible!

0 Likes