I am trying to zip a folder in my Win32 Visual C++ app using a system call. On my computer, I can do this by the cmd command:
PowerShell -Command "Compress-Archive -Path C:\Users\ttyler\Desktop\Software\Folder2\RUN -DestinationPath C:\Users\ttyler\Desktop\Software\Folder2\RUN"
Where "Try" is a folder.
I am trying to do this on my app using a System call, but in my app, I have the "Path" and the "DestinationPath" stored in variables (because the destination path is being pulled in by the user). I'm not sure I'm using the variables correctly in my system call because this is giving me the error: "'+': cannot add two pointers" and "expression must have integral or unscoped enum type".
TCHAR path = L"C:\Users\ttyler\Desktop\Software\Folder2\RUN";
TCHAR DestinationPath = L"C:\Users\ttyler\Desktop\Software\Folder2\RUN.zip";
system("Compress-Archive -Path" + path[0] + "-DestinationPath" + DestinationPath[0]);
What am I doing wrong when using the variables in my system call?
Your code won't work for many reasons:
TCHAR path[] = L"C:\\Users\\ttyler\\Desktop\\Software\\Folder2\\RUN";
TCHAR DestinationPath[] = L"C:\\Users\\ttyler\\Desktop\\Software\\Folder2\\RUN.zip";
LPCTSTR path = L"C:\\Users\\ttyler\\Desktop\\Software\\Folder2\\RUN";
LPCTSTR DestinationPath = L"C:\\Users\\ttyler\\Desktop\\Software\\Folder2\\RUN.zip";
WCHAR path[] = L"C:\\Users\\ttyler\\Desktop\\Software\\Folder2\\RUN";
WCHAR DestinationPath[] = L"C:\\Users\\ttyler\\Desktop\\Software\\Folder2\\RUN.zip";
WCHAR cmd[(MAX_PATH*2)+50] = {};
swprintf(cmd, L"Compress-Archive -Path \"%s\" -DestinationPath \"%s\"", path, DestinationPath);
// use cmd as needed...
Or, just use std::wstring
instead, eg:
std::wstring path = L"C:\\Users\\ttyler\\Desktop\\Software\\Folder2\\RUN";
std::wstring DestinationPath = L"C:\\Users\\ttyler\\Desktop\\Software\\Folder2\\RUN.zip";
std::wstring cmd = L"Compress-Archive -Path \"" + path + L"\" -DestinationPath \"" + DestinationPath + L"\"";
// use cmd as needed...
system()
takes a const char*
pointer as input. But you are using TCHAR
strings, which will only work correctly for your wide string literals if TCHAR
is WCHAR
. Which means you can't pass your concatenated string to system()
anyway. You will have to use _wsystem()
instead, eg:_wsystem(cmd); // when using WCHAR[]/LPWSTR
_wsystem(cmd.c_str()); // when using std::wstring
system()
/_wsystem()
runs an instance of cmd.exe /C <command-line>
, where <command-line>
is the specified input string. But PowerShell.exe
is its own app with its own command-line parameters. PowerShell.exe
commands ARE NOT valid cmd.exe
commands, ie you are trying to execute this:cmd.exe /C Compress-Archive -Path <path> -DestinationPath <dest>
Which is not a valid command, as cmd.exe
does not know what Compress-Archive
is. You would need to execute this instead:
cmd.exe /C PowerShell -Command "Compress-Archive -Path \"<path>\" -DestinationPath \"<dest>\""
WCHAR cmd[(MAX_PATH*2)+70] = {};
swprintf(cmd, L"PowerShell -Command \"Compress-Archive -Path \\\"%s\\\" -DestinationPath \\\"%s\\\"", path, DestinationPath);
std::wstring cmd = L"PowerShell -Command \"Compress-Archive -Path \\\"" + path + L"\\\" -DestinationPath \\\"" + DestinationPath + L"\\\"";
But, you really should use CreateProcess()
instead to run PowerShell.exe
directly, don't use cmd.exe
at all, eg:
STARTUPINFO si = {sizeof(STARTUPINFO), 0};
PROCESS_INFORMATION pi = {};
if (CreateProcess(NULL, cmd/*cmd.data()*/, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
{
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
Otherwise, put your PowerShell commands into a .bat
script, eg:
@echo off
PowerShell -Command "Compress-Archive -Path \"%0\" -DestinationPath \"%1\""
And then you can use system()
/_wsystem()
to run that script, eg:
WCHAR cmd[(MAX_PATH*2)+25] = {};
swprintf(cmd, L"myscript.bat \"%s\" \"%s\"", path, DestinationPath);
_wsystem(cmd);
std::wstring cmd = L"myscript.bat \"" + path + L"\" \"" + DestinationPath + L"\"";
_wsystem(cmd.c_str());