How to run an exe using c prog - c

I am new to this forum. I am in need of a program in C that runs an exe file in Windows.
While googling I found the code below :
1.
Code:
#include<stdlib.h>
#include<stdio.h>
int main()
{
(void)system("C:\\Windows\\notepad.exe");
return 0;
}
The above code compiles successfully in Borland Turbo C. But it fails to run Notepad.
2
Code:
#include<stdlib.h>
#include<stdio.h>
void main()
{
int result ;
result=system("C:\\Windows\\notepad.exe");
printf("%d",result);
}
The above code on running gives -1 as output. Why am I getting -1.
My OS Windows XP
Borland Turbo C Compiler
Please help.

There are at least two wrong things here:
you're using system();
you're hardcoding a path.
For the first problem, I already wrote a long rant some time ago, you can have a look at it here; long story short, to start a process you should go with the platform-specific way, namely, on Windows, CreateProcess or, if you want to open a file with it's associated application, ShellExecute.
For the second problem, you're assuming (1) that c:\windows exists, (2) that it is the windows directory of the currently running windows instance (3) that notepad.exe actually exists and (4) that it is in such directory.
While notepad.exe is pretty much guaranteed to exist on every Windows installation, it's not clear where you should search it. Since Windows 3.0 it was in the Windows directory, but on the NT family it used to stay in the system32 subdirectory. So, from some Windows version onward Microsoft put two copies of notepad, both in the windows directory and in the system32 directory (see this blog post).
Additional fun: from Windows Server 2008 the copy from the Windows directory has been removed (link - incidentally, the title of the post is What idiot would hard-code the path to Notepad? :D), so your program will fail to open notepad even if Windows resides in c:\windows.
But the biggest problem here is that Windows isn't guaranteed to be installed in c:\windows; on every NT-family Windows before Windows XP it was actually installed by default in c:\winnt, so your code would fail here.
Moreover, if you have more than one copy of Windows installed (say Windows 7 64 bit on c:, Windows XP 32 bit on d:) c:\windows may actually exist, but it may contain a copy of Windows different from the one currently executing, so you'd be opening the notepad from another copy of Windows (and if that copy is 64 bit and the running one is 32 bit it won't run).
Similar stuff may happen also if you install Windows on a disk that already contains a windows directory; in that case the setup will put Windows in a Windows(01) directory (or something like that), and c:\windows may be empty.
Long story short:
avoid using system: apart from its other flaws, in all these scenarios your application wouldn't have any clue that notepad didn't start;
avoid hardcoding paths: c:\windows isn't guaranteed to exist; if you need to get the path of the Windows directory, you can expand the environment variable %windir% (or %systemroot), or use the API GetWindowsDirectory;
if your app is in PATH, you may exploit this fact: the Windows and system32 directory are in the PATH environment variable, which means that, if you just try to start notepad, you can avoid to specify it's full path; on the other hand, you're exposing yourself to vulnerabilities if a malicious user put a dangerous application in the working directory of your application;
if you want to open a file, use ShellExecute: it will automatically open that file with the associated application.

I'm not sure notepad has ever been stored in the Windows directory. This code works under WinXP.
#include<stdlib.h>
#include<stdio.h>
/* main() returns int, not void. */
int main( void ) {
int result ;
result=system("C:/Windows/system32/notepad.exe");
printf("%d",result);
return 0;
}

Look where you save your source file, alway C++ Compilers generate two files, let say your source named "hello.cpp"
These files should be in your source path:
hello.obj
hello.exe <--your prgram to distribut
ALSO
I think you should use new free IDE/Compiler for better result such as:CodeBlocks at http://www.codeblocks.org

As per me I dont see any problem with the code, did you try running the program with some standard IDE like, dev-cpp or code-blocks.
And do one thing
try running the same command on the command prompt first and tell the result.
I would also like to tell you to go inside the Windows directory and check if Notepad.exe is there or not.
It is not likely but there is a chance.
Thanks
Alok Kr.

Could be that your path is wrong in some way. I would suggest following Kumar's advice and try running it in the command prompt first just to see that you are using the right path.
Also, you might want to try running notepad.exe without a path at all. As it is located in the PATH, you should be able to specify just "notepad.exe".

Related

C code to move file to trash

I'm trying to remove a file in a C program, but when I use the remove() function it completely removes the file and not sending it to the trash. How can I remove a file to trash?
Thanks in advance!
On Mac OS, you should use the recycleURLs:completionHandler: method in NSWorkspace.
Almost every operating system provides an API to perform a soft delete by moving files to the trash. Unfortunately there is no unified specification on how a trash / recycling bin should work. On Windows you can use IFileOperation, macOS has the NSFileManager and on Linux and BSD you either use a tool that implements the FreeDesktop.org trash specification such as gio trash (GNOME), kioclient5 move (KDE), trash-cli or implement your own.
Another solution is using a cross-platform library that allows to move files and directories to the trash / recycling bin like libtrashcan. This simplifies development because you only use a single function call without worrying about platform specific details.
For Windows See SHFileOperation with FOF_ALLOWUNDO.
http://msdn.microsoft.com/en-us/library/bb762164.aspx
On Mac OS X, you have to call FSMoveObjectToTrashSync (or its async friend) from CoreServices.
In linux i will do...
system("mv your_file.txt /home/username/.local/share/Trash/");
If you are on Windows try this.
Open a Command Prompt (DOS windows) and type
cd \$RECYCLE.BIN
dir \a
and you will get a list of all the trashes of all the users in your computer.
In your program move the file to the proper trash.

Calling fopen on Windows core files returns NULL pointer

I am trying to open a couple different files via their absolute path (determined elsewhere, programmatically), so I can get their SHA1 hash*, some of which are core windows files. fopen() is returning NULL on some (but not all) files when I attempt to open them as follows (normally the filename is gotten via QueryFullProcessImageName but I hardcoded it just in case):
char * filename = "c:\\windows\\system32\\spoolsv.exe";
FILE * currFileRead = fopen(filename, "rb");
if (currFileRead == NULL)
{
printf("Failed to open %s, error %s\n", filename, strerror(errno) );
}
else
{
//hashing code
}
The reported error is 2: "No such file or directory", but obviously they're there. It also only fails for some processes, like spoolsv.exe or winlogon.exe, while svchost.exe and wininint.exe seem to open just fine.
My program has administrative privileges, and I can't figure why some processes would fail while others opened without trouble?
*I'm using a method from LibTomCrypt (http://libtom.org/?page=features) which is open source with a permissive license. The call to sha1_process takes in a hash_state (internal to the library), an unsigned char buffer, and the length of the buffer. I need to read the file with fopen to get the file into memory for hashing.
Because your program is a 32-bit process, when you try to open c:\windows\system32 you actually get c:\windows\syswow64 which does not contain all of the same files.
You can use IsWow64Process to determine whether you are running on a 64-bit system. If you are, you can replace system32 with sysnative in the path to open the actual file, unless you need to support Windows 2003 or Windows XP. Depending on your circumstances, you might need to cope with the possibility that the Windows folder is not c:\windows and/or the possibility that there are other folders named system32.
On the whole it would be more robust to have separate 32-bit and 64-bit versions of your application, or perhaps just the particular part of it that is exhibiting the problem. If you can't leave it up to the user to install the appropriate version, the installer could decide which to install, or you could always install both and have the 32-bit version automatically launch the 64-bit version when running on a 64-bit system.
Having administrative privileges is not always enough, because if the file you want to open is in use and the program that is using it has locked it, then you can't open and read that file.

How do I run bcdedit from my c program?

I don't understand why the following code returns "'bcdedit' is not an internal or external command" when ran from a c program. bcdedit works perfectly fine on cmd line. How can I get this to work?
#include <stdio.h>
int main ()
{
system("bcdedit");
system("TIMEOUT /T 3");
return(0);
}
It happens because when you run the Command Prompt via Start Menu or even the Execute window you are running the 64-bit cmd version, located at C:\Windows\System32\cmd.exe, however when call cmd from your c program it calls the 32-bit cmd version, located at C:\Windows\SySWOW64\cmd.exe. This happens because your C compiler generates a 32-bit application.
According to MSDN:
The %windir%\System32 directory is reserved for 64-bit applications.
Most DLL file names were not changed when 64-bit versions of the DLLs
were created, so 32-bit versions of the DLLs are stored in a different
directory. WOW64 hides this difference by using a file system
redirector.
In most cases, whenever a 32-bit application attempts to access
%windir%\System32, the access is redirected to %windir%\SysWOW64.
Source: http://msdn.microsoft.com/en-us/library/windows/desktop/aa384187%28v=vs.85%29.aspx
If you compare both cmds you will realize that they are identical, what differs are the dll's.
The problem is that Windows x64 provides a 64-bit bcdedit.exe in the System32 folder, but doesn't provide a 32-bit bcdedit.exe anywhere. So the 32-bit cmd can't run the 64-bit bcdedit, so it returns that this command is invalid.
Solution: You can both obtain a 32-bit bcdedit from a Windows x86 version or you can compile a 64-bit application.
Most likely because it cannot find the executable. Either ensure your path is correct(a) or use the full path name:
system ("c:\\windows\\system32\\bcdedit.exe");
And, of course, this should go without saying: make sure you run it as an administrative user.
(a) You should be able to confirm this with something like:
system ("path");
I think you have cut one command into two part.And I think you want to run "bcdedit.exe /timeout 3",but you give the
argument of the system command two parts, one is "bcedit.exe", another is "/timeout 3". I think you should wrote this
system("bcdedit.exe /timeout 3");
to run the command you wanted.Hope this will help you

Using Visual Studio 2010, how do I provide input to a Visual C++ Win32 Console Application?

I am using Visual Studio 2010 Pro for simple C programming, I would like to know how I can provide input to the program without having to manually do so. The enviroment I am used to working is your standard commandline Unix enviroment. Once I compile a C file call "inputsInts" it becomes "a.out" and to test input I would type:
The easy way
echo 1 2 3 4| ./a.out //to provide input
The number of ints input was 4 //output
The easier way
more input.txt| ./a.out //to provide input
The number of ints input was 4 //output
The tedious way
./a.out
//now I would manually type
1 2 3 4 s //in this case I have to type a letter to move on
The number of ints input was 4 //output
Hard is how I have to do it in Visual Studio 2010. I would like to be able to just input in an area the input ahead of time or at least have it read a text file. Obviously I can't test large sets of data by manually typing it in. At the moment I am just doing the coding in VS2010 and going to the unix enviroment to do most testing. I would like to stay in the VS2010 enviroment until I am ready to do a final test in Unix.
I have altered the question quite a bit since I first posted, so the original answers may seem off a bit. Again I appretiate everyone's time and help.
This is just the simple code for an example:
#include
int main () {
int x, n = 0;
while (scanf("%d", &x)==1)
n++;
printf("The number of ints input was %d\n", n);
return(0);
}
You need to create a "Console Application" when you start a new Visual Studio project. This will give you a program that runs from a Windows Command Prompt window, otherwise known as the Cmd window after the name of the shell program that runs underneath it. The command window is located under Programs->Accessories in Windows XP, not sure about other versions of Windows. Once you open a command window, things will work similarly to what you're used to on Linux.
cd MyProject
echo 1 2 3 4|.\MyProject.exe
MyProject.exe <input.txt
The cmd.exe shell has a pipe operator that works similar to the Unix pipe operator. It has some quirks in some versions of Windows but in general, you should be able to do many of the same things with it.
You can run your program pretty much the same way at the Windows command line, the only obvious difference being that you need to specify the correct executable name instead of a.out.
To do roughly the same from inside the VS IDE, you'd probably need to store your sample input in a text file, and then specify something like < sample.txt as the arguments to supply to the program in the project's debug settings.
In the Windows Shell (cmd.exe) you can use a pipe similar to linux for commands like
dir|more
Outside the shell, you're talking about a GUI environment (as in Linux's GUI) so passing info from one program to the next will be a bit different.
However, you can achieve similar functionality using pipes (shared memory in Windows). See here for a full explanation with examples from the folks at Microsoft Developer Network:
http://msdn.microsoft.com/en-us/library/aa365780%28v=VS.85%29.aspx
Or if you're feeling to lazy to poke around, here's an example of transactions on named pipes:
http://msdn.microsoft.com/en-us/library/aa365789%28v=VS.85%29.aspx
...or you can simply dump and read from output files.
(Both of these methods are similar to those used with Linux programs)
More info on your specific needs would be helpful.

fopen fails mysteriously under Windows

Maybe I just have another black out but, this one line is giving me a lot of troubles:
FILE *fp = fopen("data/world.data", "rb");
This works fine under Linux when compiled with GCC. But when I compile it with Visual Studio, it crashes. fp is always NULL. Both the BIN and the EXE are in the exact same directory. Now, to make things even crazier, when I run the EXE using Wine under Linux... it... works...
I have absolutely not a god damn clue what's going on here. Maybe it's some insanely stupid mistake on my side, but I cannot get this thing to run under Windows :/
Also, I have another program which works just fine, there the data files are also contained in a sub directory named data.
EDIT:
To make it clear neither / NOR `\ * do work.
EDIT 2:
OK I've given up on this, maybe someone has fun trying to figure it out, here's ZIP containing the EXE, Debug Data for VS etc.:
https://dl.dropbox.com/u/2332843/Leaf.zip
EDIT 3:
Compiled it with CodeBlocks and MinGW, works like a charm. Guess it has to do something with MSVC or the Project Settings in VS.
It sounds like data isn't a subdirectory of your current directory when you run the program. By default (for x86 targets) VS will build and run your program from either a DEBUG or RELEASE subdirectory of the base directory you've created for the project. You can modify the directory that will be "current" when it runs though (e.g., project | properties | configuration properties | debugging for VS 2008).
Edit: While Windows requires that you use a backslash as a directory separator at the command line, a forward slash works fine in code -- this is not the source of your problem.
In windows you have to write the following:
FILE *fp = fopen("data\\world.data", "rb");
This is like that because the backslash is a special character (so a backslash in a string is written using \ and a quotation symbol is \" and so with other special characters).
Since this issue happens only on windows. I doubt whether the file is really named "world.data". As you know, the default setting for windows hides the file extention. Is its real name world.data.xxx?
Include a line to GetCurrentDirectory(), to see if you are running from the directory you expected.
When I develop in C#/ C++ on visual studio, I normally get to run it from the debug folder. I don't think it matters if forward slash is used in place of backslash in .net.
I happened to have the same problem, and suddenly i figured it out.
That should be your windows fault.
Let's say, FILE *fp = fopen("data/world.data", "rb"); in windows, if you hide the extensions, then you can see the file data/world.data, but actually it maybe /data/world.dat.txt or somewhat.
So please check the extensions.
Hope it helps!
I ran into this today, and it happened because I used "br" instead of "rb" on that mode argument.
The underlying fopen is throwing an exception of some kind, which only registers as a crash. It's not bothering to return the standard NULL response or set the associated error values.
I'm not sure but it may be because you're using slash instead of (an escaped) backslash in the path?

Resources