Win32 获取EXE/DLL文件版本信息

news2024/11/25 16:23:24

CFileVersion.h

#pragma once

#include <windows.h>
#include <string>
#include <tchar.h>

#ifdef _UNICODE
using _tstring = std::wstring;
#else
using _tstring = std::string;
#endif

// 版本号辅助类
class CVersionNumber
{
public:

    // 无参构造
    CVersionNumber();

    // 从版本字符串构造
    CVersionNumber(LPCTSTR lpStrVer);

    // 从指定版本号构造
    CVersionNumber(WORD v1, WORD v2, WORD v3, WORD v4);

    // 从版本字符串构造
    CVersionNumber& operator = (LPCTSTR lpStrVer);

    // 比较版本号大小
    int CompareVersion(const CVersionNumber& ref) const;

    //获取版本号字符串
    _tstring GetVersionStr() const;

    // 比较运算重载
    bool operator == (const CVersionNumber& ref);
    bool operator != (const CVersionNumber& ref);
    bool operator < (const CVersionNumber& ref);
    bool operator <= (const CVersionNumber& ref);
    bool operator > (const CVersionNumber& ref);
    bool operator >= (const CVersionNumber& ref);

private:

    WORD m_nVer[4];         //版本号
};

typedef struct _FILE_VERSION_INFO
{
    _tstring strComments;                       //文件注释
    _tstring strInternalName;                   //内部名称
    _tstring strProductName;                    //产品名称
    _tstring strCompanyName;                    //公司名称
    _tstring strLegalCopyright;                 //法律版权
    _tstring strProductVersion;                 //产品版本
    _tstring strFileDescription;                //文件描述
    _tstring strLegalTrademarks;                //合法商标
    _tstring strPrivateBuild;                   //私有构建
    _tstring strFileVersion;                    //文件版本
    _tstring strOriginalFilename;               //原始文件名
    _tstring strSpecialBuild;                   //特殊构建
    _tstring strFileVersionEx;                  //文件版本(从 VS_FIXEDFILEINFO中 获取)
    _tstring strProductVersionEx;               //产品版本(从 VS_FIXEDFILEINFO中 获取)

    CVersionNumber FileVerNumber;               //文件版本号
    CVersionNumber ProductVerNumber;            //产品版本号
}FILE_VERSION_INFO;

class CFileVersion
{
    struct LANGANDCODEPAGE {
        WORD wLanguage;
        WORD wCodePage;

        LANGANDCODEPAGE()
            :
            wLanguage(0),
            wCodePage(0)
        {

        }
    };

public:
    CFileVersion();
    ~CFileVersion();

    CFileVersion operator = (const CFileVersion& r) = delete;
    static FILE_VERSION_INFO GetVersionInfo(const _tstring& strFile);
    static FILE_VERSION_INFO GetCurrentModuleVersionInfo();

public:
    bool LoadFile(const _tstring& strFile);             //加载文件信息
    void Close();

    FILE_VERSION_INFO GetVersionInfo() const;           //整个版本信息

    _tstring GetComments() const;                       //文件注释
    _tstring GetInternalName() const;                   //内部名称
    _tstring GetProductName() const;                    //产品名称
    _tstring GetCompanyName() const;                    //公司名称
    _tstring GetLegalCopyright() const;                 //法律版权
    _tstring GetProductVersion() const;                 //产品版本
    _tstring GetFileDescription() const;                //文件描述
    _tstring GetLegalTrademarks() const;                //合法商标
    _tstring GetPrivateBuild() const;                   //私有版本
    _tstring GetFileVersion() const;                    //文件版本
    _tstring GetOriginalFilename() const;               //原始文件名
    _tstring GetSpecialBuild() const;                   //特别版本
    _tstring GetFileVersionEx() const;                  //文件版本(从 VS_FIXEDFILEINFO中 获取)
    _tstring GetProductVersionEx() const;               //产品版本(从 VS_FIXEDFILEINFO中 获取)
    VS_FIXEDFILEINFO GetFixedFileInfo() const;          //文件的版本信息

private:
    _tstring _QueryInfo(const _tstring& strName) const;
    void _LoadAllInfo();

    LPVOID m_lpVerData;                                 //文件信息数据指针
    LANGANDCODEPAGE m_Translate;                        //语言代码页
    VS_FIXEDFILEINFO m_VsFixedFileInfo;                 //文件的版本信息
    FILE_VERSION_INFO m_VersionInfo;                    //版本信息
};

CFileVersion.cpp

#include "CFileVersion.h"
#include <tchar.h>
#include <strsafe.h>

#pragma comment(lib, "Version.lib")

#pragma pack(push)
#pragma pack(1)
// 包含文件的版本信息。 此信息与语言和代码页无关
// https://learn.microsoft.com/zh-cn/windows/win32/menurc/vs-versioninfo
typedef struct {
    WORD             wLength;       // VS_VERSIONINFO 结构的长度(以字节为单位),此长度不包括在 32 位边界上对齐任何后续版本资源数据的填充
    WORD             wValueLength;  // Value 成员的长度(以字节为单位)
    WORD             wType;         // 版本资源中的数据类型, 1: 资源包含文本数据 0: 版本资源包含二进制数据
    WCHAR            szKey[15];     // Unicode 字符串 L“VS_VERSION_INFO”
    WORD             Padding1;      // 在 32 位边界上对齐 Children 成员所需的任意或零个 WORD
    //VS_FIXEDFILEINFO Value
    //WORD             Padding2
    //WORD             Children
} VS_VERSIONINFO, * PVS_VERSIONINFO;

#pragma pack(pop)

CVersionNumber::CVersionNumber()
    :m_nVer{ 0 }
{
};

CVersionNumber::CVersionNumber(LPCTSTR lpStrVer)
    :
    m_nVer{ 0 }
{
    _stscanf_s(lpStrVer, _T("%hd.%hd.%hd.%hd"), &m_nVer[0], &m_nVer[1], &m_nVer[2], &m_nVer[3]);
}

CVersionNumber::CVersionNumber(WORD v1, WORD v2, WORD v3, WORD v4)
    :m_nVer{ v1, v2, v3, v4 }
{
}

CVersionNumber& CVersionNumber::operator = (LPCTSTR lpStrVer)
{
    _stscanf_s(lpStrVer, _T("%hd.%hd.%hd.%hd"), &m_nVer[0], &m_nVer[1], &m_nVer[2], &m_nVer[3]);
    return *this;
}

int CVersionNumber::CompareVersion(const CVersionNumber& ref) const
{
    for (int i = 0; i < _countof(m_nVer); i++)
    {
        if (m_nVer[i] != ref.m_nVer[i])
        {
            return (m_nVer[i] > ref.m_nVer[i] ? 1 : -1);
        }
    }

    return 0;
}

_tstring CVersionNumber::GetVersionStr() const
{
    TCHAR szBuf[MAX_PATH] = { 0 };
    (void)::StringCchPrintf(szBuf, _countof(szBuf), _T("%hd.%hd.%hd.%hd"),
        m_nVer[0],
        m_nVer[1],
        m_nVer[2],
        m_nVer[3]
    );

    return szBuf;
}

bool CVersionNumber::operator == (const CVersionNumber& ref)
{
    return CompareVersion(ref) == 0;
}

bool CVersionNumber::operator != (const CVersionNumber& ref)
{
    return CompareVersion(ref) != 0;
}

bool CVersionNumber::operator < (const CVersionNumber& ref)
{
    return CompareVersion(ref) < 0;
}

bool CVersionNumber::operator <= (const CVersionNumber& ref)
{
    return CompareVersion(ref) <= 0;
}

bool CVersionNumber::operator > (const CVersionNumber& ref)
{
    return CompareVersion(ref) > 0;
}

bool CVersionNumber::operator >= (const CVersionNumber& ref)
{
    return CompareVersion(ref) >= 0;
}

CFileVersion::CFileVersion()
    :
    m_lpVerData(NULL)
{
    memset(&m_VsFixedFileInfo, 0, sizeof(m_VsFixedFileInfo));
}

CFileVersion::~CFileVersion()
{
    this->Close();
}

FILE_VERSION_INFO CFileVersion::GetVersionInfo(const _tstring& strFile)
{
    CFileVersion verInfo;
    verInfo.LoadFile(strFile);
    return verInfo.GetVersionInfo();
}

FILE_VERSION_INFO CFileVersion::GetCurrentModuleVersionInfo()
{
    TCHAR szBuf[MAX_PATH] = { 0 };
    ::GetModuleFileName(NULL, szBuf, _countof(szBuf));
    return GetVersionInfo(szBuf);
}

bool CFileVersion::LoadFile(const _tstring& strFile)
{
    PVOID pFsRedirectionOldValue = NULL;
    bool isDisableWow64Fs = false;
    bool isSuccess = false;
    UINT cbTranslate = 0;
    DWORD dwVerSize;

    if (strFile.empty())
    {
        return false;
    }

    this->Close();

    m_VersionInfo = FILE_VERSION_INFO();

    // 禁用文件重定向
    isDisableWow64Fs = ::Wow64DisableWow64FsRedirection(&pFsRedirectionOldValue);

    do
    {
        // 获取版本信息数据大小
        dwVerSize = ::GetFileVersionInfoSize(strFile.c_str(), 0);
        if (0 == dwVerSize)
        {
            break;
        }

        // 分配版本信息缓冲
        m_lpVerData = ::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, dwVerSize);
        if (!m_lpVerData)
        {
            break;
        }

        // 获取版本信息
        if (!::GetFileVersionInfo(strFile.c_str(), 0, dwVerSize, m_lpVerData))
        {
            break;
        }

        // 获取语言代码
        LANGANDCODEPAGE* lpTranslate = NULL;
        if (!::VerQueryValue(m_lpVerData, _T("\\VarFileInfo\\Translation"), (LPVOID*)&lpTranslate, &cbTranslate))
        {
            break;
        }

        m_Translate = *lpTranslate;

        // 获取 VS_FIXEDFILEINFO 信息
        PVS_VERSIONINFO lpVersion = (PVS_VERSIONINFO)m_lpVerData;
        if (0 != lpVersion->wValueLength)
        {
            VS_FIXEDFILEINFO* pFixedFileInfo = (VS_FIXEDFILEINFO*)((LPBYTE)lpVersion + sizeof(VS_VERSIONINFO));

            DWORD dwAlign = 4;
            DWORD_PTR dwPadding = ((DWORD_PTR)pFixedFileInfo % dwAlign);
            if (0 != dwPadding)
            {
                pFixedFileInfo = (VS_FIXEDFILEINFO*)((LPBYTE)pFixedFileInfo + (dwAlign - dwPadding));
            }

            m_VsFixedFileInfo = *pFixedFileInfo;
        }

        // 加载所有信息
        _LoadAllInfo();

        isSuccess = true;

    } while (false);

    // 不成功则关闭
    if (!isSuccess)
    {
        this->Close();
    }

    // 恢复文件重定向
    if (isDisableWow64Fs)
    {
        ::Wow64RevertWow64FsRedirection(pFsRedirectionOldValue);
    }

    return isSuccess;
}

void CFileVersion::Close()
{
    if (m_lpVerData)
    {
        HeapFree(::GetProcessHeap(), 0, m_lpVerData);
        m_lpVerData = NULL;
    }
}

void CFileVersion::_LoadAllInfo()
{
    m_VersionInfo.strComments = _QueryInfo(_T("Comments"));
    m_VersionInfo.strInternalName = _QueryInfo(_T("InternalName"));
    m_VersionInfo.strProductName = _QueryInfo(_T("ProductName"));
    m_VersionInfo.strCompanyName = _QueryInfo(_T("CompanyName"));
    m_VersionInfo.strLegalCopyright = _QueryInfo(_T("LegalCopyright"));
    m_VersionInfo.strProductVersion = _QueryInfo(_T("ProductVersion"));
    m_VersionInfo.strFileDescription = _QueryInfo(_T("FileDescription"));
    m_VersionInfo.strLegalTrademarks = _QueryInfo(_T("LegalTrademarks"));
    m_VersionInfo.strPrivateBuild = _QueryInfo(_T("PrivateBuild"));
    m_VersionInfo.strFileVersion = _QueryInfo(_T("FileVersion"));
    m_VersionInfo.strOriginalFilename = _QueryInfo(_T("OriginalFilename"));
    m_VersionInfo.strSpecialBuild = _QueryInfo(_T("SpecialBuild"));
    m_VersionInfo.strFileVersionEx = GetFileVersionEx();
    m_VersionInfo.strProductVersionEx = GetProductVersionEx();

    m_VersionInfo.FileVerNumber = m_VersionInfo.strFileVersionEx.c_str();
    m_VersionInfo.ProductVerNumber = m_VersionInfo.strProductVersionEx.c_str();

}

_tstring CFileVersion::_QueryInfo(const _tstring& strName) const
{
    _tstring strRes;
    TCHAR strQuery[MAX_PATH] = { 0 };
    LPCTSTR lpQueryRes = NULL;
    UINT uQueryCchSize;

    do
    {
        if (!m_lpVerData)
        {
            break;
        }

        (void)::StringCchPrintf(strQuery, _countof(strQuery),
            _T("\\StringFileInfo\\%04x%04x\\%s"),
            m_Translate.wLanguage,
            m_Translate.wCodePage,
            strName.c_str());

        if (!::VerQueryValue(m_lpVerData, strQuery, (LPVOID*)&lpQueryRes, &uQueryCchSize))
        {
            break;
        }

        strRes = lpQueryRes;

    } while (false);

    return strRes;
}

_tstring CFileVersion::GetComments() const
{
    return m_VersionInfo.strComments;
}

_tstring CFileVersion::GetInternalName() const
{
    return m_VersionInfo.strInternalName;
}

_tstring CFileVersion::GetProductName() const
{
    return m_VersionInfo.strProductName;
}

_tstring CFileVersion::GetCompanyName() const
{
    return m_VersionInfo.strCompanyName;
}

_tstring CFileVersion::GetLegalCopyright() const
{
    return m_VersionInfo.strLegalCopyright;
}

_tstring CFileVersion::GetProductVersion() const
{
    return m_VersionInfo.strProductVersion;
}

_tstring CFileVersion::GetFileDescription() const
{
    return m_VersionInfo.strFileDescription;
}

_tstring CFileVersion::GetLegalTrademarks() const
{
    return m_VersionInfo.strLegalTrademarks;
}

_tstring CFileVersion::GetPrivateBuild() const
{
    return m_VersionInfo.strPrivateBuild;
}

_tstring CFileVersion::GetFileVersion() const
{
    return m_VersionInfo.strFileVersion;
}

_tstring CFileVersion::GetOriginalFilename() const
{
    return m_VersionInfo.strOriginalFilename;
}

_tstring CFileVersion::GetSpecialBuild() const
{
    return m_VersionInfo.strSpecialBuild;
}

_tstring CFileVersion::GetFileVersionEx() const
{
    TCHAR szBuf[MAX_PATH] = { 0 };
    (void)::StringCchPrintf(szBuf, _countof(szBuf), _T("%hd.%hd.%hd.%hd"),
        HIWORD(m_VsFixedFileInfo.dwFileVersionMS),
        LOWORD(m_VsFixedFileInfo.dwFileVersionMS),
        HIWORD(m_VsFixedFileInfo.dwFileVersionLS),
        LOWORD(m_VsFixedFileInfo.dwFileVersionLS)
    );

    return szBuf;
}

_tstring CFileVersion::GetProductVersionEx() const
{
    TCHAR szBuf[MAX_PATH] = { 0 };
    (void)::StringCchPrintf(szBuf, _countof(szBuf), _T("%hd.%hd.%hd.%hd"),
        HIWORD(m_VsFixedFileInfo.dwProductVersionMS),
        LOWORD(m_VsFixedFileInfo.dwProductVersionMS),
        HIWORD(m_VsFixedFileInfo.dwProductVersionLS),
        LOWORD(m_VsFixedFileInfo.dwProductVersionLS)
    );

    return szBuf;
}

VS_FIXEDFILEINFO CFileVersion::GetFixedFileInfo() const
{
    return m_VsFixedFileInfo;
}

FILE_VERSION_INFO CFileVersion::GetVersionInfo() const
{
    return m_VersionInfo;
}

main.cpp

#include <locale.h>
#include "Win32Utils/CFileVersion.h"

int _tmain(int argc, LPCTSTR argv[])
{
    setlocale(LC_ALL, "");
    FILE_VERSION_INFO info = CFileVersion::GetCurrentModuleVersionInfo();
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1463354.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

uniapp实现全局悬浮框

uniapp实现全局悬浮框(按钮,页面,图片自行设置) 可拖动 话不多说直接上干货 1,在components新建组件(省去了每个页面都要引用组件的麻烦) 2,实现代码 <template><view class"call-plate" :style"top: top px;left: left px;" touchmove&quo…

探索Redis是否为单线程的奥秘(文末送书)

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;数据结构、网络奇遇记 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 &#x1f4cb;前言一. Redis中的多线程二. I/O多线程三. Redis中的多进程四. 结论五. 书籍推荐5.1 书…

OpenLayers水平镜像和垂直镜像

目录 1.前言2.概念介绍2.1 旋转2.2 水平镜像2.3 垂直镜像 3.要素的镜像3.1 镜像轴始终是水平的或者垂直的3.2 镜像轴是任意角度 4.图片的镜像5.总结 1.前言 最近项目中用到了要素和图片的水平镜像和垂直镜像功能。这些功能说难不难&#xff0c;说简单也不简单&#xff0c;就是稍…

【SQL注入】靶场SQLI DUMB SERIES-24通过二次注入重置用户密码

先使用已知信息admin/admin登录进去查下题&#xff0c;发现可以修改密码 猜测可能存在的SQL语句&#xff1a;UPDATE user SET password新密码 WHERE user用户名 and password旧密码 假设我们知道有个admin用户&#xff0c;但是不知道其密码&#xff0c;如何可以将其密码重置&…

[AIGC] 使用Curl进行网络请求的常见用法

使用Curl进行网络请求的常见用法 Curl是一个无比强大的工具&#xff0c;它可以用来获取和发送数据&#xff0c;支持众多的协议&#xff0c;包括HTTP、HTTPS、FTP、FTPS、SFTP和更多。它还支持HTTP POST&#xff0c;HTTP PUT&#xff0c;HTTPS证书&#xff0c;HTTP基础验证等。…

【2024软件测试面试必会技能】Postman(1): postman的介绍和安装

Postman的介绍 Postman 是一款谷歌开发的接口测试工具,使API的调试与测试更加便捷。 它提供功能强大的 Web API & HTTP 请求调试。它能够发送任何类型的HTTP 请求 (GET, HEAD, POST, PUT..)&#xff0c;附带任何数量的参数 headers。 postman是一款支持http协议的接口调试…

流动人员人事档案主要有哪些作用

流动人员人事档案是指记录企事业单位与个人之间的雇佣关系的文件。在企事业单位中&#xff0c;流动人员是指临时聘用的员工、实习生、临时工等&#xff0c;他们的雇佣关系相对不稳定&#xff0c;因此需要建立相应的人事档案来管理和记录他们的基本信息、工作经历、劳动合同等重…

unity学习(34)——角色选取界面(跨场景坑多)

先把SelectMenu中的camera的audio listener去掉。 现在还是平面&#xff0c;直接在camera下面添加两个panel即可&#xff0c;应该是用不到canvas了&#xff0c;都是2D的UI。 加完以后问题来了&#xff0c;角色选择界面的按钮跑到主界面上边了&#xff0c;而且现在账号密码都输…

机器人内部传感器阅读笔记及心得-位置传感器-电位器式位置传感器

位置传感器 位置感觉是机器人最基本的感觉要求&#xff0c;可以通过多种传感器来实现。位置传感器包括位置和角度检测传感器。常用的机器人位置传感器有电位器式、光电式、电感式、电容式、霍尔元件式、磁栅式及机械式位置传感器等。机器人各关节和连杆的运动定位精度要求、重…

C语言自定义类型:结构体的使用及其内存对齐【超详细建议点赞收藏】

目录 1. 结构体类型的声明1.1 结构的声明1.2 结构体变量的创建和初始化1.3 结构的特殊声明---匿名结构体1.4 结构的自引用 2.结构体内存对齐&#xff08;重点&#xff01;&#xff01;&#xff09;2.1 对齐规则2.2 例题讲解2.3 为什么存在内存对齐&#xff1f;2.4 修改默认对齐…

vue3前端excel导出;组件表格,自定义表格导出;Vue3 + xlsx + xlsx-style

当画面有自定义的表格或者样式过于复杂的表格时&#xff0c;导出功能可以由前端实现 1. 使用的插件 &#xff1a; sheet.js-xlsx 文档地址&#xff1a;https://docs.sheetjs.com/ 中文地址&#xff1a;https://geekdaxue.co/read/SheetJS-docs-zh/README.md xlsx-style&#…

⭐北邮复试刷题LCR 052. 递增顺序搜索树__DFS (力扣119经典题变种挑战)

LCR 052. 递增顺序搜索树 给你一棵二叉搜索树&#xff0c;请 按中序遍历 将其重新排列为一棵递增顺序搜索树&#xff0c;使树中最左边的节点成为树的根节点&#xff0c;并且每个节点没有左子节点&#xff0c;只有一个右子节点。 示例 1&#xff1a; 输入&#xff1a;root [5,…

跨境电商消息多发脚本制作需要用到的代码!

在跨境电商的运营中&#xff0c;为了更有效地推广产品、提升品牌知名度并增强与消费者的互动&#xff0c;消息群发成为了一个重要的营销手段。 为了实现这一目的&#xff0c;许多跨境电商团队会选择制作消息多发脚本&#xff0c;通过自动化发送消息来提高效率和覆盖面&#xf…

算法沉淀——穷举、暴搜、深搜、回溯、剪枝综合练习三(leetcode真题剖析)

算法沉淀——穷举、暴搜、深搜、回溯、剪枝综合练习三 01.字母大小写全排列02.优美的排列03.N 皇后04.有效的数独 01.字母大小写全排列 题目链接&#xff1a;https://leetcode.cn/problems/letter-case-permutation/ 给定一个字符串 s &#xff0c;通过将字符串 s 中的每个字…

获取discord上自己创建的服务器的服务器ID、频道ID以及discord的登录token(用于第三方登录)

在服务器图标上右键点击-》复制服务器ID 在频道上右键点击-》复制频道ID F12->手机模式-》application-》local storage-》填写过滤条件【token】 我开发的chatgpt网站&#xff1a; https://chat.xutongbao.top

铌酸锂芯片与精密划片机:科技突破引领半导体制造新潮流

在当今快速发展的半导体行业中&#xff0c;一种结合了铌酸锂芯片与精密划片机的创新技术正在崭露头角。这种技术不仅引领着半导体制造领域的进步&#xff0c;更为其他产业带来了前所未有的变革。 铌酸锂芯片是一种新型的微电子芯片&#xff0c;它使用铌酸锂作为基底材料&#x…

dp入门(模板题)

解法一&#xff1a; 双指针&#xff0c;没必要开数组直接边输边算&#xff0c;max至少要2个数&#xff0c;补一个数时的特判 #include <iostream> #include <vector> #include <algorithm> using namespace std; #define endl \nint main() {ios::sync_wit…

ChatGPT调教指南 | 咒语指南 | Prompts提示词教程(二)

在我们开始探索人工智能的世界时&#xff0c;了解如何与之有效沉浸交流是至关重要的。想象一下&#xff0c;你手中有一把钥匙&#xff0c;可以解锁与OpenAI的GPT模型沟通的无限可能。这把钥匙就是——正确的提示词&#xff08;prompts&#xff09;。无论你是AI领域的新手&#…

SaaS智慧校园管理平台全套源码,支持二次开发,项目使用

什么是电子班牌系统&#xff1f; 电子班牌用来显示班级信息&#xff0c;班级活动信息以及学校的通知信息。信息内容为文字、图片、视频、FLASH等&#xff0c;为学生和老师提供新颖的师生交流及校园服务平台。融合了多媒体信息发布、家校互通、物联控制、教务管理、日常办公等一…

求人脸底库匹配用时统计记录

1、 注意事项 1、预热 2、torch 异步 import torch import time torch.cuda.synchronize()device torch.device(cuda:2) data_type torch.float32t1 time.time() a torch.rand((40000000,512),dtypedata_type,devicedevice) b torch.rand((512,1),dtypedata_type,device…