Skip to content

Commit b49d44b

Browse files
committed
fix: Simplifying Windows AppData path detection to avoid problematic ctypes-based path retrieval
1 parent 930ab41 commit b49d44b

File tree

5 files changed

+14
-86
lines changed

5 files changed

+14
-86
lines changed

backend/config.py

Lines changed: 5 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -37,39 +37,11 @@ def _get_config_path() -> Path:
3737
# Running as PyInstaller bundle - use AppData location
3838
import os
3939
if os.name == 'nt': # Windows
40-
import ctypes
41-
42-
# Define HRESULT manually for PyInstaller compatibility
43-
try:
44-
from ctypes import wintypes
45-
HRESULT = wintypes.HRESULT
46-
except AttributeError:
47-
# PyInstaller sometimes doesn't include all wintypes
48-
HRESULT = ctypes.c_long
49-
50-
CSIDL_LOCAL_APPDATA = 0x001c
51-
SHGetFolderPath = ctypes.windll.shell32.SHGetFolderPathW
52-
53-
try:
54-
from ctypes import wintypes
55-
SHGetFolderPath.argtypes = [wintypes.HWND, ctypes.c_int, wintypes.HANDLE, wintypes.DWORD, wintypes.LPCWSTR]
56-
SHGetFolderPath.restype = HRESULT
57-
path_buf = ctypes.create_unicode_buffer(wintypes.MAX_PATH)
58-
result = SHGetFolderPath(0, CSIDL_LOCAL_APPDATA, 0, 0, path_buf)
59-
if result == 0:
60-
return Path(path_buf.value) / "Echo" / "config.yaml"
61-
else:
62-
return Path.home() / "AppData" / "Local" / "Echo" / "config.yaml"
63-
except AttributeError:
64-
# Fallback if wintypes are not available
65-
SHGetFolderPath.argtypes = [ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_uint, ctypes.c_wchar_p]
66-
SHGetFolderPath.restype = HRESULT
67-
path_buf = ctypes.create_unicode_buffer(260) # MAX_PATH
68-
result = SHGetFolderPath(0, CSIDL_LOCAL_APPDATA, 0, 0, path_buf)
69-
if result == 0:
70-
return Path(path_buf.value) / "Echo" / "config.yaml"
71-
else:
72-
return Path.home() / "AppData" / "Local" / "Echo" / "config.yaml"
40+
appdata = os.environ.get('LOCALAPPDATA')
41+
if appdata:
42+
return Path(appdata) / "Echo" / "config.yaml"
43+
else:
44+
return Path.home() / "AppData" / "Local" / "Echo" / "config.yaml"
7345
else:
7446
return Path.home() / ".echo" / "config.yaml"
7547
else:

backend/paths.py

Lines changed: 5 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -35,43 +35,11 @@ def _get_base_path(self) -> Path:
3535
if getattr(sys, 'frozen', False):
3636
# Running as PyInstaller bundle
3737
if os.name == 'nt': # Windows
38-
import ctypes
39-
40-
# Define HRESULT manually for PyInstaller compatibility
41-
try:
42-
from ctypes import wintypes
43-
HRESULT = wintypes.HRESULT
44-
except AttributeError:
45-
# PyInstaller sometimes doesn't include all wintypes
46-
HRESULT = ctypes.c_long
47-
48-
CSIDL_LOCAL_APPDATA = 0x001c
49-
SHGetFolderPath = ctypes.windll.shell32.SHGetFolderPathW
50-
51-
try:
52-
from ctypes import wintypes
53-
SHGetFolderPath.argtypes = [wintypes.HWND, ctypes.c_int, wintypes.HANDLE, wintypes.DWORD, wintypes.LPCWSTR]
54-
SHGetFolderPath.restype = HRESULT
55-
56-
path_buf = ctypes.create_unicode_buffer(wintypes.MAX_PATH)
57-
result = SHGetFolderPath(0, CSIDL_LOCAL_APPDATA, 0, 0, path_buf)
58-
59-
if result == 0:
60-
return Path(path_buf.value) / "Echo"
61-
else:
62-
return Path.home() / "AppData" / "Local" / "Echo"
63-
except AttributeError:
64-
# Fallback if wintypes are not available
65-
SHGetFolderPath.argtypes = [ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_uint, ctypes.c_wchar_p]
66-
SHGetFolderPath.restype = HRESULT
67-
68-
path_buf = ctypes.create_unicode_buffer(260) # MAX_PATH
69-
result = SHGetFolderPath(0, CSIDL_LOCAL_APPDATA, 0, 0, path_buf)
70-
71-
if result == 0:
72-
return Path(path_buf.value) / "Echo"
73-
else:
74-
return Path.home() / "AppData" / "Local" / "Echo"
38+
appdata = os.environ.get('LOCALAPPDATA')
39+
if appdata:
40+
return Path(appdata) / "Echo"
41+
else:
42+
return Path.home() / "AppData" / "Local" / "Echo"
7543
else:
7644
return Path.home() / ".echo"
7745
else:

config.yaml.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
api:
22
# Replace with your actual API key from https://dashscope.aliyun.com/
3-
dashscope_key: YOUR_API_KEY_HERE
3+
dashscope_key: '' # Your DashScope API Key here
44

55
models:
66
instruction_voice: Elias

frontend/package-lock.json

Lines changed: 0 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

launcher.py

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,9 @@
2727
def get_app_data_path():
2828
"""Get the application data directory for Echo."""
2929
if os.name == 'nt': # Windows
30-
import ctypes
31-
from ctypes import wintypes
32-
33-
CSIDL_LOCAL_APPDATA = 0x001c
34-
SHGetFolderPath = ctypes.windll.shell32.SHGetFolderPathW
35-
SHGetFolderPath.argtypes = [wintypes.HWND, ctypes.c_int, wintypes.HANDLE, wintypes.DWORD, wintypes.LPCWSTR]
36-
SHGetFolderPath.restype = wintypes.HRESULT
37-
38-
path_buf = ctypes.create_unicode_buffer(wintypes.MAX_PATH)
39-
result = SHGetFolderPath(0, CSIDL_LOCAL_APPDATA, 0, 0, path_buf)
40-
41-
if result == 0:
42-
return Path(path_buf.value) / "Echo"
30+
appdata = os.environ.get('LOCALAPPDATA')
31+
if appdata:
32+
return Path(appdata) / "Echo"
4333
else:
4434
return Path.home() / "AppData" / "Local" / "Echo"
4535
else:

0 commit comments

Comments
 (0)