[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[问题求助] PowerShell怎么调用api[已解决]

本帖最后由 czjt1234 于 2024-4-12 20:25 编辑

DosDateTimeToFileTime
https://learn.microsoft.com/zh-cn/windows/win32/api/winbase/nf-winbase-dosdatetimetofiletime

FileTimeToSystemTime
https://learn.microsoft.com/zh-cn/windows/win32/api/timezoneapi/nf-timezoneapi-filetimetosystemtime

我想调用这两个api处理dos格式的时间,请问应该怎么写

QQ 20147578

dos格式时间怎么得到的呢,什么格式

TOP

本帖最后由 czjt1234 于 2024-4-12 19:35 编辑

回复 2# went


是一个64位无符号整数
比如 0x5C8A688A

纠正:32位

QQ 20147578

TOP

https://learn.microsoft.com/zh-c ... sdatetimetofiletime
根据这里按二进制逐位分析,可以得到年月日时分秒,但一来麻烦,二来秒的处理结果有问题

QQ 20147578

TOP

回复 3# czjt1234


    64位数,怎么得出MSDN里描述的wFatDate和wFatTime? API里面需要这两个参数

TOP

给出一个反向转换的示例
使用API,当前时间转MS-DOS时间
  1. cls
  2. $code=@'
  3.     using System;
  4.     using System.Runtime.InteropServices;
  5.     public static class WinApi{
  6.         public struct FILETIME {
  7.             public uint dwLowDateTime;
  8.             public uint dwHighDateTime;
  9.         };
  10.         public struct SYSTEMTIME {
  11.             public short wYear;
  12.             public short wMonth;
  13.             public short wDayOfWeek;
  14.             public short wDay;
  15.             public short wHour;
  16.             public short wMinute;
  17.             public short wSecond;
  18.             public short wMilliseconds;
  19.         };
  20.         [DllImport("kernel32.dll")]
  21.         public static extern bool DosDateTimeToFileTime(short wFatDate, short wFatTime, ref FILETIME lpFileTime);
  22.         [DllImport("kernel32.dll")]
  23.         public static extern bool FileTimeToDosDateTime(ref FILETIME lpFileTime, ref short wFatDate, ref short wFatTime);
  24.         [DllImport("kernel32.dll")]
  25.         public static extern bool FileTimeToSystemTime(ref FILETIME lpFileTime,ref SYSTEMTIME lpSystemTime);
  26.         [DllImport("kernel32.dll")]
  27.         public static extern bool SystemTimeToFileTime(ref SYSTEMTIME lpSystemTime, ref FILETIME lpFileTime);
  28.         [DllImport("kernel32.dll")]
  29.         public static extern void GetLocalTime(ref SYSTEMTIME lpSystemTime);
  30.     }
  31. '@
  32. Add-Type -TypeDefinition $code
  33. $st_file_time = New-Object 'WinApi+FILETIME'
  34. $st_system_time = New-Object 'WinApi+SYSTEMTIME'
  35. $wFatDate = New-Object 'uint16'
  36. $wFatTime = New-Object 'uint16'
  37. [WinApi]::GetLocalTime([ref]$st_system_time)
  38. [WinApi]::SystemTimeToFileTime([ref]$st_system_time,[ref]$st_file_time)
  39. [WinApi]::FileTimeToDosDateTime([ref]$st_file_time,[ref]$wFatDate,[ref]$wFatTime)
  40. '当前时间 {0:d4}/{1:d2}/{2:d2} {3:d2}:{4:d2}:{5:d2}' -f $st_system_time.wYear,$st_system_time.wMonth,$st_system_time.wDay,$st_system_time.wHour,$st_system_time.wMinute,$st_system_time.wSecond
  41. 'MS-DOS wFatDate:{0:X4} wFatTime:{1:X4}' -f $wFatDate,$wFatTime
复制代码

TOP

这个自己不能转吗

TOP

.net支持的语言(如C#)的平台调用
或者
基于反射的动态平台调用

不管那种都挺麻烦的(尤其是后者)

不如convert成字符串 , 然后截取手动解析

TOP

如果32位数0x5C8A688A高16位是wFatDate,低16位是wFatTime,使用以下代码转换
  1. $st_file_time = New-Object 'WinApi+FILETIME'
  2. $st_system_time = New-Object 'WinApi+SYSTEMTIME'
  3. $ms_dos_time = 0x5C8A688A
  4. $wFatDate = $ms_dos_time -shr 16
  5. $wFatTime = $ms_dos_time -band 0xffff
  6. [WinApi]::DosDateTimeToFileTime($wFatDate,$wFatTime,[ref]$st_file_time)
  7. [WinApi]::FileTimeToSystemTime([ref]$st_file_time,[ref]$st_system_time)
  8. 'MS-DOS wFatDate:{0:X4} wFatTime:{1:X4}' -f $wFatDate,$wFatTime
  9. '系统时间 {0:d4}/{1:d2}/{2:d2} {3:d2}:{4:d2}:{5:d2}' -f $st_system_time.wYear,$st_system_time.wMonth,$st_system_time.wDay,$st_system_time.wHour,$st_system_time.wMinute,$st_system_time.wSecond
复制代码

TOP

直接转换
  1. cls
  2. $ms_dos_time = 0x5C8A688A
  3. $wFatDate = $ms_dos_time -shr 16
  4. $wFatTime = $ms_dos_time -band 0xffff
  5. $day = $wFatDate -band 0x1f
  6. $month = ($wFatDate -shr 5) -band 0x0f
  7. $year = (($wFatDate -shr 9) -band 0x7f)+1980
  8. $second = ($wFatTime -band 0x1f)*2
  9. $minute = ($wFatTime -shr 5) -band 0x3f
  10. $hour = ($wFatTime -shr 11) -band 0x1f
  11. 'MS-DOS wFatDate:{0:X4} wFatTime:{1:X4}' -f $wFatDate,$wFatTime
  12. '系统时间 {0:d4}/{1:d2}/{2:d2} {3:d2}:{4:d2}:{5:d2}' -f $year,$month,$day,$hour,$minute,$second
复制代码

TOP

回复 7# terse


可以转的,年月日时分都没问题
但是秒要除以2
我就纳闷4秒和5秒怎么区分,还是就不能区分
所以想用API对比一下计算结果

QQ 20147578

TOP

本帖最后由 czjt1234 于 2024-4-12 19:49 编辑

回复 9# went

用6楼的换算
当前时间 2024/04/12 19:39:57
MS-DOS wFatDate:588C wFatTime:9CFD

但是用9楼的计算0x588C9CFD报错
无法将“DosDateTimeToFileTime”的参数“wFatTime”(其值为“40189”)转换为类型“System.Int16”:“无法将值“40189”转换为
类型“System.Int16”。错误:“值对于 Int16 太大或太小。””
所在位置 行:44 字符: 1
+ [WinApi]:osDateTimeToFileTime($wFatDate,$wFatTime,[ref]$st_file_tim ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: ( [], MethodException
    + FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument

QQ 20147578

TOP

回复 10# went

这个代码可以运行,不过我的纠结是秒的准确数,因为这样没有单数的秒了

还有小细节,这个时间是UTC时间,转换为系统时间要+8小时

QQ 20147578

TOP

本帖最后由 went 于 2024-4-12 20:09 编辑

回复 13# czjt1234


    上面报错需要把函数声明short改为ushort
api转换的时间也是把秒缩放的,2个相近的秒时间会生成同个ms-dos时间

TOP

回复 14# went


    非常感谢

QQ 20147578

TOP

返回列表