Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Implementation of RNFS for Windows #952

Merged
merged 72 commits into from Apr 12, 2023
Merged

Conversation

avmoroz
Copy link
Contributor

@avmoroz avmoroz commented Nov 14, 2020

Created new implementation of RNFS for Windows using C++.
Previous implementation is located in the windows_legacy folder.

copyFolder implemented to account for slow file transfers.

Copy link

@jeanmaried jeanmaried left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Testing out the exists and readFile methods I found that they fail and crash the app when the file path points to a non-existent file. In my case I have a file located at DocumentDirectoryPath + properties.json. When the error is thrown, the catch that is supposed to return a promise.Resolve(false) is never called.

promise.Resolve(true);
}
}
catch (const hresult_error& ex)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This catch is never called if the filepath points to a non-existent path. These are the type of exceptions in the output:

Exception thrown at 0x00007FFED89D4B89 (KernelBase.dll) in MyApp.exe: WinRT originate error - 0x80070002 : 'The system cannot find the file specified.'.
Exception thrown at 0x00007FFED89D4B89 in MyApp.exe: Microsoft C++ exception: winrt::hresult_error at memory location 0x0000003BE39FD5F0.

winrt::hstring base64Content{ Cryptography::CryptographicBuffer::EncodeToBase64String(buffer) };
promise.Resolve(winrt::to_string(base64Content));
}
catch (const hresult_error& ex)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This catch is also not reached if the file path points to non-existent file. These are the type of exceptions in the output:

Exception thrown at 0x00007FFED89D4B89 (KernelBase.dll) in MyApp.exe: WinRT originate error - 0x80070002 : 'The system cannot find the file specified.'.
Exception thrown at 0x00007FFED89D4B89 in MyApp.exe: Microsoft C++ exception: winrt::hresult_error at memory location 0x0000003BE39FD5F0.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed yesterday also these The system cannot find the file specified errors in my tests.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested now more exists method and it seems that error goes to catch block. There is still error in console Exception thrown at 0x00007FFED89D4B89 (KernelBase.dll) in MyApp.exe: WinRT originate error - 0x80070002 : 'The system cannot find the file specified.' maybe it is ok?

exists catch block has bug in error hanlding.

@tero-paananen
Copy link

tero-paananen commented May 20, 2021

Is there bug in error handling for example in RNFSManager::exists ?

catch (const hresult_error& ex)
{
    hresult result{ ex.code() };
    if (result == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) {
        promise.Resolve(false);
    }
    // "Failed to check if file or directory exists.
    promise.Reject(winrt::to_string(ex.message()).c_str());
}

code calls promise twice, first promise.Resolve(false); and then promise.Reject(winrt::to_string(ex.message()).c_str()); if error is that ERROR_FILE_NOT_FOUND

@tero-paananen
Copy link

tero-paananen commented May 20, 2021

When RNFS receives lot of Exception thrown at 0x00007FFED89D4B89 (KernelBase.dll) in MyApp.exe: WinRT originate error - 0x80070002 : 'The system cannot find the file specified. errors is my Visual Studio debug always stopped. I had to press Continue to let app run again. This is not very developer friendly? I had to remove this winrt:hresult_error error from list of Break When Thrown to not always stop this. I do not know what is right solution for this.

error

@jeanmaried
Copy link

When RNFS receives lot of Exception thrown at 0x00007FFED89D4B89 (KernelBase.dll) in MyApp.exe: WinRT originate error - 0x80070002 : 'The system cannot find the file specified. errors is my Visual Studio debug always stopped. I had to press Continue to let app run again. This is not very developer friendly? I had to remove this winrt:hresult_error error from list of Break When Thrown to not always stop this. I do not know what is right solution for this.

error

This is the issue that I'm having.

@exotexot
Copy link

This is also a observation I have made. If this could be fixed appropriately, that would be awesome! @avmoroz

@exotexot
Copy link

Any updated happening here? :(

@asklar
Copy link
Contributor

asklar commented Jul 27, 2021

@chiaramooney could you take on driving to get this merged?

@raaannzzz
Copy link

+1

@emanuelmartin
Copy link

@chiaramooney could you take on driving to get this merged?

So happy to hear that 💯

@chiaramooney
Copy link

@itinance any concerns merging this?

@namrog84
Copy link

namrog84 commented Oct 1, 2021

Any potential update on this getting in? Would love to see it happen!

@emanuelmartin
Copy link

We need a GIF saying "Merge it mate"

@exotexot
Copy link

Anyone tested this with a recent react-native version under Windows 11 ?

@datacana
Copy link

sadly no. example cannot build. does throw errors in react native JsiApiContext.cpp

Screenshot 2021-11-30 231825

@asklar @avmoroz any ideas?

@asklar
Copy link
Contributor

asklar commented Nov 30, 2021

sadly no. example cannot build. does throw errors in react native JsiApiContext.cpp

Screenshot 2021-11-30 231825

@asklar Alexander Sklar FTE @avmoroz any ideas?

See microsoft/react-native-windows#7585 (comment)

@@ -0,0 +1,3 @@
EXPORTS
DllCanUnloadNow = WINRT_CanUnloadNow PRIVATE
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was testing this PR in our code via a patch and was getting weird error around this file when it wasn't using crlf (it appears to be currently lf) Visual Studio 2019 compiler errored out on it.

Consider updating to crlf?

@namrog84
Copy link

namrog84 commented Jan 3, 2022

@asklar, @avmoroz, @tero-paananen

Is there anything still blocking this branch from going in?

It'd be awesome to just get it in, and then would be easier to fix bugs/make PRs to it then.

@asklar
Copy link
Contributor

asklar commented Jan 4, 2022

@asklar, @avmoroz, @tero-paananen

Is there anything still blocking this branch from going in?

It'd be awesome to just get it in, and then would be easier to fix bugs/make PRs to it then.

No concerns from me to merge and fix bugs separately as the pr is already large. However I don't know how much appetite @itinance might have to merge this (as it's been open for a long time), and if further changes are required to fix bugs, I'd be concerned about the velocity with which changes are accepted. So perhaps a fork might be required.

@creambyemute
Copy link

I'm currently facing a problem with user-directory paths that contain Umlaute/accentuated characters

Maybe someone has an idea how to handle the std::string --> std::path conversion correctly?

microsoft/react-native-windows#9315

@creambyemute
Copy link

creambyemute commented Jan 7, 2022

@asklar @namrog84 @avmoroz FYI
I was testing my std::string --> path withUmlaute problem today and got the app working with a few rather small changes in RNFS:

I created a convertPath method and adapted the widely used splitPath method as well.
With a few more changes (using convertPath(...) where splitPath(...) isn't used) + a change to downloadFile(...) (path.string() instead of path.c_str()) it started working.

I don't like this solution yet (as it probably isn't correct?) and it can most likely be further narrowed down and simplified.

std::filesystem::path RNFSManager::convertPath(const std::filesystem::path originalPath) 
{
    winrt::hstring fPathHString = winrt::to_hstring(originalPath.string());
    std::filesystem::path path{fPathHString.c_str()};
    path.make_preferred();
    return path;
}


void RNFSManager::splitPath(const std::string& fullPath, winrt::hstring& directoryPath, winrt::hstring& fileName) noexcept
{
    std::filesystem::path path(fullPath);
    path.make_preferred();
    std::filesystem::path convertedPath = convertPath(path);

    directoryPath = convertedPath.has_parent_path() ? winrt::to_hstring(convertedPath.parent_path().c_str()) : L"";
    fileName = convertedPath.has_filename() ? winrt::to_hstring(convertedPath.filename().c_str()) : L"";
}

winrt::fire_and_forget RNFSManager::downloadFile(...) noexcept
{
    auto filePath{ winrt::to_hstring(path.string()) };
}

// In mkdir and some others
std::filesystem::path firstPath(pathString);
firstPath.make_preferred();
std::filesystem::path path = convertPath(firstPath);

Edit:
After some more tests, it seems that the following is enough when directly using the filesystem::path with UWP/winRT apis.

std::filesystem::path fPath{ stringPath };
fPath.make_preferred();
StorageFolder::GetFolderFromPathAsync(fPath.string())

// Also works
StorageFolder::GetFolderFromPathAsync(fPath.string().c_str())

Edit2:
After some more tests, it seems even better to pass std::wstring instead of std::string as path from JS --> RN-Windows

std::filesystem::path fPath{ wstringPath };
fPath.make_preferred();
StorageFolder::GetFolderFromPathAsync(fPath.wstring())

@creambyemute
Copy link

@namrog84 FYI: I have created a branch (fixUmlautePaths) and PR on https://github.com/wwimmo/react-native-fs if your team wants to try out the changes

@adamgorMSFT
Copy link

Is there anything that needs to happen to help this PR get in? I am sure there are some bugs that need fixing that I'd help contribute to fixes, but I know this PR is massive and going to cause a little bit of hiccup for a moment.

@taduyde
Copy link

taduyde commented Jul 15, 2022

when we merge this branch?

@shanelile
Copy link

Are there any updates to this? Is it blocked by anything?

@itinance itinance merged commit e8e092c into itinance:master Apr 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet