Skip to content

Commit

Permalink
Create temporary folder for Edge in IEMode (#10006)
Browse files Browse the repository at this point in the history
Signed-off-by: jimevans <[email protected]>
  • Loading branch information
guangyuexu authored Nov 3, 2021
1 parent d9f2bb8 commit a33e739
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 2 deletions.
97 changes: 97 additions & 0 deletions cpp/iedriver/BrowserFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,44 @@ void BrowserFactory::LaunchBrowserUsingCreateProcess(PROCESS_INFORMATION* proc_i
delete[] command_line;
}

bool BrowserFactory::DirectoryExists(std::wstring& dir_name) {
DWORD attribs = ::GetFileAttributes(dir_name.c_str());
if (attribs == INVALID_FILE_ATTRIBUTES) {
return false;
}
return (attribs & FILE_ATTRIBUTE_DIRECTORY);
}

bool BrowserFactory::CreateUniqueTempDir(std::wstring &temp_dir) {
// get temporary folder for the current user
wchar_t temp[128];
::GetTempPath(128, temp);
std::wstring wtemp = temp;
if (!DirectoryExists(wtemp)) {
return false;
}

// create a IEDriver temporary folder inside the user level temporary folder
bool temp_dir_created = false;
for (int i=0; i<10; i++) {
std::wstring output = wtemp + L"IEDriver-" + StringUtilities::CreateGuid();
if (DirectoryExists(output)) {
continue;
}

::CreateDirectory(output.c_str(), NULL);
if (!DirectoryExists(output)) {
continue;
}

temp_dir = output;
temp_dir_created = true;
break;
}

return temp_dir_created;
}

void BrowserFactory::LaunchEdgeInIEMode(PROCESS_INFORMATION* proc_info,
std::string* error_message) {
LOG(TRACE) << "Entering BrowserFactory::LaunchEdgeInIEMode";
Expand All @@ -353,6 +391,14 @@ void BrowserFactory::LaunchEdgeInIEMode(PROCESS_INFORMATION* proc_info,
executable_and_url.append(L" --ie-mode-force");
executable_and_url.append(L" --internet-explorer-integration=iemode");

// create a temporary directory for IEDriver test
std::wstring temp_dir;
if (CreateUniqueTempDir(temp_dir)) {
LOG(TRACE) << L"Using temporary folder " << LOGWSTRING(temp_dir) << ".";
executable_and_url.append(L" --user-data-dir=" + temp_dir);
this->edge_user_data_dir_ = temp_dir;
}

executable_and_url.append(L" ");
executable_and_url.append(this->initial_browser_url_);

Expand Down Expand Up @@ -1393,4 +1439,55 @@ bool BrowserFactory::IsEdgeMode() const {
return this->edge_ie_mode_;
}

// delete a folder recursively
int BrowserFactory::DeleteDirectory(const std::wstring &dir_name) {
WIN32_FIND_DATA file_info;

std::wstring file_pattern = dir_name + L"\\*.*";
HANDLE file_handle = ::FindFirstFile(file_pattern.c_str(), &file_info);
if (file_handle != INVALID_HANDLE_VALUE) {
do {
if (file_info.cFileName[0] == '.') {
continue;
}
std::wstring file_path = dir_name + L"\\" + file_info.cFileName;

if (file_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
int return_value = DeleteDirectory(file_path);
if (return_value) {
return return_value;
}
} else {
if (::SetFileAttributes(file_path.c_str(), FILE_ATTRIBUTE_NORMAL) == FALSE) {
return ::GetLastError();
}

if (::DeleteFile(file_path.c_str()) == FALSE) {
return ::GetLastError();
}
}
} while (::FindNextFile(file_handle, &file_info) == TRUE);

::FindClose(file_handle);
DWORD dwError = ::GetLastError();
if (dwError != ERROR_NO_MORE_FILES) {
return dwError;
}

if (::SetFileAttributes(dir_name.c_str(), FILE_ATTRIBUTE_NORMAL) == FALSE) {
return ::GetLastError();
}

if (::RemoveDirectory(dir_name.c_str()) == FALSE) {
return ::GetLastError();
}
}

return 0;
}

std::wstring BrowserFactory::GetEdgeTempDir() {
return this->edge_user_data_dir_;
}

} // namespace webdriver
8 changes: 6 additions & 2 deletions cpp/iedriver/BrowserFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,17 +74,20 @@ class BrowserFactory {
static BOOL CALLBACK FindEdgeBrowserHandles(HWND hwnd, LPARAM arg);

static bool IsWindowsVistaOrGreater(void);
static int DeleteDirectory(const std::wstring &dir_name);

bool IsEdgeMode(void) const;
std::wstring GetEdgeTempDir(void);
private:
static BOOL CALLBACK FindBrowserWindow(HWND hwnd, LPARAM param);


static BOOL CALLBACK FindEdgeWindow(HWND hwnd, LPARAM param);
static bool IsWindowsVersionOrGreater(unsigned short major_version,
unsigned short minor_version,
unsigned short service_pack);

static bool DirectoryExists(std::wstring& dir_name);
static bool CreateUniqueTempDir(std::wstring &temp_dir);

UINT html_getobject_msg_;
HINSTANCE oleacc_instance_handle_;

Expand Down Expand Up @@ -131,6 +134,7 @@ class BrowserFactory {

bool edge_ie_mode_;
std::wstring edge_executable_location_;
std::wstring edge_user_data_dir_;
};

} // namespace webdriver
Expand Down
22 changes: 22 additions & 0 deletions cpp/iedriver/IECommandExecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ LRESULT IECommandExecutor::OnCreate(UINT uMsg,
this->command_handlers_ = new CommandHandlerRepository();

this->is_edge_chromium_ = false;
this->edge_temp_dir_ = L"";

return 0;
}
Expand Down Expand Up @@ -465,6 +466,26 @@ LRESULT IECommandExecutor::OnBrowserQuit(UINT uMsg,
} else {
LOG(WARN) << "Unable to find browser to quit with ID " << browser_id;
}

// Delete IEDriver temporary folder when IEDriver drvies Edge in IEMode.
// Note that the this->factory_ object might have been deleted.
if (this->edge_temp_dir_ != L"") {
for (int i=0;i<100;i++) {
::Sleep(100); // wait for the Edge browser completing read/write work
// the delete usually completes in 1 retries
if (BrowserFactory::DeleteDirectory(edge_temp_dir_)) {
// directory delete failed when some files/folders are locked
LOG(TRACE) << "Failed to delete Edge temporary user data directory " << LOGWSTRING(edge_temp_dir_)
<< ", retrying " << i+1 << "...";
} else {
// the temporary folder has been deleted
LOG(TRACE) << "Deleted Edge temporary user data directory " << LOGWSTRING(edge_temp_dir_) << ".";
break;
}
}
this->edge_temp_dir_ = L"";
}

return 0;
}

Expand Down Expand Up @@ -1430,6 +1451,7 @@ int IECommandExecutor::CreateNewBrowser(std::string* error_message) {
LOG(WARN) << "Browser was launched and attached to, but is still busy.";
}
wrapper->SetFocusToBrowser();
this->edge_temp_dir_ = this->factory_->GetEdgeTempDir();
return WD_SUCCESS;
}

Expand Down
1 change: 1 addition & 0 deletions cpp/iedriver/IECommandExecutor.h
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ class IECommandExecutor : public CWindowImpl<IECommandExecutor>, public IElement
bool use_strict_file_interactability_;
bool is_edge_chromium_;
std::string edge_executable_path_;
std::wstring edge_temp_dir_;

Command current_command_;
std::string serialized_response_;
Expand Down

0 comments on commit a33e739

Please sign in to comment.