I have a visual c++ redistributable installer exe in a resource file. File is extracted, moved to %TEMP%, run with QProcess and removed after process ends. The problem I have is that file removal fails with "Permission denied" even with escalated privileges. It seems that it is caused by file still being used by something (busy) because it starts working if I add a 1 second delay before removal.
QFile vcredistResource2015(":\\data\\vc_redist.x86.exe");
QString dst2015 = QDir::temp().absolutePath()+"/vc_redist.x86.exe";
vcredistResource2015.copy(dst2015);
QProcess p2015;
p2015.start(dst2015);
p2015.waitForFinished(-1);
//QThread::sleep(1); //this line solves it
QFile rm15(dst2015);
rm15.setPermissions(QFile::ReadOther|QFile::WriteOther);
if (rm15.exists() && rm15.remove()) {
qDebug() << "removed 2015";
}
else {
qDebug() << rm15.errorString(); //Permission denied here
}
Related
I have encountered a very strange issue with printing to console using std::cout in a c++11 application under CentOS.
printf("Before...\n"); // This gets printed with no issue
std::cout << "This won't be printed to console\n" << std::flush; // This won't get printed
std::cout.flush();
printf("After...\n"); // This gets printed with no issue
The output in the console is:
Before...
After...
The cout message for some reason is not printed. There is no stdout redirection in my code. I purposely redirected cout to a file but the issue was not solved. I am confused as to where to track down the issue.
What would prevent cout from printing? In what potential scenarios, cout stops functioning? What could be the issue?
Problem:
CLion doesn't output any console output for debugging purposes.
I'm using CLion with the MingW compiler and cmake. No matter whether I use:
std::cout << "Testing" << std::endl;
Or:
printf("Testing");
I don't see any console output.
Attempts at Resolution:
1:
I've checked "Run", "Debug", "Terminal" and "Cmake". I've attempted to edit my configurations but "Debug" doesn't show up.
2:
Next, I went to Settings->Build,Execution,Deployment->CMake to edit the Generation types. I added Debug and RelWithDebInfo and still to no avail.
3:
I also attempted to add "-Debug" to Cmake, but I still have no output.
4:
The closest thing I've received for debugging is using GDB to view variable values at break points. This only works in the "RelWithDebInfo" generation.
Solution:
I ended up figuring out what the problem was.
I'm developing a Qt GUI application within CLion on Windows. You have to specify a console for console output to print onto.
Call this Console() function early in your main for a console prompt to open up. Now, whenever you run
QDebug() << <string>;
or
std::cout << <string> std::endl;
You'll see your debugging statements. Hope this helps somebody else out there with the same problem.
Code:
void Console()
{
AllocConsole();
FILE *pFileCon = NULL;
pFileCon = freopen("CONOUT$", "w", stdout);
COORD coordInfo;
coordInfo.X = 130;
coordInfo.Y = 9000;
SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coordInfo);
SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE),ENABLE_QUICK_EDIT_MODE| ENABLE_EXTENDED_FLAGS);
}
Source:
I found a solution here:
[0] Console output in a Qt GUI app?
There's a simpler solution that doesn't require adding any code. Simply add the following environment variable in your debug configuration:
QT_ASSUME_STDERR_HAS_CONSOLE=1
With this, CLion shows QDebug and QML's console.*() when started with a debugger.
When 32bit app like java or python is trying to open c:\windows\system32\bash.exe this file simply not found.
How ever, it works perfectly if process ir 64bit. I've created a simple C app to check how it works.
#include <stdio.h>
#include <windows.h>
int main(int argc, char *argv[]) {
char* path;
OFSTRUCT junk;
if (argc != 2) {
printf("provide path to file");
return 1;
}
path = argv[1];
if( fopen( path, "r")) {
printf("OK: Runtime reports file exists");
} else {
printf("ERR: Runtime reports file does not exist");
}
printf("\n");
if (OpenFile(path, &junk,OF_EXIST) != HFILE_ERROR) {
printf("OK: Win32API reports file exists");
} else {
printf("ERR: Win32API reports file does not exist");
}
return 0;
}
It reports OK/OK when compiled and linked as x64 and ERR/ERR when compiled as x86. How could it be? Does there is some way to "hide" file from 32 bit apps in Windows?
This is the file system redirector in action.
In most cases, whenever a 32-bit application attempts to access %windir%\System32, the access is redirected to %windir%\SysWOW64.
So, your 32-bit application is looking for C:\Windows\SysWOW64\bash.exe instead, which presumably doesn't exist.
The recommended way to override it:
32-bit applications can access the native system directory by substituting %windir%\Sysnative for %windir%\System32. WOW64 recognizes Sysnative as a special alias used to indicate that the file system should not redirect the access.
Note that there are similar redirections for the registry as well.
I am trying to delete a text file in haskell while working in winhugs with help of removeFile function.But it is giving an error that
Program error: price.txt: Directory.removeFile: permission denied
What can be the reason?
According to the Hackage Docs for removeFile, the operation may fail with:
isPermissionError / PermissionDenied The process has insufficient privileges to perform the operation. [EROFS, EACCES, EPERM]
Also, according to the source code there, removeFile is just a thin wrapper around deleteFile in the Win32 API:
removeFile :: FilePath -> IO ()
removeFile path =
#if mingw32_HOST_OS
Win32.deleteFile path
#else
Posix.removeLink path
#endif
Update
After digging around the source code for winhugs, it seems the Windows API function unlink is actually being used to delete a file in Hugs:
primFun(primRemoveFile) { /* remove a file */
int rc;
String s = evalName(IOArg(1));
if (!s) {
IOFail(mkIOError(NULL,
nameIllegal,
"Directory.removeFile",
"illegal file name",
&IOArg(1)));
}
rc = unlink(s);
if (rc != 0)
throwErrno("Directory.removeFile", TRUE, NO_HANDLE, &IOArg(1));
IOReturn(nameUnit);
}
In any case, the previous answer is going to hold up in the sense that any permissions constraint is not introduced by Haskell. Rather, any permissions error would be due to the underlying OS environment (user accounts, open files, permissions, etc).
This is related to: How do I read the results of a system() call in C++?
I am trying to do the exact the same thing only that my program needs to pass 'multiple parameters with spaces' to the command. I need the command line output and the exit code from the process.
Example: An example with Textpad. The application I'm really using prints stuff on stdout.
string command1 = "\"C:\Program Files\TextPad 5\Textpad.exe\" C:\readme0.txt";
string command2 = "\"C:\Program Files\TextPad 5\Textpad.exe\" \"C:\read me2.txt\"";
cout << system(command1.c_str()) << endl;
cout << system(command1.c_str()) << endl;
Output:
0
'C:\Program' is not recognized as an internal or external command,
operable program or batch file.
1
The first call to system passes and second one fails with the error above. _popen in Windows works similarly on Windows so no help there. I can easily do this on Linux as I can escape spaces in the parameters without having to use quotes.
An alternative is to write a huge chunk of non-cross-platform code as listed here:
http://msdn.microsoft.com/en-us/library/ms682499(VS.85).aspx
But in case I want to avoid that, are there any alternatives to system() and _popen() on Windows?
Thanks!
The lowest level Windows API function used by _popen() and system() is CreateProcess().
However CreateProcess() is not that simple to use - especially when you want to get the process'es output or write to the process'es input.
CreateProcess() will definitely work with file names that contain space characters (as long as they are written in quotation marks the way you did that).
The following solves the spaces in the path problem. Catching the output of the command is much more difficult, however:
#include <string>
#include <cstdlib>
using namespace std;
int main() {
string cmd = "\"c:\\program files\\notepad++\\notepad++.exe\"";
system( cmd.c_str() );
return 0;
}
A bunch of utility libraries have taken that chunk of non-portable code and wrapped it up with a portable interface. For an example, see Qt's QProcess.
I do this (note - this is VB.NET code), so I can write the output of the command to my log file (it's wrapped in a RunCommand() method):
Try
Dim myprocess As New Process()
myprocess.StartInfo.FileName = "C:\Program Files\TextPad 5\Textpad.exe"
myprocess.StartInfo.RedirectStandardOutput = True
myprocess.StartInfo.UseShellExecute = False
' inArgs are the arguments on the command line to the program
myprocess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
myprocess.StartInfo.Arguments = "C:\readme0.txt"
' the dir to set as default when the program runs
Then myprocess.StartInfo.WorkingDirectory = "C:\Program Files\TextPad 5\"
myprocess.Start()
' grab a reader to the standard output of the program
procReader = myprocess.StandardOutput()
' read all the output from the process
While (Not procReader.EndOfStream)
procLine = procReader.ReadLine()
' write the output to my log
writeNotes(procLine)
End While
procReader.Close()
Catch ex As Exception
' Write the error to my log
writeErrors("Couldn't execute command "C:\Program Files\TextPad 5\Textpad.exe", ex)
End Try
I think ShellExecute() is what you're looking for.
Never use system() in Windows !
Just redirect i/o handles.