I want to try some C libraries that are only available in windows so i installed wine and install dev C++.
Unlike on windows, after i compile and run, it successfuly generate/compile into "exe" but the cmd is not showing up .
I found a way on how to run the exe by launching the terminal and putting
$wine cmd
$myc.exe
It works but it takes time to manually launch the "exe".
How can i make dev c++ to automatically find cmd in wine and execute the compiled code?
Thank you in advance.
UPDATE :
The time I posted this question, I'm new to Linux/Ubuntu that's why I'm looking/expecting for that functionality in wine. But now after 2 years amany months i figured out that codeblock running on wine which is for windows and cannot call ubuntu terminal once compiled.
Dev-C++, by default, relies on a simple file called ConsolePauser.exe. This file calls the compiled .exe file, and gives the familiar Process exited after 0.xxxxx seconds with return value x. notice after it exits.
However, ConsolePauser.exe is a native Windows binary, it cannot be executed in Ubuntu, unless called by Wine. Also, the ConsolePauser calls the bare name of the executable, instead of a call to Wine, which is required.
Therefore, what you need to do to make Dev-C++ to run .exe files automatically after you press F9 is to build your OWN ConsolePauser. This is quite simple, actually:
#include <chrono>
#include <iostream>
#include <string>
int main(int agrc, char ** argv)
{
using namespace std;
string s = argv[1];
string s1;
for (const auto & ss : s)
{
if ((ss == ' ') || (ss == '\\')) s1.push_back('\\');
s1.push_back(ss);
}
s = "wine " + s1;
auto begin = chrono::high_resolution_clock::now();
auto retVal = system(s.c_str());
auto end = chrono::high_resolution_clock::now();
cout << "-------------------------------------" << endl;
cout << "Process completed after " << chrono::duration_cast<chrono::milliseconds>(end - begin).count();
cout << " milliseconds with return value " << retVal << "." << endl;
cout << "Press any key to continue. . ." << endl;
cin.get();
return 0;
}
What it simply does is parsing the argument, escaping required characters, and pass it to Wine. It is a quick and dirty version, you start improving it by checking if argc == 1.
Compile it as ConsolePauser.exe with Ubuntu's compiler, put it anywhere in your computer's PATH and it should work.
Another problem exists, however. For unknown reasons, Ubuntu's executables don't get executed in a separate window, if called by an app like Dev-C++, unlike Windows. Therefore, you will have to find a way to bring the ConsolePauser.exe to a new window.
A simple approach is rename your file to ConsolePauser1.exe, and use this code for ConsolePauser.exe:
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char ** argv)
{
string s = argv[1];
//Opens new window through gnome-terminal:
string command = "gnome-terminal -e ";
command += string("\"") + "bash -c ";
command += string("\\\"") + "ConsolePauser1.exe ";
command += string("\\\\\\\"") + s;
command += string("\\\\\\\"");
command += string("\\\"");
command += string("\"");
system(command.c_str());
cerr << command << endl;
//Make sure that window lingers...
system("exec bash");
return 0;
}
Put these two files in the same folder in your PATH, and the familiar old Console Pauser will work like a charm.
I'd like to submit my approach, although it is not specific to Ubuntu. It can work with any distro with xterm installed.
Rename ConsolePauser.exe to ConsolePauserEngine.exe and create a new ConsolePauser.exe text file in the same dir with the following lines:
#! /bin/sh
CMD=$(printf "%q" $#) #https://stackoverflow.com/questions/2854655/command-to-escape-a-string-in-bash#answer-2856010
CONSOLE_PAUSER_PATH=$(printf "%q" "C:\Program Files (x86)\Dev-Cpp\ConsolePauserEngine.exe")
xterm -e "wine $CONSOLE_PAUSER_PATH $CMD"
EDIT: Don't forget to make the new ConsolePauser.exe executable.
Related
I was taking a look at this Github project: https://github.com/LloydLabs/delete-self-poc
This project uses the SetFileInformationByHandle API (https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-setfileinformationbyhandle) in a somewhat creative way to allow the deletion from disk of a locked file. I am attempting to implement this as part of a larger program, however I have ran into an issue when compiling for x86. I use mingw-w64 on a debian machine to compile my program and when doing compatibility checks for x86, I found a very strange issue.
#include "main.h"
static
HANDLE
ds_open_handle(
PWCHAR pwPath
)
{
return CreateFileW(pwPath, DELETE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
}
static
BOOL
ds_rename_handle(
HANDLE hHandle
)
{
FILE_RENAME_INFO fRename;
RtlSecureZeroMemory(&fRename, sizeof(fRename));
// set our FileNameLength and FileName to DS_STREAM_RENAME
LPWSTR lpwStream = DS_STREAM_RENAME;
fRename.FileNameLength = sizeof(lpwStream);
RtlCopyMemory(fRename.FileName, lpwStream, sizeof(lpwStream));
return SetFileInformationByHandle(hHandle, FileRenameInfo, &fRename, sizeof(fRename) + sizeof(lpwStream));
}
static
BOOL
ds_deposite_handle(
HANDLE hHandle
)
{
// set FILE_DISPOSITION_INFO::DeleteFile to TRUE
FILE_DISPOSITION_INFO fDelete;
RtlSecureZeroMemory(&fDelete, sizeof(fDelete));
fDelete.DeleteFile = TRUE;
return SetFileInformationByHandle(hHandle, FileDispositionInfo, &fDelete, sizeof(fDelete));
}
int
main(
int argc,
char** argv
)
{
WCHAR wcPath[MAX_PATH + 1];
RtlSecureZeroMemory(wcPath, sizeof(wcPath));
// get the path to the current running process ctx
if (GetModuleFileNameW(NULL, wcPath, MAX_PATH) == 0)
{
DS_DEBUG_LOG(L"failed to get the current module handle");
return 0;
}
HANDLE hCurrent = ds_open_handle(wcPath);
if (hCurrent == INVALID_HANDLE_VALUE)
{
DS_DEBUG_LOG(L"failed to acquire handle to current running process");
return 0;
}
// rename the associated HANDLE's file name
DS_DEBUG_LOG(L"attempting to rename file name");
if (!ds_rename_handle(hCurrent))
{
DS_DEBUG_LOG(L"failed to rename to stream");
return 0;
}
DS_DEBUG_LOG(L"successfully renamed file primary :$DATA ADS to specified stream, closing initial handle");
CloseHandle(hCurrent);
// open another handle, trigger deletion on close
hCurrent = ds_open_handle(wcPath);
if (hCurrent == INVALID_HANDLE_VALUE)
{
DS_DEBUG_LOG(L"failed to reopen current module");
return 0;
}
if (!ds_deposite_handle(hCurrent))
{
DS_DEBUG_LOG(L"failed to set delete deposition");
return 0;
}
// trigger the deletion deposition on hCurrent
DS_DEBUG_LOG(L"closing handle to trigger deletion deposition");
CloseHandle(hCurrent);
// verify we've been deleted
if (PathFileExistsW(wcPath))
{
DS_DEBUG_LOG(L"failed to delete copy, file still exists");
return 0;
}
DS_DEBUG_LOG(L"successfully deleted self from disk");
return 1;
}
When compiling the base code found in the linked repository (and shown above) as x86, attempting to run the program fails at the SetFileInformationByHandle call in the ds_rename_handle function. Calling GetLastError() returns 123:
ERROR_INVALID_NAME
123 (0x7B)
The filename, directory name, or volume label syntax is incorrect.
The very bizarre part is that the program succeeds when ran from an Administrator prompt. Even stranger, compiling the same code for x64 works both in a normal and an Administrator prompt.
As a sanity check I copied the code verbatim over to VS2019 and compiled there, and the resulting x86 program was able to run without Administrator privileges.
The only changes to the source code made on the debian system were made in the header file:
#pragma once
#pragma comment(lib, "Shlwapi.lib")
#include <Windows.h>
#include <shlwapi.h>
#include <stdio.h>
#include <stdlib.h>
#define DS_STREAM_RENAME L":wtfbbq"
#define DS_DEBUG_LOG(msg) wprintf(L"[LOG] - %s\n", msg)
Where <Windows.h> was changed to <windows.h> and the DS_DEBUG_LOG line changed to %ls so that the entire log message would print.
The GCC command used to compile for x86 was:
i686-w64-mingw32-gcc main.c -o delete32.exe -s -DUNICODE -Os -lshlwapi
I have tried removing all switches and compiling and it still fails.
As a note, the shlwapi library is only required for the very last call in main(), PathFileExistsW. I have commented out that portion and removed shlwapi from imports and from the gcc command to no effect.
The x64 gcc command which succeeded was:
x86_64-w64-mingw32-gcc main.c -o delete32.exe -s -DUNICODE -Os -lshlwapi
In the issues tab of the github repo there are some mentions of errors in the code which I have looked at separately. However I would desperately like to know why mingw is causing an issue with the 32 bit version of this program. Unfortunately "just compile with VS" isn't an option, as I use a program to generate and compile the program that this bit of code will be part of on my linux machine.
Thanks for any insight.
RtlCopyMemory(fRename.FileName, lpwStream, sizeof(lpwStream)); writes 4 or 8 bytes into a 2 byte buffer! Who knows where the remaining bytes are going, the program behavior is probably undefined.
The concept of deleting a running exe like this might work but the code indicates that the author does not have a full understanding of Windows and C. You are better off rewriting it from scratch...
Edit:
After playing with your uploaded files I can with confidence say that it is the lack of a application manifest that causes it to fail when it is not elevated. Your vc file has a requestedExecutionLevel element which gives it Vista operating system context. If you remove the manifest resource in the vc exe it stops working. If you add a manifest to the mingw exe it starts working.
the ds_rename_handle function is wrong implemented.
the FILE_RENAME_INFO is variable size structure.
as result declaration
FILE_RENAME_INFO fRename;
almost always wrong (it will ok only if FileName containing 1 or 2 symbols)
really we need first calculate FileNameLength and then allocate PFILE_RENAME_INFO based on this
as example:
ULONG FileNameLength = (ULONG)wcslen(DS_STREAM_RENAME) * sizeof(WCHAR);
ULONG dwBufferSize = FIELD_OFFSET(FILE_RENAME_INFO, FileName) + FileNameLength;
PFILE_RENAME_INFORMATION fRename = (PFILE_RENAME_INFORMATION)alloca(dwBufferSize);
so complete code for ds_rename_handle can be next:
ULONG ds_rename_handle(HANDLE hHandle, PCWSTR DS_STREAM_RENAME)
{
ULONG FileNameLength = (ULONG)wcslen(DS_STREAM_RENAME) * sizeof(WCHAR);
ULONG dwBufferSize = FIELD_OFFSET(FILE_RENAME_INFO, FileName) + FileNameLength;
PFILE_RENAME_INFO fRename = (PFILE_RENAME_INFO)alloca(dwBufferSize);
fRename->ReplaceIfExists = TRUE;
fRename->RootDirectory = 0;
fRename->FileNameLength = FileNameLength;
memcpy(fRename->FileName, DS_STREAM_RENAME, FileNameLength);
return SetFileInformationByHandle(hHandle, FileRenameInfo,
fRename, dwBufferSize) ? NOERROR : GetLastError();
}
but documentation of FILE_RENAME_INFO is very bad. unclear - in what form - full pathname, file name or a relative pathname - must be FileName ?!
from my research - it must be full pathname only (not file name) or begin with a colon : ( The new name for the stream )
much more better use NtSetInformationFile with FileRenameInformation
compare description of FILE_RENAME_INFORMATION structure with FILE_RENAME_INFO !
here exist detailed description - in what form FileName it should be.
so i always use
NTSTATUS ds_rename_handle_nt(HANDLE hHandle, PCWSTR DS_STREAM_RENAME)
{
ULONG FileNameLength = (ULONG)wcslen(DS_STREAM_RENAME) * sizeof(WCHAR);
ULONG dwBufferSize = FIELD_OFFSET(FILE_RENAME_INFO, FileName) + FileNameLength;
PFILE_RENAME_INFORMATION fRename = (PFILE_RENAME_INFORMATION)alloca(dwBufferSize);
fRename->ReplaceIfExists = TRUE;
fRename->RootDirectory = 0;
fRename->FileNameLength = FileNameLength;
memcpy(fRename->FileName, DS_STREAM_RENAME, FileNameLength);
IO_STATUS_BLOCK iosb;
return NtSetInformationFile(
hHandle, &iosb, fRename, dwBufferSize, FileRenameInformation);
}
For a project I am working on, I am trying to use libgit2.
For the moment, I am just trying to create a repo using git_repository_init but it fails with the following error message :
Error: -1/2: Failed to resolve path 'D:/Workspace/<project_name>/test/.git/': Invalid argument
The code is the following :
#include <iostream>
#include "git2.h"
int main(int argc, char *argv[])
{
git_libgit2_init();
git_repository *repo;
git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT;
opts.flags |= GIT_REPOSITORY_INIT_MKDIR;
int err = git_repository_init_ext(&repo, "D:/Workspace/<project_name>/test", &opts);
if(err < 0)
{
const git_error *e = giterr_last();
std::cerr << "Error: " << err << "/" << e->klass << ": " << e->message << std::endl;
}
git_repository_free(repo);
git_libgit2_shutdown();
return 0;
}
The .git directory in the test directory is still created but it's empty.
I have tried with relative and absolute path and also Unix and windows path but the result seem to always be the same.
Also, when executing libgit2_clar, a lot of test fail always with the same error : "error -1 - Failed to resolve path 'attr': Invalid argument".
libgit2 and the previous code has been compiled and executed on a Windows XP 32bit using MinGW with gcc 4.8.1.
Windows XP is not supported by libgit2. Support ended in v0.21.0 in 2014:
Top-level Improvements
We've dropped support for Windows XP. We're evil like that.
The repo_path parameter of git_repository_init_ext isn't legal because
it contains the chars '<' '>' .
Try to make new directory with the above chars and you get error message.
I used to develop Java project by Eclipse.
A Java project can contain many code files with the main function (the entry point), so we can run each code file which has a main function.
But now I want to develop C project by Eclipse CDT.
In a C project we can have only one main function. Can I have many code files with a main function and run each file just like I would in Java?
P.S.: I don't like to write Make Target for each file by main self
Javas option to have a main in every object is highly irritating and does not make sense to me.
I assume you want to train a bit in c and want to find a way to have all training lessons in one file. Here is an option that would do that for you in a crude way. This would not be reasonable to do as an application but you can use this to execute different options.
To use this you would call your program like 'progname 1'.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int ProgrammingLesson001(void);
int main(int argc, char * argv[])
{
int i;
int option;
int e = 0;
printf("%i\n", argc);
for(i = 0; i < argc; ++i)
{
printf("%s\n", argv[i]);
}
if(2 == argc)
{
option = atoi(argv[1]);
printf("Your Option was '%s' interpreted as %i\n", argv[1], option);
}
else
{
option = 0;
e |= 1;
}
switch(option)
{
case 0:
printf("zero is an error\n");
e |= 1;
break;
case 1:
e |= ProgrammingLesson001();
break;
default:
break;
}
if(0 != e)
{
printf("an error has occureed\n");
}
return e;
}
int ProgrammingLesson001(void)
{
printf("This could behave like a main for training purposes\n");
}
If you spent some time programming in c take a second look at makefiles.
You can create a makefile that will fit all your programs.
This reduces the actual work you need to put into this so much that maintaining the switch construct is harder than creating a new project.
Thank Clifford to fixed my quest and guys who replied
I have solved this problem by myself
Here is my solution:
#!/bin/bash
SourceFile=$1
Path="$(dirname "$SourceFile")"
ParentPath="$(dirname "$Path")"
OutputPath="$ParentPath/bin"
OutputFile="$OutputPath/a.out"
mkdir -p $OutputPath
rm -f $OutputFile
gcc -w $SourceFile -lm -o $OutputFile
$OutputFile
This bash's name is gcc.sh
In eclipse run -> external tools -> external tools configurations -> new a configuration
Location: /home/xxxxx/gcc.sh
Working Directory: (just let it be empty)
arguments: ${resource_loc}
Then you can run C file by your customize command
I'm struggling with creating a window with the GLFW 3 function, glfwCreateWindow.
I have set an error callback function, that pretty much just prints out the error number and description, and according to that the GLFW library have not been initialized, even though the glfwInit function just returned success?
Here's an outtake from my code
// Error callback function prints out any errors from GFLW to the console
static void error_callback( int error, const char *description )
{
cout << error << '\t' << description << endl;
}
bool Base::Init()
{
// Set error callback
/*!
* According to the documentation this can be use before glfwInit,
* and removing won't change anything anyway
*/
glfwSetErrorCallback( error_callback );
// Initialize GLFW
/*!
* This return succesfull, but...
*/
if( !glfwInit() )
{
cout << "INITIALIZER: Failed to initialize GLFW!" << endl;
return false;
}
else
{
cout << "INITIALIZER: GLFW Initialized successfully!" << endl;
}
// Create window
/*!
* When this is called, or any other glfw functions, I get a
* "65537 The GLFW library is not initialized" in the console, through
* the error_callback function
*/
window = glfwCreateWindow( 800,
600,
"GLFW Window",
NULL,
NULL );
if( !window )
{
cout << "INITIALIZER: Failed to create window!" << endl;
glfwTerminate();
return false;
}
// Set window to current context
glfwMakeContextCurrent( window );
...
return true;
}
And here's what's printed out in the console
INITIALIZER: GLFW Initialized succesfully!
65537 The GLFW library is not initialized
INITIALIZER: Failed to create window!
I think I'm getting the error because of the setup isn't entirely correct, but I've done the best I can with what I could find around the place
I downloaded the windows 32 from glfw.org and stuck the 2 includes files from it into minGW/include/GLFW, the 2 .a files (from the lib-mingw folder) into minGW/lib and the dll, also from the lib-mingw folder, into Windows/System32
In code::blocks I have, from build options -> linker settings, linked the 2 .a files from the download. I believe I need to link more things, but I can figure out what, or where I should get those things from.
I tried reinstalling codeblocks and mingw, which solved the issue.
Seems like GLFW3 doesn't like having previous versions installed at the same time for some reason, so if anyone else is having a similar problem, you might want to try that.
I experienced similar problems in Cocos 3.8.1 and 3.10.
I have never installed codeblocks or mingw, so it did not make sense to install them for me.
The GLFW.lib file in the cocos directory is out of date.
http://www.glfw.org/download.html, and replace the lib file in your project with the latest one, and it may resolve your error.
I was wondering how can I print colorful text in the console? I use eclipse win64 OS. Does it have to do with the compiler? Can anyone give a simple example in C with just a hello world text in red or whatever?
I know that this is incredibly easy to do in C++, but I found this for you to look at in C:
#include <stdio.h>
#include <windows.h> // WinApi header
int main()
{
HANDLE hConsole;
int k;
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
// you can loop k higher to see more color choices
for(k = 1; k < 255; k++)
{
SetConsoleTextAttribute(hConsole, k);
printf("%3d %s\n", k, "I want to be nice today!");
}
getchar(); // wait
return 0;
}
All of the comments will help you to find your way through the code - hope it helps!
If you want to print colored text in Windows console, you will have to use Windows API. ANSI.sys support is no longer present in Windows.
In Linux you can still use ANSI escape sequences to color text.
You can use ANSI escape sequence on Windows as well with the following modification:
reg add HKEY_CURRENT_USER\Console /v VirtualTerminalLevel /t REG_DWORD /d 0x00000001 /f
example:
int main()
{
printf("\033[33mThis is yellow\033[0m");
return 0;
}
source:
https://www.codeproject.com/Tips/5255355/How-to-Put-Color-on-Windows-Console
If you are constrained to using just printf(), this requires knowledge of the terminal to which you're writing. The chances are it is an ANSI-style terminal, so it can be done. The Unix curses (Linux ncurses) library handles such information in a terminal-independent way. Basically, you will need to define or manufacture control strings to turn the terminal into red mode and then reset it back again (but how do you know what state it was in before you changed it to writing red text?). The libraries mentioned keep track of the state information, amongst many other details.
However, if you get the strings organized, then code like this will do the trick (more or less):
static const char to_red[] = "\033...";
static const char to_black[] = "\033...";
printf("%s%s%s\n", to_red, "hello world", to_black);
The hard part is determining what goes in the constant strings (which need not actually be constant).
All this means there is probably a Windows-specific interface that can be used to do the job, but that does not really involve printf() for controlling the colours; you call the Windows API to set the colour, then write with printf(), then call the API again to reinstate the colour. There is probably a query function to allow you to find the current setting, which you use before changing it.
The console in Java uses stdout which is whatever OS you are running on. For Windows, you would need to access the Console API to change the colours. For Linux or Mac, the console might support ANSI escape sequences which can change the console colours via stdout.
Here's a further example for you. It is in C++, but I'm sure you can handle that; but I do also have the exact same code in this example in python. It's a small demo I wrote to end up drawing some lines in colors.
Anyway the series of demos is at:
https://github.com/goblinhack/c-plus-plus-python-tutorial
With the full source for the below example at:
https://github.com/goblinhack/c-plus-plus-python-tutorial/blob/master/lesson1/lesson1.cpp
The C++ code for the above picture is using the Ansi color class I define in the lesson1.cpp. But once you use that, it's very simple to use. hth.
int main (int argc, char *argv[])
{
Ansi ansi;
std::cout << ansi.get_code(ansi.FOREGROUND_RED);
std::cout << "hello ";
std::cout << ansi.get_code(ansi.FOREGROUND_GREEN);
std::cout << "beautiful";
std::cout << ansi.get_code(ansi.RESET);
std::cout << ansi.get_code(ansi.FOREGROUND_CYAN);
std::cout << " colorful";
std::cout << ansi.get_code(ansi.RESET);
std::cout << ansi.get_code(ansi.FOREGROUND_BLUE);
std::cout << " world";
std::cout << ansi.get_code(ansi.RESET);
std::cout << std::endl;
return (0);
}
With similar ability in python
def lesson1():
""" hello beautiful world """
ansi = Ansi()
for bg_col in range(ansi.Code.BACKGROUND_BLACK,
ansi.Code.BACKGROUND_WHITE):
for fg_col in range(ansi.Code.FOREGROUND_BLACK,
ansi.Code.FOREGROUND_WHITE):
sys.stdout.write("{0: <20} {1: <20}".format(\
ansi.get_code_name(bg_col),
ansi.get_code_name(fg_col)))
sys.stdout.write(ansi.get_bgfg_code(bg_col, fg_col))
sys.stdout.write("colorful")
sys.stdout.write(ansi.get_code(ansi.Code.RESET))
print()
sys.stdout.write(ansi.get_code(ansi.Code.FOREGROUND_RED))
sys.stdout.write("hello")
sys.stdout.write(ansi.get_code(ansi.Code.FOREGROUND_GREEN))
sys.stdout.write(" beautiful")
sys.stdout.write(ansi.get_code(ansi.Code.FOREGROUND_CYAN))
sys.stdout.write(" colorful")
sys.stdout.write(ansi.get_code(ansi.Code.FOREGROUND_BLUE))
sys.stdout.write(" world")
sys.stdout.write(ansi.get_code(ansi.Code.RESET))
print("from Python")
lesson1()