2013-08-28 34 views
7

Chức năng SHGetFolderPath() không được dùng nữa bắt đầu bằng Windows Vista: http://msdn.microsoft.com/en-us/library/bb762181%28v=VS.85%29.aspxSHGetFolderPath Không được chấp nhận: Điều gì là thay thế để truy xuất đường dẫn cho các thư mục Windows?

Cách khác để truy xuất đường dẫn đến Thư mục ứng dụng trong Windows là gì?

SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, 0, szPath) 

Bên cạnh đó, tại sao tôi có được những lỗi khi sử dụng chức năng này:

Error 1 error C2065: 'CSIDL_COMMON_APPDATA' : undeclared identifier 

Error 2 error C3861: 'SHGetFolderPath': identifier not found 
+0

Xem: http://msdn.microsoft.com/en-us/library/windows/desktop/bb762181(v=vs.85).aspx và http://msdn.microsoft .com/vi-us/library/windows/desktop/bb762188 (v = vs.85) .aspx và cuối cùng, http://msdn.microsoft.com/en-us/library/windows/desktop/dd378457(v= vs.85) .aspx – enhzflep

Trả lời

11

Phương án thay thế được mô tả trong tài liệu mà bạn liên kết. Cụ thể là SHGetKnownFolderPath.

Tuy nhiên, SHGetKnownFolderPath chỉ khả dụng trên Vista trở lên. Vì vậy, nếu bạn sử dụng thời gian tải liên kết, và chạy một chương trình gọi SHGetKnownFolderPath trên XP, sau đó chương trình đó sẽ không bắt đầu. Đây rõ ràng là một vấn đề nếu bạn muốn hỗ trợ XP.

Bây giờ, bạn có thể chuyển sang liên kết thời gian chạy của SHGetKnownFolderPath. Thực hiện kiểm tra phiên bản trước khi bạn gọi nó, và nếu chức năng không có sẵn, sau đó rơi trở lại SHGetFolderPath.

Cá nhân, tôi sẽ không cho phép việc ngừng sử dụng này khiến bạn lo lắng quá mức. Microsoft nổi tiếng về việc duy trì khả năng tương thích ngược. Đừng mong đợi SHGetFolderPath sẽ biến mất bất kỳ lúc nào. Bạn sẽ thấy rằng SHGetFolderPath tồn tại trong Windows 8 và tôi hy vọng nó vẫn có mặt trong bất kỳ Windows nào hiện tại là 10 năm kể từ bây giờ. Lời khuyên của tôi là gắn bó với thời gian tải liên kết và chỉ chuyển sang SHGetKnownFolderPath khi bạn từ bỏ hỗ trợ XP.

Câu hỏi khác của bạn, mà bạn yêu cầu chỉnh sửa, là cách gọi số SHGetFolderPath. Bạn cần phải tôn trọng các yêu cầu được đặt ra ở dưới cùng của chủ đề tài liệu MSDN mà bạn đã liên kết trong câu hỏi của bạn. Cụ thể, bao gồm Shlobj.h và chuyển Shlobj.lib cho trình liên kết.

+0

Nhưng Cách truy cập thư mục Dữ liệu ứng dụng? – user88004

+2

Đó là một câu hỏi hoàn toàn khác. Tôi đã cập nhật câu trả lời để đề cập đến nó, nhưng tôi sẽ đề nghị rằng trong tương lai bạn phải giữ một câu hỏi tại một thời điểm. –

2

Nó được liên kết ngay ở phía trên cùng, SHGetKnownFolderPath.

CSIDL_COMMON_APPDATA được thay thế bằng FOLDERID_ProgramData trong API mới.

+0

Nhưng Cách truy cập thư mục Dữ liệu Ứng dụng? – user88004

0

Tôi đã thử nghiệm bằng cách sử dụng SHGetFolderPath() với Visual Studio 2015 Enterprise trên PC Windows 10 và nó được biên dịch và hoạt động tốt để tìm thư mục chính của người dùng hiện tại. Trong trang của Windows Dev Center trên SHGetFolderPath()SHGetFolderPath function có các lưu ý sau:

Note Tính đến Windows Vista, chức năng này chỉ đơn thuần là một wrapper cho SHGetKnownFolderPath. Giá trị CSIDL được dịch sang số KNOWNFOLDERID được liên kết và sau đó gọi là SHGetKnownFolderPath. Ứng dụng mới nên sử dụng hệ thống thư mục đã biết thay vì hệ thống thư mục cũ hơn CSIDL chỉ được hỗ trợ để tương thích ngược.

Như David Heffman đã chỉ ra câu trả lời của mình, Microsoft có lịch sử giữ tính tương thích ngược trong nhiều năm, đặc biệt khi họ có thể thực hiện chức năng cũ hơn và chuyển hướng đến chức năng mới. Giá trị CSIDL dường như có giá trị KNOWNFOLDERID tương ứng.Xem này table of the CSIDL constants với chú thích ngắn gọn và giá trị KNOWNFOLDERID tương ứng.

Ví dụ về việc sử dụng hàm sau. Việc sử dụng này truy xuất thư mục người dùng hiện tại của người dùng (ví dụ: "C: \ Users \ myuser \ Documents" trong Windows 7) và sau đó thêm tên thư mục vào cuối đường dẫn bằng cách sử dụng hàm PathAppend().

TCHAR achDevice[MAX_PATH]; 
HRESULT hr; 
// include file ShlObj.h contains list of CSIDL defines however only a subset 
// are supported with Windows 7 and later. 
// for the 3rd argument, hToken, can be a specified Access Token or SSID for 
// a user other than the current user. Using NULL gives us the current user. 
if (SUCCEEDED(hr = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, achDevice))) { 
    // append a folder name to the user's Documents directory. 
    // the Path Handling functions are pretty handy. 
    PathAppend(achDevice, L"xxx"); 
} 

Một lỗi có thể xảy ra là một hoặc nhiều đối số không hợp lệ (hr == E_INVALIDARG). Giá trị trả lại là S_OK cho biết cuộc gọi đã thành công.

Có một vài hằng số CSIDL có thể được sử dụng để sửa đổi kết quả của hàm như CSIDL_FLAG_CREATE bằng cách sử dụng toán tử bitwise OR. Tôi không chắc các nhà khai thác đó sẽ hoạt động tốt như thế nào với Windows 7 trở lên.

Có giới hạn đối với hằng số được hỗ trợ CSIDL với Windows 7 trở lên. Nó cũng giống như có thể có các vấn đề có thể khắc phục trong các thư mục phức tạp, từ xa được gắn kết, chuyển hướng và/hoặc chia sẻ trong Active Directory hoặc môi trường tương tự.

Xem thêm KNOWNFOLDERID bao gồm bảng cho biết một số giới hạn của CSIDLSHGetFolderPath(). Một số ví dụ từ bảng số CSIDL hằng số có thể hữu ích.

CSIDL_LOCAL_APPDATA - %USERPROFILE%\AppData\Local 
CSIDL_MYDOCUMENTS - %USERPROFILE%\Document 
CSIDL_PERSONAL - %USERPROFILE%\Documents 
CSIDL_FONTS -  %windir%\Fonts 
CSIDL_MYMUSIC -  %USERPROFILE%\Music 
CSIDL_MYPICTURES - %USERPROFILE%\Pictures 
CSIDL_COMMON_APPDATA - %ALLUSERSPROFILE% (%ProgramData%, %SystemDrive%\ProgramData) 
CSIDL_COMMON_DOCUMENTS - %PUBLIC%\Documents 

Bằng cách này, Shell Path Handling Functions là thư viện phương pháp tốt để thao tác đường dẫn tệp.

Xem thêm Where to put common writable application files?

Các vấn đề liên quan