0

I am trying to get the windows path using Qt and C++. The below code compiles, but not gettting the windows folder path in Qt. The same code works in Visual Studio 2010

      wchar_t path[MAX_PATH];
      SHGetFolderPath(NULL, CSIDL_WINDOWS, NULL, 0, path);

The below code change seems working:

     int const bufferSize = 512;        
     QScopedPointer<WCHAR> dirPath(new WCHAR[bufferSize]);
     ZeroMemory( dirPath.operator ->(), bufferSize);
     SHGetFolderPath(NULL, CSIDL_WINDOWS, NULL, 0, dirPath.operator ->());
5
  • What do you mean by "in QT"? Qt is a library, it's not comparable to an IDE like Visual Studio. You can use Qt with a multitude of compilers, including Visual C++ compiler used by Visual Studio. Commented Jun 5, 2012 at 17:06
  • I need to get the windows path using QT 4.6.3 using windows APIs Commented Jun 5, 2012 at 17:07
  • 1
    Are you referring to the Qt Creator IDE? That is not the same as Qt. As it stands your question has nothing to do with Qt. And it's Qt, not QT. Commented Jun 5, 2012 at 17:09
  • My devleopment environment is QT Creator/QT library, also I am using Windows APIs. Commented Jun 5, 2012 at 17:10
  • This answer worked for me. Commented Dec 23, 2016 at 16:28

6 Answers 6

2

There isn't a Qt function to do this, but what you are asking could be achieved by reading the environtment variable WINDIR:

QStringList env_list(QProcess::systemEnvironment());

int idx = env_list.indexOf(QRegExp("^WINDIR=.*", Qt::CaseInsensitive));
if (idx > -1)
{
    QStringList windir = env_list[idx].split('=');
    qDebug() << "Var : " << windir[0];
    qDebug() << "Path: " << windir[1];
}

Outputs:

Var :  "WINDIR"
Path:  "C:\WINDOWS"
Sign up to request clarification or add additional context in comments.

3 Comments

Not necessarily if Windows is installed somewhere else (is that possible?), or is called something else on a localized version. Lots of people hard coded "Program Files" in their apps and got bitten by 64bit
It's was people finding their app is now in "Program Files(x86)". Does "Windows" not get translated?
I rewrote the answer, it's worth checking it out. Maybe it's appropriate to delete your comments as well since they are outdated.
1
QString windowsInstallPath;

#ifdef Q_WS_WIN
QDir d;
if (d.cd("%windir%"))
    windowsInstallPath = d.absolutePath();
#endif

if (!windowsInstallPath.isNull())
    qDebug() << windowsInstallPath;
else
    qDebug() << "Not compiled for Windows";

Should work.

Comments

1

I think another very reasonable way to get the Windows directory would be to get it from the environment passed to the program:

QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
qDebug() << env.value("windir");

https://doc.qt.io/qt-5/qprocessenvironment.html

Comments

0

I don't think there is a specific Qt function to do this.

The nearest is QSysinfo which tells you the windows version. However SHGetFolderPath() shoudl work in Qt just as well as any other win API call.

ps In Windows vista-> this is replaced with SHGetKnownFolderPath

2 Comments

It seems an issue with the variable type wchar_t path[MAX_PATH], I think its compatible with QT
Possibly dependign on the UNICODE setting in vs2010 the function may not be included in wide char form
0

Here is a one line solution:

QString winPath = QString::fromUtf8(qgetenv("windir"));

This can also be used for any environment variable. I am not sure if qgetenv is available in Qt4 but it is in Qt5.

Comments

0

If your application is not Terminal Services aware, you may get a different directory under TS environment. Found this out myself today, not that I've ever been bit by %windir% or %SystemRoot% or using the ShGetKnownFolderPath or GetWindowsDirectory APIs.

I've opted for using GetSystemWindowsDirectory which exists Windows 2000 and upward. Microsoft's page for the function is here.

Further explanation by Raymond Chen is here.

Finally, the code...

It's written in Delphi 6. Sorry about that :) It's what I'm coding in at the moment, but if you have code for GetWindowsDirectory in your language, then just a few copy + renames are needed as the function signatures are identical. Note: this code is ANSI (...single byte chars in Delphi 6).

function GetSystemWindowsDirectoryA(lpBuffer: PAnsiChar; uSize: UINT): UINT; stdcall; external kernel32 name 'GetSystemWindowsDirectoryA';

function GetSystemWindowsDirectory: string;
var
  buf: array[0..MAX_PATH] of Char;
  resultLength: Cardinal;
begin
  resultLength := GetSystemWindowsDirectoryA(@buf, SizeOf(buf));
  if resultLength = 0 then
    RaiseLastOSError;
  SetLength(Result, resultLength);
  Move(buf, PChar(Result)^, resultLength);
end;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.