When I select a reparse point from %LocalAppData%\Microsoft\WindowsApps (e.g. julia.exe) using a QFileDialog and click the Open
button an error dialog pops up
Clicking Ok
just closes the error dialog but doesn't close the file browser window.
Here's a minimal example that demonstrates the problem. Click the Browse button and select any .exe file from %LocalAppData%\Microsoft\WindowsApps and the error dialog pops up.
from PySide6.QtWidgets import QApplication, QDialog, QPushButton, QFileDialog, QLineEdit, QVBoxLayout
class Main(QDialog):
def __init__(self):
super().__init__()
self.button = QPushButton("Browse")
self.le = QLineEdit()
self.lo = QVBoxLayout()
self.lo.addWidget(self.button)
self.lo.addWidget(self.le)
self.setLayout(self.lo)
self.button.clicked.connect(self.open_browser)
def open_browser(self):
self.le.clear()
answer = QFileDialog.getOpenFileName(self, "Open")
if answer[0] != "":
self.le.setText(answer[0])
return
if __name__ == '__main__':
app = QApplication()
window = Main()
window.show()
app.exec()
I'm aware that %LocalAppData%\Microsoft\WindowsApps is in PATH and I do not actually need to select the reparse point file anyway but this is an error dialog that some users of my app may encounter and I'd like to deal with it somehow.
The question is, how can I select the reparse point file and then return it from the QFileDialog? Is there a way to catch the error that causes the error dialog to pop up and then simply return the full path as the answer
in the above code snippet?
Win: 10
Python: 3.10.8
PySide6: 6.5.2
Things tried & considered:
QDialog.accepted
signal but this is triggered too late. The error dialog pops up before the Slot is processed.QFileDialog::DontResolveSymlinks
) did not help. Same error dialog pops up.QFileDialog::DontUseNativeDialog
). I don't want to do this because the Windows users of my app are accustomed to their native file browser.You can't do that in the current implementation, as you can see in the source. The FOS_NOVALIDATE
flag is required to remedy a limitation for reparse points. (The Win32 and COM file dialog API are pretty old and do not support reparse points).
So, your best bet is using another GUI library. One such way is calling the Win32 API directly using the pywin32
like the following.
import os
import win32gui, win32con
dir = os.path.expandvars('%LocalAppData%\\Microsoft\\WindowsApps')
print(dir)
r = win32gui.GetOpenFileNameW(
InitialDir = dir,
Flags = win32con.OFN_EXPLORER | win32con.OFN_NOCHANGEDIR |
win32con.OFN_PATHMUSTEXIST | win32con.OFN_FILEMUSTEXIST |
win32con.OFN_NOVALIDATE,
Title = 'Open',
)
print(r)