「VBA Edge制御 更新自動化コマンドプロンプトプログラム」の版間の差分

提供:yonewiki
編集の要約なし
47行目: 47行目:




そして
そして、以下のようにコードを作成します。
 
 
<yjavascript></script>
<!--
data-line-num-start="1"
data-line-highlight="3, 10-"
data-max-lines="10"
-->
<div class="hljs-wrap"><pre data-label="GetWebDriver.cpp" class="pre-wrap">
<code class="language-cpp">#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <filesystem>
#include <windows.h>
#include <winhttp.h>
#include <typeinfo>
&nbsp;
#include <zip.h>
&nbsp;
#pragma comment(lib, "winhttp.lib")
#pragma comment(lib, "Version.lib")
#pragma comment(lib, "zip.lib")
&nbsp;
std::string GetVersion(const std::string& path) {
    DWORD handle;
    DWORD size = GetFileVersionInfoSizeA(path.c_str(), &handle);
    if (size == 0) {
        throw std::runtime_error("Failed to get version info size.");
    }
&nbsp;
    std::vector<char> data(size);
    if (!GetFileVersionInfoA(path.c_str(), handle, size, data.data())) {
        throw std::runtime_error("Failed to get version info.");
    }
&nbsp;
    VS_FIXEDFILEINFO* versionInfo;
    UINT len;
    if (!VerQueryValueA(data.data(), "\\", (LPVOID*)&versionInfo, &len)) {
        throw std::runtime_error("Failed to query version info.");
    }
&nbsp;
    DWORD major = (versionInfo->dwFileVersionMS >> 16) & 0xffff;
    DWORD minor = versionInfo->dwFileVersionMS & 0xffff;
    DWORD build = (versionInfo->dwFileVersionLS >> 16) & 0xffff;
    DWORD revision = versionInfo->dwFileVersionLS & 0xffff;
&nbsp;
    return std::to_string(major) + "." +
        std::to_string(minor) + "." +
        std::to_string(build) + "." +
        std::to_string(revision);
}
&nbsp;
std::string GetHttpResponse(const std::wstring& host, const std::wstring& path) {
    HINTERNET session = WinHttpOpen(L"Downloader", WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY, NULL, NULL, 0);
    if (!session) {
        throw std::runtime_error("Failed to open WinHTTP session.");
    }
&nbsp;
    HINTERNET connect = WinHttpConnect(session, host.c_str(), INTERNET_DEFAULT_HTTPS_PORT, 0);
    if (!connect) {
        WinHttpCloseHandle(session);
        throw std::runtime_error("Failed to connect to host.");
    }
&nbsp;
    HINTERNET request = WinHttpOpenRequest(connect, L"GET", path.c_str(), NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE);
    if (!request) {
        WinHttpCloseHandle(connect);
        WinHttpCloseHandle(session);
        throw std::runtime_error("Failed to open HTTP request.");
    }
&nbsp;
    if (!WinHttpSendRequest(request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0)) {
        WinHttpCloseHandle(request);
        WinHttpCloseHandle(connect);
        WinHttpCloseHandle(session);
        throw std::runtime_error("Failed to send HTTP request.");
    }
&nbsp;
    if (!WinHttpReceiveResponse(request, NULL)) {
        WinHttpCloseHandle(request);
        WinHttpCloseHandle(connect);
        WinHttpCloseHandle(session);
        throw std::runtime_error("Failed to receive HTTP response.");
    }
&nbsp;
    DWORD size = 0;
    WinHttpQueryDataAvailable(request, &size);
&nbsp;
    std::string response(size, '\0');
    DWORD downloaded;
    WinHttpReadData(request, /*&response[0]*/ response.data(), size, &downloaded);
&nbsp;
    WinHttpCloseHandle(request);
    WinHttpCloseHandle(connect);
    WinHttpCloseHandle(session);
&nbsp;
    return response;
}
&nbsp;
void Download(const std::wstring& url, const std::string& extractDir) {
    HINTERNET session = WinHttpOpen(L"Downloader", WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY, NULL, NULL, 0);
    URL_COMPONENTS components = { 0 };
    components.dwStructSize = sizeof(URL_COMPONENTS);
    components.dwHostNameLength = -1;
    components.dwUrlPathLength = -1;
&nbsp;
    wchar_t host[256];
    wchar_t path[1024];
&nbsp;
    components.lpszHostName = host;
    components.lpszUrlPath = path;
&nbsp;
    if (!WinHttpCrackUrl(url.c_str(), 0, 0, &components)) {
        throw std::runtime_error("Failed to parse URL.");
    }
&nbsp;
    HINTERNET connect = WinHttpConnect(session, components.lpszHostName, INTERNET_DEFAULT_HTTPS_PORT, 0);
    if (!connect) {
        WinHttpCloseHandle(session);
        throw std::runtime_error("Failed to connect to host.");
    }
&nbsp;
    HINTERNET request = WinHttpOpenRequest(connect, L"GET", components.lpszUrlPath, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE);
    if (!request) {
        WinHttpCloseHandle(connect);
        WinHttpCloseHandle(session);
        throw std::runtime_error("Failed to open HTTP request.");
    }
&nbsp;
    if (!WinHttpSendRequest(request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0)) {
        WinHttpCloseHandle(request);
        WinHttpCloseHandle(connect);
        WinHttpCloseHandle(session);
        throw std::runtime_error("Failed to send HTTP request.");
    }
&nbsp;
    if (!WinHttpReceiveResponse(request, NULL)) {
        WinHttpCloseHandle(request);
        WinHttpCloseHandle(connect);
        WinHttpCloseHandle(session);
        throw std::runtime_error("Failed to receive HTTP response.");
    }
&nbsp;
    DWORD size = 0;
    WinHttpQueryDataAvailable(request, &size);
&nbsp;
    std::vector<char> data;
    DWORD downloaded = 0;
    do {
        DWORD size = 0;
        WinHttpQueryDataAvailable(request, &size);
        if (size == 0) break;
 
        std::vector<char> buffer(size);
        DWORD bytesRead = 0;
        if (!WinHttpReadData(request, buffer.data(), size, &bytesRead)) {
            throw std::runtime_error("Failed to read HTTP response data.");
        }
        data.insert(data.end(), buffer.begin(), buffer.begin() + bytesRead);
        downloaded += bytesRead;
    } while (true);
&nbsp;
    std::filesystem::create_directory(extractDir);
    std::ofstream out(extractDir + "\\driver.zip", std::ios::binary);
    out.write(data.data(), downloaded);
    out.close();
&nbsp;
    WinHttpCloseHandle(request);
    WinHttpCloseHandle(connect);
    WinHttpCloseHandle(session);
}
&nbsp;
std::string GetVersionFilePath(const std::string& browser, const std::string& version) {
    return browser + "_" + version;
}
&nbsp;
bool IsVersionDownloaded(const std::string& versionFilePath) {
    return std::filesystem::exists(versionFilePath);
}
&nbsp;
void SaveVersionFile(const std::string& versionFilePath) {
    std::ofstream file(versionFilePath);
    if (file) {
        file << "Downloaded";
        file.close();
    }
}
void extractZip(const std::string& zipPath, const std::string& extractDir) {
    int zipError = 0;
&nbsp;
    // ZIPファイルを開く
    zip_t* zip = zip_open(zipPath.c_str(), 0, &zipError);
    if (!zip) {
        std::cerr << "Failed to open ZIP file. Error code: " << zipError << std::endl;
        return;
    }
&nbsp;
    // エントリ数を取得
    zip_int64_t num_entries = zip_get_num_entries(zip, 0);
    for (zip_int64_t i = 0; i < num_entries; i++) {
        // ファイル名を取得
        const char* name = zip_get_name(zip, i, 0);
        if (!name) {
            std::cerr << "Failed to get entry name for index " << i << std::endl;
            continue;
        }
&nbsp;
        // ファイル名をstd::stringに変換
        std::string entryName(name);
&nbsp;
        // ファイル情報を取得
        zip_stat_t stat;
        if (zip_stat_index(zip, i, 0, &stat) == -1) {
            std::cerr << "Failed to get entry stats for " << entryName << std::endl;
            continue;
        }
&nbsp;
        // フルパスを作成
        std::filesystem::path fullPath = std::filesystem::path(extractDir) / entryName;
&nbsp;
        // フォルダの場合、ディレクトリを作成
        if (entryName.back() == '/') { // ZIP形式ではフォルダ名は末尾に'/'が付く
            std::filesystem::create_directories(fullPath);
            continue;
        }
&nbsp;
        // ファイルを開く
        zip_file_t* zf = zip_fopen_index(zip, i, 0);
        if (!zf) {
            std::cerr << "Failed to open file inside ZIP: " << entryName << std::endl;
            continue;
        }
&nbsp;
        // ファイル内容を読み込む
        std::string contents(stat.size, '\0'); // std::stringでメモリ確保
        if (zip_fread(zf, &contents[0], stat.size) == -1) {
            std::cerr << "Failed to read file: " << entryName << std::endl;
            zip_fclose(zf);
            continue;
        }
&nbsp;
        // 親ディレクトリを作成(必要であれば)
        std::filesystem::create_directories(fullPath.parent_path());
&nbsp;
        // ファイルを保存
        std::ofstream out(fullPath, std::ios::binary);
        if (!out) {
            std::cerr << "Failed to write file: " << fullPath << std::endl;
            zip_fclose(zf);
            continue;
        }
        out.write(contents.data(), contents.size());
        out.close();
&nbsp;
        // ファイルを閉じる
        zip_fclose(zf);
    }
&nbsp;
    // ZIPファイルを閉じる
    zip_close(zip);
}
&nbsp;
void renameFile(const std::string& dirPath, const std::string& oldName, const std::string& newName) {
    // 古いファイルのフルパス
    std::filesystem::path oldFilePath = std::filesystem::path(dirPath) / oldName;
&nbsp;
    // 新しいファイルのフルパス
    std::filesystem::path newFilePath = std::filesystem::path(dirPath) / newName;
&nbsp;
    try {
        // ファイル名を変更
        std::filesystem::rename(oldFilePath, newFilePath);
        std::cout << "File renamed from " << oldFilePath << " to " << newFilePath << std::endl;
    }
    catch (const std::filesystem::filesystem_error& e) {
        std::cerr << "Error renaming file: " << e.what() << std::endl;
    }
}
&nbsp;
void deleteDirectory(const std::string& dirPath) {
    try {
        // 指定したディレクトリが存在するか確認
        if (std::filesystem::exists(dirPath)) {
            // 再帰的に削除
            std::filesystem::remove_all(dirPath);
            std::cout << "Deleted directory and contents: " << dirPath << std::endl;
        }
        else {
            std::cerr << "Directory does not exist: " << dirPath << std::endl;
        }
    }
    catch (const std::filesystem::filesystem_error& e) {
        std::cerr << "Error deleting directory: " << e.what() << std::endl;
    }
}
&nbsp;
void copyAndRenameFile(const std::string& sourcePath, const std::string& destPath) {
    try {
        // コピー先の親ディレクトリを作成(存在しない場合)
        std::filesystem::create_directories(std::filesystem::path(destPath).parent_path());
 
        // ファイルをコピー
        std::filesystem::copy_file(sourcePath, destPath, std::filesystem::copy_options::overwrite_existing);
 
        std::cout << "File copied from " << sourcePath << " to " << destPath << std::endl;
    }
    catch (const std::filesystem::filesystem_error& e) {
        std::cerr << "Error copying file: " << e.what() << std::endl;
    }
}
&nbsp;
int main(int argc, char* argv[]) {
&nbsp;
    if (argc < 2 || argv[1] == nullptr) {
        std::cerr << "起動引数1のブラウザの種別の指定がありません。edge or chrome" << std::endl;
        return 1;
    }
&nbsp;
    if (argc < 3 || argv[2] == nullptr) {
        std::cerr << "起動引数2のWindowsユーザ名の指定がありません。" << std::endl;
        return 1;
    }
    std::string browser = argv[1];
    std::string userId = argv[2];
    std::string baseDir = "C:\\Users\\" + userId + "\\AppData\\Local\\SeleniumBasic";
&nbsp;
    std::string version;
    std::wstring driverUrl;
    std::string tempDir;
    std::string outputPath;
&nbsp;
    try {
        if (browser == "chrome") {
            version = GetVersion("C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe");
            std::wstring driverUrl = L"https://googlechromelabs.github.io/chrome-for-testing/LATEST_RELEASE_" + std::wstring(version.begin(), version.end());
            tempDir = "chromedriver_temp";
            outputPath = baseDir + "\\chromedriver.exe";
            //DownloadAndExtract(driverUrl, tempDir, baseDir + "\\chromedriver.exe");
        }
        else if (browser == "edge") {
            version = GetVersion("C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe");
            driverUrl = L"https://msedgedriver.azureedge.net/" + std::wstring(version.begin(), version.end()) + L"/edgedriver_win64.zip";
            tempDir = "edgedriver_temp";
            outputPath = baseDir + "\\edgedriver.exe";
            //DownloadAndExtract(driverUrl, tempDir, baseDir + "\\edgedriver.exe", "msedgedriver.exe");
        }
        else {
            std::cerr << "Unsupported browser: edge or chrome" << browser << std::endl;
            return 1;
        }
&nbsp;       
&nbsp;
        std::string versionFilePath = GetVersionFilePath(browser, version);
&nbsp;
        if (IsVersionDownloaded(versionFilePath)) {
            std::cout << "Version " << version << " is already downloaded. Skipping download." << std::endl;
        }
        else {
            Download(driverUrl, tempDir);
            std::cout << "Download and extraction complete for version: " << version << std::endl;
            SaveVersionFile(versionFilePath);
            std::string zipPath;
            std::string FixFilename;
            std::string driverDir;
            zipPath = tempDir + "\\driver.zip";
            driverDir = tempDir + "\\driver";
            extractZip(zipPath, driverDir);
&nbsp;
            copyAndRenameFile(driverDir + (browser == "edge" ? "\\msedgedriver.exe" : "\\chromedriver.exe"), outputPath);
&nbsp;
            FixFilename = browser + "driver_" + std::string(version.begin(), version.end()) + ".zip";
            renameFile(tempDir, "driver.zip", FixFilename);
            deleteDirectory(driverDir);
        }
    }
    catch (const std::exception& ex) {
        std::cerr << "Error: " << ex.what() << std::endl;
        return 1;
    }
&nbsp;
    return 0;</code></pre><div>
<script></yjavascript>


 
 


[[VBA Edge制御 導入]]に戻る。
[[VBA Edge制御 導入]]に戻る。

2024年12月28日 (土) 01:26時点における版

VBA Edge制御 導入に戻る。

概要

 msedgedriver.exeを自動で差し替えるコマンドプロンプトプログラムをC++言語でだらだら長めのコードになりましたが、作るには作りました。クラス化とかしてません。参考にして自分で組んでみて下さい。Chromeの対応はきっちりできていません。Chromeも同じようなやり方だと思うので、Chromeのdriverも答え合わせ的に直してみるといいかもしれない。つうかzlibとlibzipのビルドとかで手間取る。古いVisualStudio17 2022とかでやるとつまづく、最新のVisualStudio17 2022に更新した上でやるとうまく行く。



からダウンロードして解凍して、zlibはフォルダ階層のトップ下のCMakeFile.txtのあるフォルダをVisual Studioで開いて、ビルドのインストールっていうのと(zlibのパス)\out\install\x64-Debug\includeの下のzconf.hを(zlibのパス)の直下にコピーしてから、ビルドのビルドを実行するだけ。これで、zlibd.libとzlibd.dllとincludeディレクトリが生成されます。したらば次はlibzipも同じようにフォルダ階層のトップ下のCMakeFileをVisual Studioで開くんですけど、フォルダを開く前にCMakeFile.txtの中身を以下のように更新します。


cmake_minimum_required(VERSION 3.0.2)
set(ZLIB_ROOT C:/(zlibのパス)/)
set(LIB_INCLUDE_DIR C:/(zlibのパス)/out/install/x64-Debug/include)
set(ZLIB_LIBRARY_DEBUG C:/(zlibのパス)/out/install/x64-Debug/lib/zlibd.lib)
set(ZLIB_LIBRARY_RELEASE C:/(zlibのパス)/out/install/x64-Debug/lib/zlibd.lib)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)


その上でフォルダを開いて、インストールとビルドをするとzip.libとzip.dllとインクルードディレクトリが生成されます。したらば、このzip.dllとzlibd.libを自分で作成するプロジェクトで実行ファイル.exeが生成されるフォルダに保存するのと、インクルードディレクトリに以下の追加します。


  • インクルードディレクトリ
C:\(libzipパス)\out\install\x64-Debug\include;
  • ライブラリディレクトリ
C:\(libzipパス)\out\install\x64-Debug\lib;


そして、以下のようにコードを作成します。


#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
 
#include 
 
#pragma comment(lib, "winhttp.lib")
#pragma comment(lib, "Version.lib")
#pragma comment(lib, "zip.lib")
 
std::string GetVersion(const std::string& path) {
DWORD handle;
DWORD size = GetFileVersionInfoSizeA(path.c_str(), &handle);
if (size == 0) {
throw std::runtime_error("Failed to get version info size.");
}
 
std::vector data(size);
if (!GetFileVersionInfoA(path.c_str(), handle, size, data.data())) {
throw std::runtime_error("Failed to get version info.");
}
 
VS_FIXEDFILEINFO* versionInfo;
UINT len;
if (!VerQueryValueA(data.data(), "\\", (LPVOID*)&versionInfo, &len)) {
throw std::runtime_error("Failed to query version info.");
}
 
DWORD major = (versionInfo->dwFileVersionMS >> 16) & 0xffff;
DWORD minor = versionInfo->dwFileVersionMS & 0xffff;
DWORD build = (versionInfo->dwFileVersionLS >> 16) & 0xffff;
DWORD revision = versionInfo->dwFileVersionLS & 0xffff;
 
return std::to_string(major) + "." +
std::to_string(minor) + "." +
std::to_string(build) + "." +
std::to_string(revision);
}
 
std::string GetHttpResponse(const std::wstring& host, const std::wstring& path) {
HINTERNET session = WinHttpOpen(L"Downloader", WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY, NULL, NULL, 0);
if (!session) {
throw std::runtime_error("Failed to open WinHTTP session.");
}
 
HINTERNET connect = WinHttpConnect(session, host.c_str(), INTERNET_DEFAULT_HTTPS_PORT, 0);
if (!connect) {
WinHttpCloseHandle(session);
throw std::runtime_error("Failed to connect to host.");
}
 
HINTERNET request = WinHttpOpenRequest(connect, L"GET", path.c_str(), NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE);
if (!request) {
WinHttpCloseHandle(connect);
WinHttpCloseHandle(session);
throw std::runtime_error("Failed to open HTTP request.");
}
 
if (!WinHttpSendRequest(request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0)) {
WinHttpCloseHandle(request);
WinHttpCloseHandle(connect);
WinHttpCloseHandle(session);
throw std::runtime_error("Failed to send HTTP request.");
}
 
if (!WinHttpReceiveResponse(request, NULL)) {
WinHttpCloseHandle(request);
WinHttpCloseHandle(connect);
WinHttpCloseHandle(session);
throw std::runtime_error("Failed to receive HTTP response.");
}
 
DWORD size = 0;
WinHttpQueryDataAvailable(request, &size);
 
std::string response(size, '\0');
DWORD downloaded;
WinHttpReadData(request, /*&response[0]*/ response.data(), size, &downloaded);
 
WinHttpCloseHandle(request);
WinHttpCloseHandle(connect);
WinHttpCloseHandle(session);
 
return response;
}
 
void Download(const std::wstring& url, const std::string& extractDir) {
HINTERNET session = WinHttpOpen(L"Downloader", WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY, NULL, NULL, 0);
URL_COMPONENTS components = { 0 };
components.dwStructSize = sizeof(URL_COMPONENTS);
components.dwHostNameLength = -1;
components.dwUrlPathLength = -1;
 
wchar_t host[256];
wchar_t path[1024];
 
components.lpszHostName = host;
components.lpszUrlPath = path;
 
if (!WinHttpCrackUrl(url.c_str(), 0, 0, &components)) {
throw std::runtime_error("Failed to parse URL.");
}
 
HINTERNET connect = WinHttpConnect(session, components.lpszHostName, INTERNET_DEFAULT_HTTPS_PORT, 0);
if (!connect) {
WinHttpCloseHandle(session);
throw std::runtime_error("Failed to connect to host.");
}
 
HINTERNET request = WinHttpOpenRequest(connect, L"GET", components.lpszUrlPath, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE);
if (!request) {
WinHttpCloseHandle(connect);
WinHttpCloseHandle(session);
throw std::runtime_error("Failed to open HTTP request.");
}
 
if (!WinHttpSendRequest(request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0)) {
WinHttpCloseHandle(request);
WinHttpCloseHandle(connect);
WinHttpCloseHandle(session);
throw std::runtime_error("Failed to send HTTP request.");
}
 
if (!WinHttpReceiveResponse(request, NULL)) {
WinHttpCloseHandle(request);
WinHttpCloseHandle(connect);
WinHttpCloseHandle(session);
throw std::runtime_error("Failed to receive HTTP response.");
}
 
DWORD size = 0;
WinHttpQueryDataAvailable(request, &size);
 
std::vector data;
DWORD downloaded = 0;
do {
DWORD size = 0;
WinHttpQueryDataAvailable(request, &size);
if (size == 0) break;
std::vector buffer(size);
DWORD bytesRead = 0;
if (!WinHttpReadData(request, buffer.data(), size, &bytesRead)) {
throw std::runtime_error("Failed to read HTTP response data.");
}
data.insert(data.end(), buffer.begin(), buffer.begin() + bytesRead);
downloaded += bytesRead;
} while (true);
 
std::filesystem::create_directory(extractDir);
std::ofstream out(extractDir + "\\driver.zip", std::ios::binary);
out.write(data.data(), downloaded);
out.close();
 
WinHttpCloseHandle(request);
WinHttpCloseHandle(connect);
WinHttpCloseHandle(session);
}
 
std::string GetVersionFilePath(const std::string& browser, const std::string& version) {
return browser + "_" + version;
}
 
bool IsVersionDownloaded(const std::string& versionFilePath) {
return std::filesystem::exists(versionFilePath);
}
 
void SaveVersionFile(const std::string& versionFilePath) {
std::ofstream file(versionFilePath);
if (file) {
file << "Downloaded";
file.close();
}
}
void extractZip(const std::string& zipPath, const std::string& extractDir) {
int zipError = 0;
 
// ZIPファイルを開く
zip_t* zip = zip_open(zipPath.c_str(), 0, &zipError);
if (!zip) {
std::cerr << "Failed to open ZIP file. Error code: " << zipError << std::endl;
return;
}
 
// エントリ数を取得
zip_int64_t num_entries = zip_get_num_entries(zip, 0);
for (zip_int64_t i = 0; i < num_entries; i++) {
// ファイル名を取得
const char* name = zip_get_name(zip, i, 0);
if (!name) {
std::cerr << "Failed to get entry name for index " << i << std::endl;
continue;
}
 
// ファイル名をstd::stringに変換
std::string entryName(name);
 
// ファイル情報を取得
zip_stat_t stat;
if (zip_stat_index(zip, i, 0, &stat) == -1) {
std::cerr << "Failed to get entry stats for " << entryName << std::endl;
continue;
}
 
// フルパスを作成
std::filesystem::path fullPath = std::filesystem::path(extractDir) / entryName;
 
// フォルダの場合、ディレクトリを作成
if (entryName.back() == '/') { // ZIP形式ではフォルダ名は末尾に'/'が付く
std::filesystem::create_directories(fullPath);
continue;
}
 
// ファイルを開く
zip_file_t* zf = zip_fopen_index(zip, i, 0);
if (!zf) {
std::cerr << "Failed to open file inside ZIP: " << entryName << std::endl;
continue;
}
 
// ファイル内容を読み込む
std::string contents(stat.size, '\0'); // std::stringでメモリ確保
if (zip_fread(zf, &contents[0], stat.size) == -1) {
std::cerr << "Failed to read file: " << entryName << std::endl;
zip_fclose(zf);
continue;
}
 
// 親ディレクトリを作成(必要であれば)
std::filesystem::create_directories(fullPath.parent_path());
 
// ファイルを保存
std::ofstream out(fullPath, std::ios::binary);
if (!out) {
std::cerr << "Failed to write file: " << fullPath << std::endl;
zip_fclose(zf);
continue;
}
out.write(contents.data(), contents.size());
out.close();
 
// ファイルを閉じる
zip_fclose(zf);
}
 
// ZIPファイルを閉じる
zip_close(zip);
}
 
void renameFile(const std::string& dirPath, const std::string& oldName, const std::string& newName) {
// 古いファイルのフルパス
std::filesystem::path oldFilePath = std::filesystem::path(dirPath) / oldName;
 
// 新しいファイルのフルパス
std::filesystem::path newFilePath = std::filesystem::path(dirPath) / newName;
 
try {
// ファイル名を変更
std::filesystem::rename(oldFilePath, newFilePath);
std::cout << "File renamed from " << oldFilePath << " to " << newFilePath << std::endl;
}
catch (const std::filesystem::filesystem_error& e) {
std::cerr << "Error renaming file: " << e.what() << std::endl;
}
}
 
void deleteDirectory(const std::string& dirPath) {
try {
// 指定したディレクトリが存在するか確認
if (std::filesystem::exists(dirPath)) {
// 再帰的に削除
std::filesystem::remove_all(dirPath);
std::cout << "Deleted directory and contents: " << dirPath << std::endl;
}
else {
std::cerr << "Directory does not exist: " << dirPath << std::endl;
}
}
catch (const std::filesystem::filesystem_error& e) {
std::cerr << "Error deleting directory: " << e.what() << std::endl;
}
}
 
void copyAndRenameFile(const std::string& sourcePath, const std::string& destPath) {
try {
// コピー先の親ディレクトリを作成(存在しない場合)
std::filesystem::create_directories(std::filesystem::path(destPath).parent_path());
// ファイルをコピー
std::filesystem::copy_file(sourcePath, destPath, std::filesystem::copy_options::overwrite_existing);
std::cout << "File copied from " << sourcePath << " to " << destPath << std::endl;
}
catch (const std::filesystem::filesystem_error& e) {
std::cerr << "Error copying file: " << e.what() << std::endl;
}
}
 
int main(int argc, char* argv[]) {
 
if (argc < 2 || argv[1] == nullptr) {
std::cerr << "起動引数1のブラウザの種別の指定がありません。edge or chrome" << std::endl;
return 1;
}
 
if (argc < 3 || argv[2] == nullptr) {
std::cerr << "起動引数2のWindowsユーザ名の指定がありません。" << std::endl;
return 1;
}
std::string browser = argv[1];
std::string userId = argv[2];
std::string baseDir = "C:\\Users\\" + userId + "\\AppData\\Local\\SeleniumBasic";
 
std::string version;
std::wstring driverUrl;
std::string tempDir;
std::string outputPath;
 
try {
if (browser == "chrome") {
version = GetVersion("C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe");
std::wstring driverUrl = L"https://googlechromelabs.github.io/chrome-for-testing/LATEST_RELEASE_" + std::wstring(version.begin(), version.end());
tempDir = "chromedriver_temp";
outputPath = baseDir + "\\chromedriver.exe";
//DownloadAndExtract(driverUrl, tempDir, baseDir + "\\chromedriver.exe");
}
else if (browser == "edge") {
version = GetVersion("C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe");
driverUrl = L"https://msedgedriver.azureedge.net/" + std::wstring(version.begin(), version.end()) + L"/edgedriver_win64.zip";
tempDir = "edgedriver_temp";
outputPath = baseDir + "\\edgedriver.exe";
//DownloadAndExtract(driverUrl, tempDir, baseDir + "\\edgedriver.exe", "msedgedriver.exe");
}
else {
std::cerr << "Unsupported browser: edge or chrome" << browser << std::endl;
return 1;
}
         
 
std::string versionFilePath = GetVersionFilePath(browser, version);
 
if (IsVersionDownloaded(versionFilePath)) {
std::cout << "Version " << version << " is already downloaded. Skipping download." << std::endl;
}
else {
Download(driverUrl, tempDir);
std::cout << "Download and extraction complete for version: " << version << std::endl;
SaveVersionFile(versionFilePath);
std::string zipPath;
std::string FixFilename;
std::string driverDir;
zipPath = tempDir + "\\driver.zip";
driverDir = tempDir + "\\driver";
extractZip(zipPath, driverDir);
 
copyAndRenameFile(driverDir + (browser == "edge" ? "\\msedgedriver.exe" : "\\chromedriver.exe"), outputPath);
 
FixFilename = browser + "driver_" + std::string(version.begin(), version.end()) + ".zip";
renameFile(tempDir, "driver.zip", FixFilename);
deleteDirectory(driverDir);
}
}
catch (const std::exception& ex) {
std::cerr << "Error: " << ex.what() << std::endl;
return 1;
}
 
return 0;

 

VBA Edge制御 導入に戻る。