标题: [问题求助] [已解决]PowerShell搜索佳能EOS M2微单相机文件并复制到本地硬盘 [打印本页]
作者: ygqiang 时间: 2016-3-12 07:54 标题: [已解决]PowerShell搜索佳能EOS M2微单相机文件并复制到本地硬盘
佳能EOS M2微单相机,usb数据线连接win7系统。powershell代码问题请教。
powershell代码功能是:搜索相机里面的照片、视频文件,并复制到本地d盘下的日期文件夹下(比如2016-03)。
佳能微单相机,用usb数据线连上win7 64系统,运行powershell代码,发现的规律是:
1、如果先通过鼠标手动点开相机的照片目录。
第1次运行代码,代码就能复制相机里的全部照片/视频到本地硬盘了。
2、如果不通过鼠标手动点开相机的照片目录。要反复运行2-4次代码,代码才能复制全部照片/视频到本地硬盘。
遇到的问题是:相机与win7 64系统usb数据线连接,
1、第1次运行代码,只复制了10张照片。
手动删除图片目录d:\2016-03(代码在d盘新建的)
2、第2次运行代码,只复制了15张照片。
手动删除图片目录d:\2016-03
3、第3次运行代码,才复制了全部照片21张。
然后断开usb连接,重新连接usb数据线。如果用鼠标手动点击开相机里的照片/视频目录。
1、第1次运行代码,复制了全部照片21张。
手动删除图片目录d:\2016-03
2、第2次运行代码,复制了全部照片21张。
作者: ygqiang 时间: 2016-3-12 07:59
相机usb数据线连接win7系统,截图。。
作者: ygqiang 时间: 2016-3-12 08:01
powershell代码如下。如何修改呢?多谢- #
- # 获取 Shell.Application 代理
- #
- function Get-ShellProxy
- {
- if( -not $global:ShellProxy) {
- $global:ShellProxy = new-object -com Shell.Application
- }
- $global:ShellProxy
- }
- #
- # 查看 Shell 项
- #
- function Get-ShellItem
- {
- param($Path=17)
- $shell=Get-ShellProxy
- # 默认的 NameSpace()方法只支持目录,不支持文件
- # 为了增强兼容性和保持一致性,如果传入一个文件路径,可以尝试通过文件路径获取目录,然后再从目录的子项中获取Shell项
- trap [System.Management.Automation.MethodInvocationException]
- {
- $Path = $Path.ToString()
- $dir = $Path.Substring( 0 ,$Path.LastIndexOf('\') )
- return $shell.NameSpace($dir).items() |
- where { (-not $_.IsFolder ) -and $_.path -eq $Path} |
- select -First 1
- continue
- }
- $shell.NameSpace($Path).self
- }
- #
- # 查看 Shell 子项,支持递归和过滤
- #
- function Get-ChildShellItem
- {
- param(
- $Path=17,
- [switch]$Recurse,
- $Filter=$null)
- #内部过滤器
- Filter myFilter
- {
- if($Filter){
- $_ | where { $_.Name -match $Filter }
- }
- else{
- $_
- }
- }
- $shellItem = Get-ShellItem $Path
- $shellItem | myFilter
- # 如果是目录
- if( $shellItem.IsFolder ){
- # 如果指定递归
- if($Recurse) {
- $shellItem | myFilter
- $stack=New-Object System.Collections.Stack
- # 当前目录压入堆栈
- $stack.Push($shellItem)
- while($stack.Count -gt 0)
- {
- # 访问栈顶元素
- $top = $stack.Pop()
- $top | myFilter
- # 访问栈顶元素的子元素
- $top.GetFolder.items() | foreach {
- if( $_.IsFolder )
- { $stack.Push($_) }
- else { $_ | myFilter }
- }
- }
- }
- else{
- $shellItem.GetFolder.items() | myFilter }
- }
- }
- #
- # 复制Shell项
- #
- function Copy-ShellItem
- {
- param($Path,$Destination)
- $shell=Get-ShellProxy
- $shell.NameSpace($Destination).Copyhere($Path,4)
- }
- #
- # 删除Shell项
- #
- function Remove-ShellItem
- {
- param($Path)
- $ShellItem = Get-ShellItem $Path
- $ShellItem.InvokeVerb('delete')
- }
- #
- # 移动Shell项
- #
- function Move-ShellItem
- {
- param($Path,$Destination)
- $shell=Get-ShellProxy
- $shell.NameSpace($Destination).MoveHere($Path,16)
- }
- # 文件存放的地址
- $des = 'd:\'
- # 匹配相机的关键字,比如:canon,nokia,Windows Phone,meizu,Smartisan,ZUK Z1
- $keywords = 'canon','meizu','Windows Phone','nokia','Smartisan','ZUK Z1'
- foreach ($keyword in $keywords)
- {
- $phones = Get-ChildShellItem | where { $_.name -like "*$keyword*" }
- foreach ($phone in $phones)
- {
- if($phone -eq $null)
- {
- break
- }
- Get-ChildShellItem -Path "$($phone.Path)" -Recurse -Filter '((.jpg)|(.crw)|(.cr2)|(.avi)|(.mov)|(.mp4))$' | foreach {
- #获取照片创建日期
- $datestr = $_.Parent.GetDetailsOf($_,3)
- $datestr=(get-date).tostring("yyyy-MM")
- #新建日期文件夹
- $dir = Join-Path $des $datestr
- if( -not (Test-Path $dir) ) {
- mkdir $dir
- }
- # 如果文件存在,先删掉
- $file="{0}\{1}" -f $dir,$_.name
- if( test-path $file) { remove-item $file }
- # 复制文件
- Copy-ShellItem -Path $_ -Destination $dir
- # 移动文件
- # move-ShellItem -Path $_ -Destination $dir
- }
- }
- }
- exit
- $des = [environment]::GetFolderPath([System.Environment+SpecialFolder]::MyPictures)
复制代码
作者: 523066680 时间: 2016-3-12 09:06
这…… 你有LOFTER账号吗,交流
作者: ivor 时间: 2016-3-12 11:06
回复 3# ygqiang
应该不是代码的问题,可能是系统读取相机图片错误
作者: ygqiang 时间: 2016-3-12 12:48
本帖最后由 ygqiang 于 2016-3-12 12:53 编辑
回复 5# ivor
应该不是。
为啥多运行几次,就会全部复制出来呢?
有人说:
先将相机里面的照片/视频列表出来,先ls一下相机卡目录,
再拷贝,就可以了。
作者: ivor 时间: 2016-3-12 12:50
回复 6# ygqiang
先调试能否获取到完整的全部文件列表
作者: ygqiang 时间: 2016-3-12 13:52
回复 7# ivor
对powershell代码不懂啊。能否帮忙修改下。谢谢了
作者: ivor 时间: 2016-3-12 13:53
本帖最后由 ivor 于 2016-3-12 18:30 编辑
回复 1# ygqiang
我用Python写的,放在相机最顶层- # coding:utf-8
- # python 3.5.1
- import os, shutil, time
-
- # 需要复制的文件名后缀数组
- end_filter = ('.jpg','.crw', '.cr2', '.avi','.mov', '.mp4')
- # 目标文件夹
- dest_dir = 'd:\\%s-%s'% (time.localtime().tm_year,time.localtime().tm_mon)
- # 如果目标文件不存在则创建
- if os.path.exists(dest_dir) == False:
- os.mkdir(dest_dir)
- # 遍历查找需要复制的文件
- for parent, dirnames, files in os.walk('.'):
- for i in files:
- if i.endswith(end_filter):
- shutil.copy(('%s\\%s'% (parent, i)),dest_dir)
- print('copying %s\\%s'% (parent, i))
- os.system('pause')
-
-
复制代码
作者: ygqiang 时间: 2016-3-12 17:01
回复 9# ivor
用Python写的,放在相机最顶层???
具体如何使用呢?
台式机win7系统环境下,都需要装什么软件?多谢
作者: ivor 时间: 2016-3-12 17:22
回复 10# ygqiang
https://www.python.org/ftp/python/3.5.1/python-3.5.1.exe
代码保存为xx.py,后缀是.py,放在相机里面运行就会复制当前目录下面所有的照片和视频到指定目录
作者: ygqiang 时间: 2016-3-12 18:19
本帖最后由 ygqiang 于 2016-3-12 18:22 编辑
回复 11# ivor
多谢。一会测试下啊。
请问下,
# 遍历查找需要复制的文件
这个下面的代码,哪里体现出搜索佳能微单EOS M2目录下的图片/视频文件了呢?
还有,能否修改成:根据当前的年和月份,如果检测到d盘下面没有这种目录,就自动建立目录。
比如2016-03、2016-10、2017-01等等,
作者: ygqiang 时间: 2016-3-12 18:26
回复 11# ivor
文件复制不到相机任何一个目录下。
作者: ygqiang 时间: 2016-3-12 18:27
回复 11# ivor
xx.py最好放在d盘根目录下,运行1次,就自动搜索相机目录并复制所有照片/视频,到d盘的某个时间/日期目录下。
作者: ygqiang 时间: 2016-3-12 18:35
本帖最后由 ygqiang 于 2016-3-12 18:36 编辑
回复 9# ivor
你的py代码测试了。
如果py文件放在普通的目录下,目录下有01.jpg,02.jpg,IMG_0296.JPG,IMG_0298.JPG等等照片
运行py代码,只能复制01和02照片,IMG_xxxx.jpg的照片,无法复制。
搞定了。竟然也分辨大小写的扩展名。
end_filter = ('.jpg','.JPG','.crw', '.cr2', '.avi','.mov', '.mp4')
作者: ygqiang 时间: 2016-3-12 18:59
回复 11# ivor
你的这个py代码。bat批处理也能实现。- echo 搜索某个目录下所有的jpg文件,并复制到目标目录
- setlocal enabledelayedexpansion&for /f "delims=" %%a in ('dir /s /b C:\000\*.jpg') do (copy "%%a" "D:\test")
复制代码
作者: ivor 时间: 2016-3-12 19:13
回复 16# ygqiang
我搜了一下,访问相机好像很麻烦
作者: ygqiang 时间: 2016-3-12 19:18
回复 17# ivor
相机/手机,通过usb数据线连接到win7系统,不显示U盘那种盘符。
访问/读取这种设备,应该有统一的解决方案吧?
作者: ygqiang 时间: 2016-3-12 22:40
初步解决了。索引文件需要些时间 等待一会的话 文件就全了。- #
- # 获取 Shell.Application 代理
- #
- function Get-ShellProxy
- {
- if( -not $global:ShellProxy) {
- $global:ShellProxy = new-object -com Shell.Application
- }
- $global:ShellProxy
- }
- #
- # 查看 Shell 项
- #
- function Get-ShellItem
- {
- param($Path=17)
- $shell=Get-ShellProxy
- # 默认的 NameSpace()方法只支持目录,不支持文件
- # 为了增强兼容性和保持一致性,如果传入一个文件路径,可以尝试通过文件路径获取目录,然后再从目录的子项中获取Shell项
- trap [System.Management.Automation.MethodInvocationException]
- {
- $Path = $Path.ToString()
- $dir = $Path.Substring( 0 ,$Path.LastIndexOf('\') )
- return $shell.NameSpace($dir).items() |
- where { (-not $_.IsFolder ) -and $_.path -eq $Path} |
- select -First 1
- continue
- }
- $shell.NameSpace($Path).self
- }
- #
- # 查看 Shell 子项,支持递归和过滤
- #
- function Get-ChildShellItem
- {
- param(
- $Path=17,
- [switch]$Recurse,
- $Filter=$null)
- #内部过滤器
- Filter myFilter
- {
- if($Filter){
- $_ | where { $_.Name -match $Filter }
- }
- else{
- $_
- }
- }
- $shellItem = Get-ShellItem $Path
- $shellItem | myFilter
- # 如果是目录
- if( $shellItem.IsFolder ){
- # 如果指定递归
- if($Recurse) {
- $shellItem | myFilter
- $stack=New-Object System.Collections.Stack
- # 当前目录压入堆栈
- $stack.Push($shellItem)
- while($stack.Count -gt 0)
- {
- # 访问栈顶元素
- $top = $stack.Pop()
- $top | myFilter
- # 访问栈顶元素的子元素
- $top.GetFolder.items() | foreach {
- if( $_.IsFolder )
- { $stack.Push($_) }
- else { $_ | myFilter }
- }
- }
- }
- else{
- $shellItem.GetFolder.items() | myFilter }
- }
- }
- #
- # 复制Shell项
- #
- function Copy-ShellItem
- {
- param($Path,$Destination)
- $shell=Get-ShellProxy
- $shell.NameSpace($Destination).Copyhere($Path,4)
- }
- #
- # 删除Shell项
- #
- function Remove-ShellItem
- {
- param($Path)
- $ShellItem = Get-ShellItem $Path
- $ShellItem.InvokeVerb('delete')
- }
- #
- # 移动Shell项
- #
- function Move-ShellItem
- {
- param($Path,$Destination)
- $shell=Get-ShellProxy
- $shell.NameSpace($Destination).MoveHere($Path,16)
- }
- # 文件存放的地址
- $des = 'd:\'
- # 匹配相机的关键字,比如:canon,nokia,Windows Phone,meizu,Smartisan,ZUK Z1
- $keywords = 'canon','meizu','Windows Phone','nokia','Smartisan','ZUK Z1'
- foreach ($keyword in $keywords)
- {
- $phones = Get-ChildShellItem | where { $_.name -like "*$keyword*" }
- foreach ($phone in $phones)
- {
- if($phone -eq $null)
- {
- break
- }
- 1..3|%{Get-ChildShellItem -Path "$($phone.Path)" -Recurse -Filter '((.jpg)|(.crw)|(.cr2)|(.avi)|(.mov)|(.mp4))$'
- sleep 3}
- Get-ChildShellItem -Path "$($phone.Path)" -Recurse -Filter '((.jpg)|(.crw)|(.cr2)|(.avi)|(.mov)|(.mp4))$'| foreach {
- #获取照片创建日期
- $datestr = $_.Parent.GetDetailsOf($_,3)
- $datestr=(get-date).tostring("yyyy-MM")
- #新建日期文件夹
- $dir = Join-Path $des $datestr
- if( -not (Test-Path $dir) ) {
- mkdir $dir
- }
- # 如果文件存在,先删掉
- $file="{0}\{1}" -f $dir,$_.name
- if( test-path $file) { remove-item $file }
- # 复制文件
- Copy-ShellItem -Path $_ -Destination $dir
- # 移动文件
- # move-ShellItem -Path $_ -Destination $dir
- }
- }
- }
- exit
- $des = [environment]::GetFolderPath([System.Environment+SpecialFolder]::MyPictures)
复制代码
欢迎光临 批处理之家 (http://www.bathome.net/) |
Powered by Discuz! 7.2 |