I'm trying to use CreateProcess to start a child process, however I keep getting error 2, which, according to the documentation is file not found.
My code looks like this:
if (!(CreateProcess(LPCTSTR("test.exe") ,NULL ,NULL,NULL,FALSE ,0 ,NULL ,NULL ,&producer_si
,&producer)))
{
printf("Create process failed!(%d)\n", GetLastError());
}
Where test.exe is an executable program which I created earlier. The child process is very simple, with the code looking like this:
void _tmain (int argc, TCHAR* argv[])
{
printf("%s\n", "hello!");
}
test.exe is also found in the same folder as the parent process. I'm not understanding why I'm always getting an error code of 2.
Error 2 is ERROR_FILE_NOT_FOUND. As others have told you, you are relying on a relative path when you need to use an absolute path instead.
Also, LPCTSTR("test.exe") is not valid code. If UNICODE is defined, CreateFile() maps to CreateFileW(), and LPCTSTR maps to LPCWSTR ie const wchar_t*. You cannot typecast a char* to a wchar_t* and end up with meaningful data. If you want to use TCHAR-sensitive literals, use the TEXT() macro instead, eg:
if (!CreateProcess(TEXT("full path to\\test.exe"), ...))
Otherwise, forget using TCHAR and just write Ansi-specific or Unicode-specific code instead, depending on your needs:
if (!CreateProcessA("full path to\\test.exe", ...))
if (!CreateProcessW(L"full path to\\test.exe", ...))
test.exe is never being looked up in the directory that the calling exe lives in. It is being looked up in the current directory which is a per-process path variable. Maybe the current directory is not pointed to where test.exe lives. You should also never rely on that because it can change arbitrarily (for example by using the file dialogs, or when the parent process changes it).
The CreateProcess function is very sensitive when it comes to file names, at least in my opinion.
When you specify your exe like that you actually specify it according to the current directory which may not be the same as the directory your main exe is in, which explains the file not found.
One way around is to simply get your current exe's directory with GetModulePath stip away the exe name from that and there you have the same directory, or simply use an absolute path.
According to the CreateProcess documentation the first parameter can be NULL :
The lpApplicationName parameter can be NULL. In that case, the module name must be the first white space–delimited token in the lpCommandLine string.
At least for me it seemed that if you just specify the command line only it works far better than with the application name, and also within the application name you can't handle the commandline.
With QT the MSDN function TEXT() it doesn't work: QTCreator's compiler return:
'Lvar' undeclared (first use in this function)
where var is input of Text(), because of QT whose enable UNICODE and because of that:
#ifdef UNICODE
/*
* NOTE: This tests UNICODE, which is different from the _UNICODE define
* used to differentiate standard C runtime calls.
*/
typedef WCHAR TCHAR;
typedef WCHAR _TCHAR;
/*
* __TEXT is a private macro whose specific use is to force the expansion of a
* macro passed as an argument to the macro TEXT. DO NOT use this
* macro within your programs. It's name and function could change without
* notice.
*/
#define __TEXT(q) L##q
#else
typedef CHAR TCHAR;
typedef CHAR _TCHAR;
#define __TEXT(q) q
#endif
#endif
in particular this passage:
#define __TEXT(q) L##q
in winnt.h included by windows.h
So, to solve this problem, we have to add this:
DEFINES -= UNICODE
in the .pro file of the QTCreator's project and it will work.
Related
I was recently at a presentation where one of the speakers stated that he'd used a single CGI file, written in C, that is called by the webserver, but the webserver calls the file by using different names, the CGI file would run a different method.
How can I have a single C file execute different functions within when it is called by different names? Also how do I re-direct the calls for differently named files back to this single file?
Is this possible or was he just full of himself?
If you create the executable with different names but with the same code base, you can take a different branch of the code based the name of the executable used to invoke the program.
Simple example file:
#include <stdio.h>
#include <string.h>
int main1(int argc, char** argv)
{
printf("Came to main1.\n");
return 0;
}
int main2(int argc, char** argv)
{
printf("Came to main2.\n");
return 0;
}
int main(int argc, char** argv)
{
// If the program was invoked using main1, go to main1
if (strstr(argv[0], "main1") != NULL )
{
return main1(argc-1, argv+1);
}
// If the program was invoked using main2, go to main2
if (strstr(argv[0], "main2") != NULL )
{
return main2(argc-1, argv+1);
}
// Don't know what to do.
return -1;
}
Create two different executables from the file.
cc test-262.c -o main1
cc test-262.c -o main2
Then, invoke the program by using the two different executables:
./main1
Output:
Came to main1.
and...
./main2
Output:
Came to main2.
Unix filesystems support the concept of hard and soft links. To create them just type:
ln origfile newfile
to create a hard link, or:
ln -s origfile newfile
to create a soft link.
Soft links are just a special kind of file that contains the path of another file. Most operations in the link transparently result in operating on the target file.
Hard links are lower level. In effect, all files are a link from the pathname to the content. In Unix you can link more than one pathname to the same content. In effect, there's no "original" and "links", all are links. When you delete a file, you're just removing a link, and when the link count goes to zero, the content is removed.
Many unix utilities do this trick. Since the running shell includes the name used to invoque the executable, it's handled just like the 0'th argument of the command line.
When a CGI script is being called by a web server, it receives a considerable amount of information in its environment to let it know how it was called, including:
SCRIPT_NAME, the path to the script from the document root
SCRIPT_FILENAME, the filesystem path to the script (usually the same as argv[0])
REQUEST_URI, the path that was requested by the browser (usually similar to SCRIPT_NAME in the absence of URL rewriting)
QUERY_STRING and PATH_INFO, which contain URL parameters following the script's name
HTTP_*, which contain most of the HTTP headers that were passed in the request
Point is, the script gets a lot of information about how it was called. It could be using any of those to make its decision.
It's possible and actually pretty common.
The first element in the argv array passed to the main function is the "name" of the executable. This can be the full path, or it can be just the last component of the path, or -- if the executable is started with an exec* function call, it can be an arbitrary string. (And Posix allows it to be a null string, as well, but in practice that's pretty rare.)
So there is nothing stopping the executable from looking at argv[0] (having first checked to make sure that argc > 0) and parsing it.
The most typical way to introduce a different name for the executable is to insert a filesystem link with the alternate name (which could be either a hard or a soft-link, but for maintainability soft links are more useful.)
For CGIs, it is not even necessary to examine argv[0], since there are various useful environment variables, including (at least): SCRIPT_NAME.
I have a C program that uses some resources located in the same directory as the executable. When I execute the program from a random working directory (not the directory where the program is located) the resources don't load, because the relative path I use in the code is not the path where the executable is. How can I solve this nicely?
Pass the path of the directory that contains the resources to the program as an argument and either:
change the current directory of the process to the directory (chdir() on Unix and SetCurrentDirectory() on Windows), or
construct absolute paths to the resources
If it is Windows, as the comment on the question suggests, you can obtain the path of the exe using GetModuleFileName(), extract the directory from it and avoid having to provide an argument to the program. Then either of two options listed would allow the program to be executed from anywhere and still locate its resources.
For anyone happening upon this old question in the future as I just did:
The program (at least in linux) keeps the command it was called by as the first argument of int main argument list.
e.g.
In this example we will drill down a couple of directories to get to our program, resulting in the following call command user#PC:~$ ./foo/bar/awesome_program.x86_64.
The program (code below) will print ./foo/bar/awesome_program.x86_64.
Since we have that string as a variable, it should be rather simple to construct relative paths from it, only replacing the end of that string with paths relative to the executable.
working code:
#include <stdio.h>
int main (int argc, char **argv)
{
printf("calling path: %s\n", argv[0]);
return 0;
}
This is a simple C program that prints the number of command line argument passed to it:
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("%d\n", argc);
}
When I give the input
file_name *
It prints 623 instead of 2 in my pc (operating system Windows 7). But it gives the correct output in other cases. Is * a reserved character for command line arguments?
Note this program gives correct output for the following input:
file_name *Rafi
Output = 2
On a Unix command line, the shell is responsible for handling wildcards. yourapp * will run yourapp, and pass the name of ALL of the non-hidden files in the current directory as arguments. In your case, that's 622 files (623 = 622 files + name of the program).
On Windows, applications are responsible for wildcard parsing, so argc is 2, 1 for the name of the program (argv[0]) and 1 for the wildcard (argv[1] = *);
That * gets expanded by the shell or the runtime library (the former on *nixes, the latter on Windowses), and instead of literal * you get the names of all the files in the current working directory.
As others have mentioned, you're getting the 'shell wildcard expansion' or 'globbing' where the * is used as a wildcard to match file names to place in the argv array.
On Unix systems this is performed by the shell and has nothing (or little) to do with the C runtime.
On Windows systems, this functionality is not performed by the shell (unless possibly if you're using some Unix-like shell replacement like Cygwin). The globbing functionality may or may not be performed by the C runtime's initialization depending on what tools and/or linker options you use:
if you're using Microsoft's compiler, the C runtime will not perform globbing by default, and you would get an argc value of 2 in your example. However, if you ask the linker to link in setargv.obj (or wsetargv.obj if you have a Unicode build), then globbing is added to the runtime initialization and you'll get behavior similar to Unix's. setargv.obj has been distributed with MSVC for as long as I can remember, but it's still little known. I believe that most Windows programs perform their own wildcard expansion.
if you're using the MinGW/GCC tool chain, the C runtime will perform globbing before calling main() (at least it does for MinGW 4.6.1 - I suspect it's been in MinGW for a long time). I think MinGW might not perform globbing for GUI programs. You can disable MinGW's globbing behavior with one of the following:
define a global variable named _CRT_glob and initialize it to 0:
int _CRT_glob = 0;
link in the lib/CRT_noglob.o object file (I think this might be order dependent - you may need to place it before any libraries):
gcc c:/mingw/lib/CRT_noglob.o main.o -o main.exe
The problem is that the shell expands * into all the file names (that don't start with a .) in the current directory. This is all about the shell and very little to do with the C program.
The value of argc includes 1 for the program's own name, plus one for each argument passed by the shell.
Try:
filename *
filename '*'
The first will give you 623 (give or take - but it is time you cleaned up that directory!). The second will give you 2.
I'm developing something on Minix 3 and, when it comes to deal with io files, I got a problem.
In the code:
#include <stdio.h> /* If I don't call any stdio funcs compiler doesnt's complain*/
int main() {
FILE * fp; /* I get the following: " * not expected " */
return 0;
}
Already tried everything that comes to my mind, can't figure it out..
/EDIT/
From what I can tell, when I include something, if I call functions not related to structs, it's OK. Is it the structs ?
I will assume you have checked whether the Minix file is present, that it really defines the type FILE and that your include path provides the correct -Ioption to the compiler to find that file.
Depending on your environment it could happen that an environment variable INCLUDE exists and is recognized by your compiler to provide additional include paths, recognized even before the include options from the command line. In such a case it might happen to include a stdio.hfrom a different compiler. Visual Studio is known to provide such an environment variable by default, and that has bitten me once before.
EDIT: Running the preprocessor in isolation may help to find out what is really happening in any case. Verify that FILEis defined in the preprocessed version of your file.
Is there any way in C to remove (using remove()) multiple files using a * (wildcards)?
I have a set of files that all start with Index. For example: Index1.txt, Index-39.txt etc.
They all start with Index but I don't know what text follows. There are also other files in the same directory so deleting all files won't work.
I know you can read the directory, iterate each file name, read the the first 5 chars, compare and if it fits then delete, but, is there an easier way (this is what I currently do by the way)?
This is standard C, since the code runs on Linux and Windows.
As you point out you could use diropen, dirread, dirclose to access the directory contents, a function of your own (or transform the wildcards into a regex and use a regex library) to match, and unlink to delete.
There isn't a standard way to do this easier. There are likely to be libraries, but they won't be more efficient than what you're doing. Typically a file finding function takes a callback where you provide the matching and action part of the code. All you'd be saving is the loop.
If you don't mind being platform-specific, you could use the system() call:
system("del index*.txt"); // DOS
system("rm index*.txt"); // unix
Here is some documentation on the system() call, which is part of the standard C library (cstdlib).
Is this all the program does? If so, let the command line do the wildcard expansion for you:
int main(int argc, char* argv[])
{
while (argc--)
remove(argv[argc]);
}
on Windows, you need to link against 'setargv.obj', included in the VC standard lib directory.