I'm trying to use 7-Zip to zip up a file via the system() function in C++ on a windows XP machine.
I tried:
(formatted to be what system() would have received)
"C:\Program Files\7-Zip\7z.exe" a -tzip "bleh.zip" "addedFile.txt"
which spat the error
'C:\Program' is not recognized as an internal or external command,
operable program or batch file.
I've tried several similar alternatives but have not yet found a solution.
I want to try to run it straight from its install directory so that as long as a user has 7-Zip installed it will be able to function. This is for an in house utility application.
EDIT:
as requested these are the actual lines of code:
std::string systemString = "\"C:\\Program Files\\7-Zip\\7z.exe\" a -tzip \"" + outDir + projectName + ".zip" + "\" \"";
//...
std::string finalSystemString = systemString + *i + "\"";
system( finalSystemString.c_str() );
*i is an iterator to a particular file that is getting added.
it looks like something is stripping the quotes around the first argument. You could play around with extra quotes to try and fix this, or you can get the MS-DOS compatible short path name for 7z.exe with the Win32 API GetShortPathName
The short path will not have spaces in it, it will be something like "C:\PROGRA~1\7-ZIP\7Z.EXE"
Have you tried escaping the spaces, i.e. "C:\Program\ Files\7-Zip\7z.exe"? That might work, although I don't know the specifics of system().
Another approach would be to use the CreateProcess function in the Windows API. It can deal with spaces in "C:\Program Files" according to its documentation.
Related
Under linux, I do the following
COMMAND /home/directory/*.txt
and all the files in that directory get passed as separate parameters (20 files in the directory results in 20 parameters in the argv variable)
Under windows, the same command results in one parameter (that string exactly).
Is this a compiler issue (VisualC++ 2008) or a windows thing or what?
In the past, I've written batch files to parse the files into multiple parameters, but I'm hoping there's a better way.
Any help would be appreciated
It's somewhat more limited than most Unix shells, but VC++ includes a file named setargv.obj that you can link with to add globbing to your application. It supports * and ?, which covers most of what most people care about.
To use it, just include setargv.obj when you link your file. In most cases, this just means adding the file name to the command line, something like this:
cl myfile.c myotherfile.c setargv.obj
Indeed that is a shell globbing feature. In PowerShell you would handle wildcard expansion inside your function using Convert-Path (or Resolve-Path) e.g.:
function ITakeWildcards([string]$Path) {
$paths = Convert-Path $path
foreach ($aPath in $paths) {
"Processing path $aPath"
}
}
I was wondering how to open a file other than notepad... Our prof gave us an example:
s = "notepad.exe test.txt";
system(s.c_str());
That will open a file type of "notepad.exe" and the file name of "test.txt"
Main Question:
Now, I was wondering if there was a way to open other type of files, such as Microsoft Excel, Microsoft Word, Visual Studio, or 7zip.
My attempt opened something in a new cmd.exe (because of the START keyword):
fileNeededtoBeOpened = "START \"New Microsoft Office Excel Worksheet.xlsx\"";
system(fileNeededtoBeOpened.c_str());
(This code is slightly different from my original, where I'm trying to open a file from a vector...) but all I really need to know is instead of "notepad.exe" or "START" is there a different command to open different file types that aren't .txt
Also, a side note, I was reading on the internet that it wasn't safe to use system() to open files, is this correct?
I found the answer by myself... for those who are curious, here an the answers:
To open a text file: system(notepad)
To open an excel file: system(start excel)
To open a word doc file: system(start winword)
To open a 7z file: system(start 7zFM)
To open a visual studio file: system(start devenv)
I think you're confused.
System executes a command as you would on the command line (type cmd into the run prompt under start menu to get that).
So, when you type notepad.exe test.txt it's saying:
Open the program notepad.exe which is on the system path (so the
command line can find it to execute that program), and pass the
parameter test.txt to it.
Notepad itself decides what to do with test.txt, in this case it opens it.
So, you can tell it to run any command (program/executable) and pass any parameters to it in reality. If excel's on your system path, you can probably just type excel.exe to open it from your system command. Otherwise, find the location excel is installed in, and refer to it with the whole path to excel.exe and it will work fine.
For example, on my computer, executing "C:\Program Files\Microsoft Office\Office12\EXCEL.EXE" would open excel from the command line. I can pass further parameters to it by having more information (like filenames) after the Excel.exe" portion, just as you did in your notepad example. Using your system command should have equivilent behavior when that line is executed.
If you are only targeting Windows systems you can use the ShellExecuteEx function (part of the Win32 API). You can just pass a filename to it and it will launch what ever program is registered to handle that file type (just as if you opened the file from windows explorer). Documentation is available on MSDN:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb762154(v=vs.85).aspx
There is some examples on Launching Applications (ShellExecute, ShellExecuteEx, SHELLEXECUTEINFO) MSDN article and lots more elsewhere around the internet.
AS the other guys mentioned , the System function only executes a cmd command, .. notepad.exe is in the system's path by default so it works directly
but for example for me if I want to open a zip file on my desktop , I'd type something like
"C:\Program Files\7-Zip\7zFM.exe" Desktop\zipfile.zip
that's when I'm currently at the my user's directory [by default] , or
"C:\Program Files\7-Zip\7zFM.exe" C:\Users\JiMMaR\Desktop\zipfile.zip
[where JiMMaR is my user name on windows 7]
note that this certain command works only on windows , if you are using another OS this won't work as it is
try doing a
fileNeededtoBeOpened = "\"C:\Program Files\7-Zip\7zFM.exe\" C:\Users\YOUR_USER_NAME\Desktop\zipfile.zip";
and see if that executes or not
edit:
if you cannot escape the space , then try this one
fileNeededtoBeOpened = "C:\Program~1\7-Zip\7zFM.exe C:\Users\YOUR_USER_NAME\Desktop\zipfile.zip";
Ok, firstly - system - is a function that starts a separate process to your program. Much the same as in a command window when you type the command. The command lines you provide will be dependent on the applications you want to launch.
Now, I was wondering if there was a way to open other type of files,
such as Microsoft Excel, Microsoft Word, Visual Studio, or 7zip.
Yes I would be pretty shocked if there wasn't a command line parameter you could specify to load a document in these apps at start up. (Ok not shocked, but it is pretty standard)
Does this have anything to do with c++ - not really - you need to look at references for the applications you mention and see what the command lines parameters are for them. Then craft a string and system(...) to your hearts content.
I wanna create a exe which has the Shell Script and Simple CPP file which calls the Shell Script using system() function. Lets say exe name 'myInstaller' which has files myintsaller.cpp and myShell.sh. When i run the exe myInstaller , it must execute shell script. I want to do like this so i can protect my Shell Script code ,which has over 3000 lines of Code.
How do i do this ... I m in real need of this.
As far as i've searched, there is no way to bundle the script inside the exe. Either it would be Shell Compiler as shelter suggested or plain shell scripts. No work around for this.
I guess it's Windows platform since you speak about exe. In this case you can add your script as a resource to your exe, extract it in run-time and execute.
You could keep the script as a string in your C++ code and call system("sh -c '" + code + "'"). Quoting may be an issue though. Otherwise, write it to a temp location, execute it and then unlink it.
I have the find.exe program in my utils folder. This does not work:
system("\"utils/find.exe\"");
All I get is
'utils' is not recognized as an internal or external command,
operable program or batch file.
However, for some reason this works:
system("\"\"utils/find.exe\"\"");
Echoing the single quoted string
system("echo \"utils/find.exe\"");
outputs
"utils/find.exe"
... so why do I need two quotes?
I assume you're on windows because you're trying to execute an .exe file. So, instead of writting "utils/find.exe", try to write "utils\find.exe". The delimiting character on windows is '\', so it probably sees "utils" as a command since '/' is ignored.
Perhaps system() is passing your command line to the shell, e.g. cmd.exe, which also needs quoting?
Even though you can use both / and \ as directory separators in Windows, the command processor will try to interpret anything starting with a / as a switch. Try this:
system("\"utils\\find.exe\"");
I am having problem referring to the file path in Windows XP (SP2). Actually I want to run an exe file from a specified path say "C:\users\rakesh\Documents and settings\myexe.exe" in my program...I am using the function _wsystem("C:\users\rakesh\Documents and settings\myexe.exe") to run the file..
The problem is that it is not recognizing the space, so I went through some articles and I found an solution for that. I tried using the solution below ..it worked great:
C:\\users\\rakesh\\Docume~1\\myexe.exe
in the above after the first 6 chars I used "~1" to accomplish the rest...but it's not working when exe name is with space like below:
C:\\users\\rakesh\\Docume~1\\my exe.exe
and also I can't replace them with "~1"(not working for exe name).
How do you execute programs when there are spaces in the path or executable file name?
Just like on the command line, the spaces need to be inside double quotes:
_wsystem ("\"C:/users/rakesh/Documents and settings/myexe.exe\"");
Note that forward slashes work just fine for path delimiters.