Currently it defaults to my system locale, which is 932 (Japanese Shift-JIS) in my case, but I want it to be 65001 (UTF-8) by default.
I can change the default for a given program by inserting a SetConsoleOutputCP line somewhere in the code and then removing it, but doing it for every program is pretty annoying.
Any suggestions?
This could be done with the standard approach: by composing the registry settings for the executable being debugged. My template dbg_console.reg:
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Console\<encoded_path_to_executable>]
"ScreenBufferSize"=dword:1388012c
"WindowSize"=dword:00340096
"FontSize"=dword:00100000
"FontFamily"=dword:00000036
"FontWeight"=dword:00000190
"FaceName"="Lucida Console"
"HistoryNoDup"=dword:00000000
"QuickEdit"=dword:00000001
"CodePage"=dword:000004e3
<encoded_path_to_executable> is the string where \ is replaced with _.
E.g.: Z:\prj\prj_name\out\debug\bin\program.exe is transformed to Z:_prj_prj_name_out_debug_bin_program.exe.
"CodePage"=dword:000004e3 sets the desired code page. It is important to choose a proper font.
Due to debug mode, the standard settings dialog called on the window header of a program console cannot function properly. However, you can get the desired settings via Windows cmd started with Win+R shortcut. They appear under the folder %SystemRoot%_system32_cmd.exe or alike.
Thus, you exactly get the desired code page in the debug console of your executable without the need to setup code page conditionally at run time. The support of the 65001 code page can be determined from the keys in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage: if there is the key 65001 having appropriate *.nls file, this page is supported.
Related
Is there any way to force displaying ACS variables from ncurses in terminal?
On urxvt and text-mode everything displays well, but on other terminals (i tested on xfce4-terminal, xterm, gnome-terminal)there is always is problem. I tought I can do nothing with this, but I saw that in alsamixer everything displays properly. I loop up for this in alsamixer code and saw they are using exacly same method to display this characters, for examle
addch(ACS_RARROW);
is giving them this result while same command gives me this on same terminal.
On a terminal where your locale says to use UTF-8 (you can see this by the naming convention of values shown by the locale command), you must do this:
compile/link with ncursesw
initialize the locale before initscr, e.g.,
setlocale(LC_ALL, "");
See the Initialization section of the ncurses manual, as well as the Line Graphics section of the addch manual page.
I'm referencing a DLL file containing a C++ class that I need for an API. The default constructor for that class pipes a wall of text to a stream I can't touch, as far as I can tell. I redirected output streams one at a time to try and isolate it, and reached 6 without successfully affecting the text. It's logging data, and I don't care about it in this context; I'd like it to go away.
The text is not returned by the constructor (the object is returned successfully as normal), it's just sent to console during the constructor's execution. I think that's why Out-Null and > $null do nothing.
The text is not evident in the console when I run the same procedure in the ISE! It's a telling clue, and I went looking for environment differences -- but there are a ton of environment differences. Which ones should I investigate?
I think the important difference is that PowerShell.exe is a console subsystem application. Any sort of output to stdout (printf, cout << 'foo', etc) is going to show up in the console. ISE on the other hand, is a Windows subsystem application - no console. What you see as a console pane in ISE, is merely another tool window that looks and behaves like a console just like the NuGet Package Manager console in Visual Studio.
My application is a GUI app that has helpful (though optional) information through the terminal (via cout).
In Windows I either have a console appear (by compiling as a console app, or allocating it dynamically) or I don't.
My intention is to make use of the console IF it is being run from the console, but ignore the console completely if it was not. (Essentially what happens in Linux and OS X).
I do not wish to redirect to a file (and in the case of using cin, this is not a viable solution anyway).
Is there a way to attach a GUI app in Windows to the console it is run from, if and only if it is run from a console?
and in the case of using cin, this is not a viable solution anyway
This is the killer detail in your question. It is simple on paper, just first call AttachConsole(ATTACH_PARENT_PROCESS) to try to attach to an existing console. That will fail when your program got started from a GUI program like Explorer or a desktop shortcut. So if it returns FALSE then call AllocConsole() to create your own console.
Using cin is a problem however. The command processor pays attention to your EXE and checks if it is console mode app or a GUI app. It will detect a GUI app in your case and then doesn't wait for the process to complete. It displays the prompt again and waits for input. You will then also wait for input but you'll lose, the command processor got there first. Your output is also intermingled with the command prompt, the easy problem to solve.
There's a simple workaround for that, your user should start your program with start /wait yourapp to tell the command processor to wait for the process to complete. Problem is: nobody ever uses that. And the user will not realize what happens when they type input, intending it to go into your program but it is actually interpreted by the command processor. Producing a mystifying error message or formatting the hard drive.
Only two good ways to solve this unsolvable problem. Either build your program as a console mode app and call FreeConsole() when you find out you want to display a GUI. Or always call AllocConsole(). These are not great alternatives. The first approach is the one used by the Java JVM on Windows. One of the oldest bugs filed against the JVM and driving Java programmers completely batty from the flashing console window.
The third alternative is the only decent one, and the one you don't want, create another EXE that will always use the console. Like Java does, javaw.exe vs java.exe.
A trick is possible, you can rename that file from "yourapp2.exe" to "yourapp.com". It will be picked first when the user types "yourapp" at the command line prompt, a desktop shortcut can still point to "yourapp.exe". Visual Studio uses this trick, devenv.com vs devenv.exe.
You can check CONSOLE_SCREEN_BUFFER_INFO (via GetConsoleScreenBufferInfo) on startup to determine if you've been run from within an existing console. If the buffer's position is 0,0, you were run from outside of the console. For details, see this Microsoft Knowledgebase Article which describes the process.
In order for this to work, you need to compile your application as a console application (using /SUBSYSTEM:CONSOLE), and then detach yourself from the console if the application started a new console (buffer at 0,0). This will cause the program to properly "attach" to the calling console when launched from a command line.
As others have pointed out you have to create a console app and a window app. So, you'd end up with console.exe and app.exe. To make it less obvious at the command-line, you can take advantage of the PATHEXT trick like devenv does. cmd.exe treats a file as a command if its extension is in the PATHEXT environment variable. COM is there by default so you could rename console.exe as app.com, allowing the command app to start the console app attached to the current console.
Note: Of course, a console app can show a GUI if desired.
The difference in the build between app.com and app.exe depends on your build system but it could just be the one attribute that sets the output type. With msbuild (for .vcxproj files), it's just a matter of another build configuration.
you can create an application in console that get a line using argc and prints it;
////
int main(int argc, char *argv[])
{
//here print argv....using cout or printf
}
save the file as console.exe in the folder of your app.
now in your app if you want to see any line in console you can call the command
system("console.exe this is the line i want to print and see in console");
I'm working on a windows application in C++, and I'd like to use cout for debugging purposes.
It seems that the effects of cout are hidden, is there a configuration option that will allow a console window to open with my debug information?
You have a couple of reasonable options. One is to rename your entrypoint from WinMain to main, so it'll be built as a console application. That can still use things like RegisterClass and CreateWindow just fine.
The obvious alternative would be to use OutputDebugString instead of cout. The output from that will show up in a debugger, or any number of programs built specifically to display what it produces (basically mini-debuggers that just don't provide other debugging capabilities).
A third solution I'd consider less reasonable is to call AllocConsole to allocate a console, then write to it. If you don't mind doing all your writing with Windows-native console functions (WriteFile, WriteConsoleOutput, etc.) that's fine. Unfortunately, it won't initialize the C++ streams to work with the console, so you'll need to either open file streams pointing the console, or else find and use the (undocumented) function that initializes the streams library for the console. While this can be made to work, you end up doing extra work to write non-portable code, and little (if any) advantage to make up for it (and in this case, "non-portable" can include not even working with other versions of the same compiler, at least if you invoke the library's initialization function).
To add a console window to a GUI application, you can use the AllocConsole API.
Then you just need to open the special file name "CONOUT$" and attach your streams to it (cout, cerr, etc)
See this explanation on MSDN.
I believe the accepted answers are actually not what you are looking for. You say you need it only for debugging, not for release. Your best options are:
a) redirect stdout and stderr to a file and then inspect the file. This you can set in the VS project Properties > Configuration Properties > Debugging > Command Arguments: you should enter >out.txt 2>&1. This will output both stdout and stderr to out.txt
b) set your debug (you say you need it only for debugging) configuration Properties > Configuration Properties > Linker > System > SubSystem to Console (/SUBSYSTEM:CONSOLE). Then you can run the project with F5, but it will hide the console window when your application finishes. If you run it with Ctrl+F5 (but then you will not have debugger attached), then it will not be hidden.
The simplest way to do this is to start a Console application from scratch:
In VisualStudio, File > New Project. Select Win32 Console Application. Select various options and create the new project.
Note that although it says Win32 Console Application, you can create x64 builds without restriction.
At this point you have an application shell. If you already have code and you want to bring it in to this new project, simply do Project > Add Existing Item... and select the files to include in the project.
Managing a console from a GUI program is horribly messy, and I suggest you do it another way. For instance, if you need to see the messages in real time, display them in a window; if not, write them to a file.
just use OutputDebugString() but remember to either set your character set to multibyte, or if you don't want to do that, you could write your code like this:
// with multibyte character set:
OutputDebugString("Failed to do something");
// without multibyte character set:
OutputDebugString(L"Failed to do something");
I'm writing a Win32 DLL with a function that adds a directory to the Windows PATH environment variable (to be used in an installer).
Looking at the environment variables in Regedit or the Control Panel after the DLL has run shows me that my DLL has succeeded in adding the path to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment and HKEY_CURRENT_USER\Environment.
But when I start up a new Command Prompt (after running the DLL), the directory I added does not show up in the output of echo %PATH% and I can not access the executable that lives in that directory by typing its name.
I think my program is not doing a good job of notifying the system that the PATH has changed, or maybe it is notifying them before the change has fully taken effect. I read an article by Microsoft that says to broadcast the WM_SETTINGCHANGE message after changing an environment variable, and I am doing that with this code:
DWORD result2 = 0;
LRESULT result = SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0,
(LPARAM)"Environment", SMTO_ABORTIFHUNG, 5000, &result2);
if (result == 0){ /* ... Display error message to user ... */ }
The order of my calls is: RegCreateKeyEx, RegSetValueEx, RegCloseKey, SendMessageTimeout
If I press "OK" in the Control Panel "Environment Variables" window, the changes made by my DLL to the PATH show up in newly-created command prompts, so there is something that the Control Panel is doing to propagate PATH changes; I want to figure out what it is and do the same thing.
Does anyone know what I should do?
I'm running 64-bit Windows Vista but I want this to work on all Windows XP, Vista and Windows 7 operating systems.
Update: The problem with the code I posted above is that I did not put the L prefix on the "Environment" string. Although it does not say it explicitly anywhere in the Microsoft documentation that I can find, the LPARAM needs to be a pointer to a WCHAR string (2-byte characters) as opposed to a CHAR string, which is what Visual Studio's compiler generates by default when I write a string literal. The solution to my problem was to change "Environment" to L"Environment". (I thought I already tried that before posting this question, but apparently I didn't try it correctly!) But anyone who wants a complete C++ solution for this task should look at Dan Moulding's answer.
It turns out there really isn't anything new under the sun. This has already been done before, at least once. By me. I created a DLL very much like what you describe for exactly the same purpose (for use in modifying the path from an NSIS installer). It gets used by the Visual Leak Detector installer.
The DLL is called editenv.dll. The source is available at github. I just tested the installer and it updated the system PATH environment variable, no problem. Based on what you've written, I don't see anything that stands out as being wrong. I also don't see anything obvious that's missing. But it may be worth a look at the editenv.dll source (you'd be most interested in EnvVar::set() in EnvVar.cpp, and possibly the pathAdd() and pathRemove() C APIs in editenv.cpp).
I have a program which calls the same Win32 API to yours to update the environment, and it works fine.
One thing to be careful of is how you are opening up the command prompt.
If you open up the command prompt by doing this:
Start -> Run -> cmd.exe
then the environment in the prompt shows that the new variable is set.
However, I also have a programmable function key on my keyboard which I have set to run the cmd.exe process. If I open a command prompt via that function key and then type env, it doesn't show the variable as being set.
I'm not sure why it works differently, but it must have something to do with the way the cmd.exe process is launched (although both are running under my user name, not SYSTEM).
How are you opening up the command prompt?