none
hide console of DLL import RRS feed

Answers

  • Following example uses an alternate console buffer to keep the output written by a C++ dll from appearing with the output of a C# console application.

    The C++ dll exports two functions to demonstrate that both the standard ouput stream and the standard error stream can be redirected to the alternate buffer.

    Example C++ dll code -

    #include <iostream>
    #include <cstdio>
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    __declspec(dllexport) void TestOut(wchar_t* psz)
    {
    	fwprintf_s(stdout, L"%s\n", psz);
    	//std::wcout << psz << std::endl;
    }
    
    __declspec(dllexport) void TestErr(wchar_t* psz)
    {
    	fwprintf_s(stderr, L"%s\n", psz);
    	//std::wcerr << psz << std::endl;
    }
    
    #ifdef __cplusplus
    }
    #endif
    

    Example code for C# console application -

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Runtime.InteropServices;
    using System.ComponentModel;
    
    namespace CSHidecon
    {
        class Program
        {
            [DllImport("Test.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode, ExactSpelling = true)]
            static private extern void TestOut(string str);
    
            [DllImport("Test.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode, ExactSpelling = true)]
            static private extern void TestErr(string str);
    
            [DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto, SetLastError = true)]
            static public extern IntPtr CreateConsoleScreenBuffer(uint dwDesiredAcess, uint dwShareMode, IntPtr lpSecurityAttributes, uint dwFlags, IntPtr lpScreenBufferData);
    
            [DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto, SetLastError = true)]
            static public extern bool SetConsoleActiveScreenBuffer(IntPtr hConsoleOutput);
    
            [DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto, SetLastError = true)]
            static public extern bool CloseHandle(IntPtr hObject);
    
            [DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto, SetLastError = true)]
            static public extern IntPtr GetStdHandle(uint nStdHandle);
    
            [DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto, SetLastError = true)]
            static public extern bool SetStdHandle(uint nStdHandle, IntPtr hHandle);
    
            [DllImport("user32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
            static public extern int MessageBox(IntPtr hwnd, string lpText, string lpCaption, uint type);
    
            static void Main(string[] args)
            {
                try
                {
                    const uint accessMode = 0x40000000; // GENERIC_WRITE
                    const uint STD_OUTPUT_HANDLE = unchecked((uint)-11);
                    const uint STD_ERROR_HANDLE = unchecked((uint)-12);
                    IntPtr INVALID_HANDLE_VALUE = (IntPtr)(-1);
    
                    IntPtr hBuffer = CreateConsoleScreenBuffer(accessMode, 0, IntPtr.Zero, 1, IntPtr.Zero);
    
                    if (hBuffer == INVALID_HANDLE_VALUE)
                        throw new Win32Exception(Marshal.GetLastWin32Error());
    
                    IntPtr hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
                    IntPtr hStdErr = GetStdHandle(STD_ERROR_HANDLE);
                    if (hStdOut == INVALID_HANDLE_VALUE || hStdErr == INVALID_HANDLE_VALUE)
                        throw new Win32Exception(Marshal.GetLastWin32Error());
    
                    if (SetStdHandle(STD_OUTPUT_HANDLE, hBuffer) && SetStdHandle(STD_ERROR_HANDLE, hBuffer))
                    {
                        TestOut("First test string");
                        TestErr("First err string");
    
                        // Restore original console buffers before calling Console.WriteLine
                        if (!SetStdHandle(STD_OUTPUT_HANDLE, hStdOut) || !SetStdHandle(STD_ERROR_HANDLE, hStdErr))
                            throw new Win32Exception(Marshal.GetLastWin32Error());
                    }
                    else
                        throw new Win32Exception(Marshal.GetLastWin32Error());
    
                    Console.WriteLine("Written by C#");
    
                    TestOut("Second test string");
                    TestErr("Second err string");
    
                    Console.WriteLine("Again, written by C#");
    
                    MessageBox(IntPtr.Zero, "Press OK Button to dispay dll output", "Switch Console Buffer", 0);
    
                    if (!SetConsoleActiveScreenBuffer(hBuffer))
                        throw new Win32Exception(Marshal.GetLastWin32Error());
    
                    MessageBox(IntPtr.Zero, "Press OK Button to return to C# Output", "Switch Console Buffer", 0);
    
                    if (!SetConsoleActiveScreenBuffer(hStdOut))
                        throw new Win32Exception(Marshal.GetLastWin32Error());
    
                    CloseHandle(hBuffer);
    
                }
                catch (Exception e)
                {
                    Console.WriteLine("Exception : {0}", e.Message);
                }
            }
        }
    }
    

    And running the sample console application displays the following --

    and then

    and finally

    Friday, December 20, 2019 3:29 PM

All replies

  • What console log and from what imported DLL ?

    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    Thursday, December 19, 2019 11:56 AM
    Moderator
  • Hi,

    thank for your attention,

    I import into my software a DLL that is stored in folder C: \ Windows \ SysWOW64, in this DLL there are a number of functions that I run through my software.
    My software is written in C # and the project is a console application type
    The problem is that console writes written in the internal functions of the DLL appear to be written to my software console.
    For example "recv failed with error: -1" console -- come from the DLL - i dont want it to be written in mu console.

    I import the DLL in this way:

     [DllImport("Test.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "Test")]

    thanks

    Pnina


    pnina

    Thursday, December 19, 2019 1:02 PM
  • Hi,

    Thank you for posting here.

    When we develop a class library, there is an easy way to hide the print log.

    if (xxx)
    {
        Console.WriteLine("xxx");
    }

    Add a judgment condition to each output statement, and then the user decides whether to output this line by passing in parameters.

    However, all this happens during the development of the class library. When we use a dll file, if the developer does not provide similar functions, I am afraid we have no way to hide the output.

    Best Regards,

    Timon


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, December 20, 2019 2:50 AM
  • Hello pnina,

    1. One way to achieve you objective is to re-direct the console outputs to a file whenever you call a DLL function.

    2. Here is a sample code to perform re-direction of console output to file and back to console again :

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.IO;
    
    namespace ConsoleApp1
    {
        class Program
        {
            static void RedirectOutputToFile()
            {
                if (swFile == null)
                {
                    FileStream fs = new FileStream("C:\\Test.txt", FileMode.Append);
                    // First, save the standard output.
                    if (twConsole == null)
                    {
                        twConsole = Console.Out;
                    }
                    swFile = new StreamWriter(fs);
                    Console.SetOut(swFile);                
                }
            }
    
            static void RedirectOutputToConsole()
            {
                if (twConsole != null)
                {
                    Console.SetOut(twConsole);
                    twConsole = null;
                }
    
                if (swFile != null)
                {
                    swFile.Close();
                    swFile = null;
                }
            }
    
            static void DoTest()
            {
                Console.WriteLine("Hello World");
    
                RedirectOutputToFile();
                Console.WriteLine("Hello file");
    
                RedirectOutputToConsole();
                Console.WriteLine("Hello World");
    
                RedirectOutputToFile();
                Console.WriteLine("Hello file");
    
                if (swFile != null)
                {
                    swFile.Close();
                    swFile = null;
                }
            }
    
            static void Main(string[] args)
            {
                DoTest();
            }
    
            private static TextWriter twConsole = null;
            private static StreamWriter swFile = null;
        }
    }
    

    3. Call the RedirectOutputToFile() method just before calling the DLL function, and then call RedirectOutputToConsole() right after that.

    4. Hope this can be helpful.

    Bio.


    Please visit my blog : http://limbioliong.wordpress.com/

    Friday, December 20, 2019 4:45 AM
  • Following example uses an alternate console buffer to keep the output written by a C++ dll from appearing with the output of a C# console application.

    The C++ dll exports two functions to demonstrate that both the standard ouput stream and the standard error stream can be redirected to the alternate buffer.

    Example C++ dll code -

    #include <iostream>
    #include <cstdio>
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    __declspec(dllexport) void TestOut(wchar_t* psz)
    {
    	fwprintf_s(stdout, L"%s\n", psz);
    	//std::wcout << psz << std::endl;
    }
    
    __declspec(dllexport) void TestErr(wchar_t* psz)
    {
    	fwprintf_s(stderr, L"%s\n", psz);
    	//std::wcerr << psz << std::endl;
    }
    
    #ifdef __cplusplus
    }
    #endif
    

    Example code for C# console application -

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Runtime.InteropServices;
    using System.ComponentModel;
    
    namespace CSHidecon
    {
        class Program
        {
            [DllImport("Test.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode, ExactSpelling = true)]
            static private extern void TestOut(string str);
    
            [DllImport("Test.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode, ExactSpelling = true)]
            static private extern void TestErr(string str);
    
            [DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto, SetLastError = true)]
            static public extern IntPtr CreateConsoleScreenBuffer(uint dwDesiredAcess, uint dwShareMode, IntPtr lpSecurityAttributes, uint dwFlags, IntPtr lpScreenBufferData);
    
            [DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto, SetLastError = true)]
            static public extern bool SetConsoleActiveScreenBuffer(IntPtr hConsoleOutput);
    
            [DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto, SetLastError = true)]
            static public extern bool CloseHandle(IntPtr hObject);
    
            [DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto, SetLastError = true)]
            static public extern IntPtr GetStdHandle(uint nStdHandle);
    
            [DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto, SetLastError = true)]
            static public extern bool SetStdHandle(uint nStdHandle, IntPtr hHandle);
    
            [DllImport("user32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
            static public extern int MessageBox(IntPtr hwnd, string lpText, string lpCaption, uint type);
    
            static void Main(string[] args)
            {
                try
                {
                    const uint accessMode = 0x40000000; // GENERIC_WRITE
                    const uint STD_OUTPUT_HANDLE = unchecked((uint)-11);
                    const uint STD_ERROR_HANDLE = unchecked((uint)-12);
                    IntPtr INVALID_HANDLE_VALUE = (IntPtr)(-1);
    
                    IntPtr hBuffer = CreateConsoleScreenBuffer(accessMode, 0, IntPtr.Zero, 1, IntPtr.Zero);
    
                    if (hBuffer == INVALID_HANDLE_VALUE)
                        throw new Win32Exception(Marshal.GetLastWin32Error());
    
                    IntPtr hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
                    IntPtr hStdErr = GetStdHandle(STD_ERROR_HANDLE);
                    if (hStdOut == INVALID_HANDLE_VALUE || hStdErr == INVALID_HANDLE_VALUE)
                        throw new Win32Exception(Marshal.GetLastWin32Error());
    
                    if (SetStdHandle(STD_OUTPUT_HANDLE, hBuffer) && SetStdHandle(STD_ERROR_HANDLE, hBuffer))
                    {
                        TestOut("First test string");
                        TestErr("First err string");
    
                        // Restore original console buffers before calling Console.WriteLine
                        if (!SetStdHandle(STD_OUTPUT_HANDLE, hStdOut) || !SetStdHandle(STD_ERROR_HANDLE, hStdErr))
                            throw new Win32Exception(Marshal.GetLastWin32Error());
                    }
                    else
                        throw new Win32Exception(Marshal.GetLastWin32Error());
    
                    Console.WriteLine("Written by C#");
    
                    TestOut("Second test string");
                    TestErr("Second err string");
    
                    Console.WriteLine("Again, written by C#");
    
                    MessageBox(IntPtr.Zero, "Press OK Button to dispay dll output", "Switch Console Buffer", 0);
    
                    if (!SetConsoleActiveScreenBuffer(hBuffer))
                        throw new Win32Exception(Marshal.GetLastWin32Error());
    
                    MessageBox(IntPtr.Zero, "Press OK Button to return to C# Output", "Switch Console Buffer", 0);
    
                    if (!SetConsoleActiveScreenBuffer(hStdOut))
                        throw new Win32Exception(Marshal.GetLastWin32Error());
    
                    CloseHandle(hBuffer);
    
                }
                catch (Exception e)
                {
                    Console.WriteLine("Exception : {0}", e.Message);
                }
            }
        }
    }
    

    And running the sample console application displays the following --

    and then

    and finally

    Friday, December 20, 2019 3:29 PM