.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

AcCoreConsole.exe .in 2015 doesn't do System.Console.WriteLine() like 2013?

28 REPLIES 28
SOLVED
Reply
Message 1 of 29
CADbloke
7032 Views, 28 Replies

AcCoreConsole.exe .in 2015 doesn't do System.Console.WriteLine() like 2013?

Greetings,  I have the same tests (same code!) written in NUnit and running in the NUnitLite version 3 runner. How, you ask? - https://github.com/CADbloke/CADtest but I digress...

 

BUT, the tests run fine and look great in the v2013 x64 accoreconsole.exe but v2015 x64 is rubbish. The code does actually run the tests in both versions and produces the same TestResults.xml but the results don't show on the commandline in v2015. Just to add to the joy, the text it does write to the console writes telex-style, slowly, taking a few seconds to write a whole line (well, the 1st line anyway). 

 

What happened?

Is accoreconsole.exe different in v2015?

Did I break it? (yes, I re-installed AutoCAD 2015).

Does v2015 not support System.console.Write...?

 

here are 2,000 words in pictures.

 

2013 looks nice

CoreConsole2013.png

 

2015 sucks. WHY?

CoreConsole2015.png

- - - - - - -
working on all sorts of things including www.tvCAD.tv & www.CADreplace.com
28 REPLIES 28
Message 2 of 29
autodaug
in reply to: CADbloke

Something did apparently change in the CoreConsole command window implementation - I'm not sure yet what or why. It's also an issue with the upcoming release.

 

It appears that you can at least avoid the line repetition problem by limiting the output line length to fewer than (approx) 100 characters. Don't see a workaround for the slow output, though.

 

Not sure what the support policy is for CoreConsole but will look into it a bit more..

 

Message 3 of 29
CADbloke
in reply to: autodaug

Thanks @autodaug, I'm quite surprised that I would be the first person to notice this. I'm eagerly waiting to hear what you find out.
- - - - - - -
working on all sorts of things including www.tvCAD.tv & www.CADreplace.com
Message 4 of 29
autodaug
in reply to: CADbloke

Well, I had noticed it but hadn't gotten around to looking into it. Your post gave me the extra motivation to dig into it 🙂

 

There is some redirection of stdout and stderr that is done by CoreConsole at initialization time. It directs these outputs to a temp file with the name "acccXXXX" in your temp dir. That seems to be causing the slow "teletype-like" console output. I think this redirection is done for internal Autodesk uses of CoreConsole and is not necessarily something that external users of CoreConsole need.

 

One way to undo the stdout redirection is to run this little piece of native code:

 

    FILE * f = _wfopen(L"CONOUT$", L"w");
    if (f)
      _dup2(_fileno(f), 1);

 I don't know yet if this is the best way to do it, or even if it will help in your case. But it seemed to help in my testing and is worth a try...

Message 5 of 29
CADbloke
in reply to: autodaug

Interesting - thanks for looking into it - I'm willing to bet it's for AutoCAD.IO.

All my code is in managed C# (or Lisp) - I wouldn't have a clue what to do with this native code. I think there's going to be issues trying to redirect the console output from C#... http://stackoverflow.com/questions/2646434/problems-with-console-setout-in-release-mode

...or not ... http://stackoverflow.com/a/15960495/492 ... http://stackoverflow.com/a/718505/492

I don't have 2015 on the PC I'm on at the moment so I'll have to try it at home while the rest of the world is sleeping.

- - - - - - -
working on all sorts of things including www.tvCAD.tv & www.CADreplace.com
Message 6 of 29
CADbloke
in reply to: autodaug

Nup, hijacking the Console output back to standard in C# didn't work for me. I used http://stackoverflow.com/a/14100502/492 which did have an effect - it stopped the contents of all those accc... temp files populating. $Deity knows where all that text actually went.

- - - - - - -
working on all sorts of things including www.tvCAD.tv & www.CADreplace.com
Message 7 of 29
autodaug
in reply to: CADbloke

I haven't tried it, but that looks like a reasonable way to undo the stdout redirection in C#.

 

When you say it doesn't work, are you looking at output from CoreConsole or from your own calls to Console.WriteLine, or both? I'm seeing Console.WriteLine output happen very fast, but I still get the teletype behavior for CoreConsole's output (such as from the list command, e.g.).

 

Message 8 of 29
CADbloke
in reply to: autodaug

I still get all the garbage in the Core Console window but nothing in the temp file except for some closing remark about a graphics kernel still having a reference which was there in all of the temp files which is probably another bug but meh.

Usually the temp files had the content I expected to see in the console window until I broke it with that code.
- - - - - - -
working on all sorts of things including www.tvCAD.tv & www.CADreplace.com
Message 9 of 29
autodaug
in reply to: CADbloke

Yeah, the garbage in the output window appears to be due to some bug with output lines longer than about 100 chars. So a work around might be to try to limit the length of these lines. E.g., in your netload of the long file path above, you could define a short symbolic link to that file path, and just load the symbolic link.

 

I'm not an official spokesperson, but it doesn't seem like AcCoreConsole is targeted for interactive use, currently. It's used more for batch processing, with input coming from script files..

 

 

Message 10 of 29
CADbloke
in reply to: autodaug


@autodaug wrote:

I'm not an official spokesperson, but it doesn't seem like AcCoreConsole is targeted for interactive use, currently. It's used more for batch processing, with input coming from script files..

 


Perhaps but they did ship a version that worked (v2013) and it is called "Console" so you would reasonably expect it to do input / output. Also, if is only for batch operations the ScriptPro should be bundled with AutoCAD too.

 

As for the 100-character workaround, thanks for working this out, it's not pretty and I'd only do it in an emergency which is unlikely, given that this isn't an ambulance. Stop the presses: I found an easier workaround, in the console window that opens, click the top-left icon of the window => "Defaults"=> , Layout tab, set the screen buffer size width and windows size widths to something silly like 150, it still does the telex-machine thing but at least it doesn't repeat itself.

 

For anyone who does want to try the Symbolic-link route, try http://schinagl.priv.at/nt/hardlinkshellext/hardlinkshellext.html

 

for anyone following at home, http://forums.autodesk.com/t5/net/accoreconsole-disappointed-with-performance/td-p/5483572 is related to this.

 

- - - - - - -
working on all sorts of things including www.tvCAD.tv & www.CADreplace.com
Message 11 of 29
autodaug
in reply to: CADbloke

I should have said it's more used within Autodesk for script processing. I'm not sure there has been much focus yet on how it will be used by 3rd parties.

 

Good find about the the layout tab! It might be nice if we could turn off line wrap altogether, but I don't see a way to do that.

 

And I think I found a way to turn off the telex-like slowdown, using this simple call:

    _setmode(3, _O_TEXT);

I did this after setting stdout back to CONOUT$, and I get fast output now. This is native C++, but maybe you can import _setmode() from msvcr1xx.dll and call it from your C#. The _O_TEXT value is from fcntl.h and is 0x4000.

Message 12 of 29
autodaug
in reply to: autodaug

And here it is in C#. The output slowdown seems to be caused by AcCoreConsole calling _setmode with mode _O_U16TEXT (0x20000). Changing it back to the default _O_TEXT seems to fix it.

 

    public class MyTest
    {
        [DllImport("msvcr110.dll")]
        private static extern int _setmode(int fileno, int mode);
        public void FixStdOut()
        {
            _setmode(3, 0x4000);
        }

 

Message 13 of 29
CADbloke
in reply to: autodaug

Thanks for all your help @autodaug. The teletext-busting FixStdOut() didn't work for me. 😞  I did get the console to display the text but not in color, which it does just fine when you attach a console to acad.exe. Here's the code which runs it both ways...

 

 

 

using System;
using System.Runtime.InteropServices;
using Autodesk.AutoCAD.ApplicationServices.Core;
using Autodesk.AutoCAD.Runtime;

[assembly: ExtensionApplication(typeof (CADTestRunner.NUnitRunnerApp))]

namespace CADTestRunner
{
  /// <summary> AutoCAD extension application implementation. </summary>
  /// <seealso cref="T:Autodesk.AutoCAD.Runtime.IExtensionApplication"/>
  public class NUnitRunnerApp : IExtensionApplication
  {
    public void Initialize()
    {
#if !CoreConsole
      if ( !AttachConsole(-1) )  // Attach to a parent process console
      AllocConsole(); // Alloc a new console if none available
#else
// http://forums.autodesk.com/t5/net/accoreconsole-exe-in-2015-doesn-t-do-system-console-writeline/m-p/5551652
// This code is so you can see the test results in the console window, as per the above forum thread.
      if (Application.Version.Major * 10 + Application.Version.Minor > 190) // >v2013
      {
        // http://stackoverflow.com/a/15960495/492
        // stdout's handle seems to always be equal to 7
        IntPtr defaultStdout = new IntPtr(7);
        IntPtr currentStdout = GetStdHandle(StdOutputHandle);
        if (currentStdout != defaultStdout) { SetStdHandle(StdOutputHandle, defaultStdout); }
        
// http://forums.autodesk.com/t5/net/accoreconsole-exe-in-2015-doesn-t-do-system-console-writeline/m-p/5551652#M43708
        FixStdOut();
      }
#endif
    }


    public void Terminate()
    {
#if !CoreConsole
      FreeConsole();
#endif
    }



// http://stackoverflow.com/questions/3917202/how-do-i-include-a-console-in-winforms/3917353#3917353
    /// <summary> Allocates a new console for current process. </summary>
    [DllImport("kernel32.dll")]
    public static extern Boolean AllocConsole();

    /// <summary> Frees the console. </summary>
    [DllImport("kernel32.dll")]
    public static extern Boolean FreeConsole();

    // http://stackoverflow.com/a/8048269/492
    [DllImport("kernel32.dll")]
    private static extern bool AttachConsole(int pid);


#if CoreConsole
// http://forums.autodesk.com/t5/net/accoreconsole-exe-in-2015-doesn-t-do-system-console-writeline/m-p/5551652#M43708
// trying to fix the telex-like line output from Core Console in versions > 2013. This didn't work for me. :(
    [DllImport("msvcr110.dll")]
    private static extern int _setmode(int fileno, int mode);
    public void FixStdOut() { _setmode(3, 0x4000); }


// http://stackoverflow.com/a/15960495/492
    private const UInt32 StdOutputHandle = 0xFFFFFFF5;
    [DllImport("kernel32.dll")]
    private static extern IntPtr GetStdHandle(UInt32 nStdHandle);
    [DllImport("kernel32.dll")]
    private static extern void SetStdHandle(UInt32 nStdHandle, IntPtr handle);
#endif
  }
}

 

- - - - - - -
working on all sorts of things including www.tvCAD.tv & www.CADreplace.com
Message 14 of 29
autodaug
in reply to: CADbloke

That's too bad that the _setmode() didn't work. I verified again that it fixes the tty-like output in my 2016 build. I looked at the AcCoreConsole differences between 2015 and 2016 and it looks like the fix should work for 2015, but I haven't tried it yet. Btw, I'm testing it by opening a dwg containing a dozen or so entities and just doing a "list all" command. So the output is coming from AcCoreConsole's internal command line echo-ing, not from calls to Console.WriteLine().

 

I think this ultimately needs to be fixed in AcCoreConsole by giving it a command line switch which tells it to not do the output redirection. This redirection stuff appears to be for internal Autodesk reasons involving specific deployments of AcCoreConsole which may not resemble what you're trying to do..

 

Message 15 of 29
CADbloke
in reply to: autodaug

I haven't tried it in v2016 yet. What do you reckon I did differently? Perhaps my Core Console installation is loading things before I call FixStdOut(); perhaps it doesn't work if there has already been a write to the Console?


"I think this ultimately needs to be fixed in AcCoreConsole..." <== yup, I agree. It's a shame they broke it since running CADtest in the 2013 core console is great, it takes about 1 second between Ctrl-F5 and the test results - in glorious colo(u|)r too. I haven't heard anything back on the Support ticket you opened but I guess they have been a little preoccupied this week.

I think the internal usages of the Core Console should take responsibility for redirecting the output rather than baking it in, imho. It should just work as a standard console.
- - - - - - -
working on all sorts of things including www.tvCAD.tv & www.CADreplace.com
Message 16 of 29
autodaug
in reply to: CADbloke

The redirection is one of the first things AcCoreConsole does at startup, so I don't think it matters how soon or how late your app sends display outout or calls FixStdOut. In my testing, I can list all of the entities in the slow tty mode as many times as I want, then run FixStdOut and then list them again in fast mode.

 

But it could be due to some obscure difference in our systems. I'm not even sure why _setmode(_O_TEXT) works (on my system), or what _setmode (_O_U16TEXT) does inside the C runtime lib to cause the slowdown in the first place.

 

One more thing you could try is making sure that your call to _setmode() is succeeding. It could fail if you were using a different version of the msvc lib, such as a debug version or an earlier release of msvc. You can check the return code to _setmode() - it should return 0x20000 (the previous mode) if it succeeds, and -1 if it fails.

 

And then finally I can get an actual 2015 build some time tomorrow and make sure the workaround works there..

 

 

 

 

 

 

 

 

Message 17 of 29
CADbloke
in reply to: autodaug


@autodaug wrote:

You can check the return code to _setmode() - it should return 0x20000 (the previous mode) if it succeeds, and -1 if it fails.

 


This just keeps getting more interesting. In v2015 x64 Win7 it returned 0x10000 - 65536. Do I get half-marks for that? 😉

 

_setmode() worked because I added a second call and that returned 0x4000 - 16384, as expected.

 

I also tried it with the SetStdHandle() code commented out and it was the same result. I had to stop it in the debugger to see the because Console.WriteLine() didn't work.

 

I migh tbe tired (or old) but the Teletext machine seems a little faster today, as it types to the waiting world (I said I was old).

 

For anyone playing along at home, this is the replacement code I used at line 34 of the code I posted above...

 

int x = FixStdOut();
string hexx = x.ToString("X4");
Console.WriteLine("Setmode hex = " + hexx + "  ... Int = " +x);

int y = FixStdOut();
string hexy = y.ToString("X4");
Console.WriteLine("Setmode redo hex = " + hexy + "  ... Int = " +y);

 

- - - - - - -
working on all sorts of things including www.tvCAD.tv & www.CADreplace.com
Message 18 of 29
autodaug
in reply to: CADbloke

I finally got my 2015 build up and running, and for me it acts like 2016 did. The _setmode() call returns 0x4000, and it fixes the slowness. So much for the theory that it was a difference between 2015 and 2016. So unfortunately I'm still not clear why we are seeing different results.

 

That 0x10000 value you're getting back from _setmode() is curious. I wonder if you could try calling _setmode() on some other file numbers besides 3, such as 4 or 5. In my case I get an assert and crash with _setmode(4, 0x4000), apparently because there is no file number 4..

 

Message 19 of 29
CADbloke
in reply to: autodaug

I tried using 4 & 5 but they both crashed. I tried running it in a VM in both v2015 & 2016 using "3" and got the same returned results from _setmode() from both as I did on my desktop.

 

for

currentStdout = GetStdHandle(StdOutputHandle);

 on ...

desktop v2015 currentStdout  == 196, 

VM v 2016 == 180

VM v2015 == 36

 

I'm not sure what to make of that.

 

Just to add to the fun, 2016 crashed with an Access Violation when disposing of using (db.TransactionManager.StartTransaction()); in SampleTests.cs @ line 57 (in the CADtest Github repo). Even weirder. Although I did compile it with the 2015 SDK DLLs so there may be an incompatibility there. The Joys.

- - - - - - -
working on all sorts of things including www.tvCAD.tv & www.CADreplace.com
Message 20 of 29
autodaug
in reply to: CADbloke

I finally found out what's going on. The redirection of stdout to a temp file was done at the request of external developers. There is a bunch of "garbage" output that various AutoCAD components send to stdout, consisting of trace messages and other things not intended to be seen by users. Since AutoCAD is a windows (not console) app, this output was never seen before AcCoreConsole came along.  In response to complaints about the garbage output appearing in AcCoreConsole, we added the stdout redirection as a way to hide it, while still displaying editor output on the console.

 

We can add a switch to turn off this redirection, but then you will see the garbage output mixed in with the regular editor output. You must have seen that already, in 2014 AcCoreConsole?

 

The other option is for you to send your text output through the editor, using Editor.WriteMessage instead of calling Console.WriteLine. Then your output will appear along with the editor's output, without the garbage text. (You're probably already doing this with 2015.) Not sure if your text coloring will still work - hopefully so. Outputting to the editor has the added benefit that if your app is loaded into regular AutoCAD, your text will appear on the command line.

 

About using the command line to redirect output to a file, as in "AcCoreConsole /i foo.dwg /s foo.scr > foo.out", that still works (in 2016 anyway). The output file will be UTF-16, however, instead of the usual ansi text. This was also at the request of external developers.

 

As for the slow output and messed up long line scrolling, those are being tracked as bugs, and we've shown some partial workarounds. The good news is that the work on AcCoreConsole is affected by external developer feedback, contrary to what I implied a few posts ago..

 

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Forma Design Contest


Autodesk Design & Make Report