Usuário com melhor resposta
Ajuda para mover um arquivo - diferentes resultados executando no prompt de comando e no Powershell ISE

Pergunta
-
Bom dia a todos!
Estou com um problema na execução de um script powershell. Ja busquei em varios foruns, varias solucoes alternativas mas ainda nao consegui.
O script importa dados de planilhas excel para um banco de dados SQLServer. O problema ocorre quando ao abrir uma planilha excel e apos algumas verificações necessárias para o cliente (ex nome da aba diferente do que tem que vir) tentamos mover a planilha com outro nome para um outro diretorio de erro. So que o powershell retorna o erro de que nao se pode mover pois o arquivo esta em uso. Fiz algumas alterações e em uma delas ocorreu algo estranho, que, no Powershell ISE, o processo roda ok e consegue mover a planilha, mas executando pelo prompt de comando, nao consegue mover a planilha.
No script antes de tentar mover a planilha, faço um loop e so saio do loop para mover o arquivo qdo retorna true. Funcao abaixo:
try { $sw = new-object system.io.streamwriter $filePath $sw.close() Write-Host "teste true" return $true } catch { Write-Host "teste false" return $false }
Como falei, ao executar pelo powershell ise, de primeira ele me retorna "teste true" e consegue mover o arquivo.
Ao executar pelo prompt, ele fica em loop infinito, retornando somente "teste false".Obrigado!
- Editado Fábio JrModerator quinta-feira, 27 de dezembro de 2012 15:44 Formatação do código
Respostas
-
Consegui resolver da seguinte maneira, fiz um loop, pois depois de uns 2 minutos, dependendo do tamanho da planilha, ele fecha a planilha. O LimitTime é para que não passe de uma hora, pois o processo roda a noite então da pra esperar este tempo para tentar mover corretamente a planilha.
Obrigado pela ajuda!!!
$test = $false $StartTime = (Get-Date) $LimitTime = (Get-Date) $LimitTime = $LimitTime.AddHours(1) while (($test -eq $false) -and ($StartTime -le $LimitTime)) { $StartTime = (Get-Date) try { $ErrorActionPreference = "Stop"; #Make all errors terminating Move-Item $file $newFile -force $test = $true } catch { $test = $false Start-Sleep -s 5 } finally { $ErrorActionPreference = "Continue"; #Reset the error action pref to default } }
- Marcado como Resposta Mateus Mollo sexta-feira, 11 de janeiro de 2013 13:13
Todas as Respostas
-
-
Fabio,
não, não consigo mover o arquivo quando o powershell é executado pelo prompt do DOS e está no loop de "false"
Segue o principal do codigo, pois é meio grande devido aos tratamentos dos dados da planilha.Function Process-Files { $items = dir $location -filter $filter if($items -eq $null) { Write-Log "No items to process at the time" $script:dbConn.close() exit } # clear stage tables foreach($it in $script:stageTable) { Clear-Stage-Table $it } $backupFile = $true $backupItens = $true foreach($it in $items) { $script:filexl = $location + "\" + $it Write-Log $(Get-Date) + " ------------------------------------------------------------------------" Write-Log "Processing file $script:filexl" try { # Loop for spreadsheets $stg = 0 foreach($sheet in $spreadsheets) { if($sheet -eq $null) { break; } # Retrieve data try { $data = Get-ACEData -FilePath $script:filexl -Worksheet $($sheet+ "$") } catch { Write-Host "It was not possible to retrieve the data from Excel spreadsheet. Impossible to continue." Write-Log "It was not possible to retrieve the data from Excel spreadsheet. Impossible to continue." Write-Log $_ #exit # entra aqui devido a aba da planilha estar com nome diferente do definido $backupItens = $false } if ($backupItens -eq $true) { ........ } else { $backupItens = $true $backupFile = $false continue }
#apos o continue entra neste ponto
# Moves the file
$filename = Backup-Excel $script:filexl
Esta é a função que move o arquivo Excel
function Backup-Error-Excel { param($file) $filename = $(split-path -leaf $file).split(".")[0] $extension = $(split-path -leaf $file).split(".")[1] $newFile = $script:ErrorLocation + "\" + $filename + "-" + $(get-date -f "yyyyMMddhhmm") + "." + $extension if(test-path $newFile) { Remove-Item -Force $newFile } $fileStatus = $false while ($fileStatus -eq $false) { $fileStatus = checkFileStatus $file $fileStatus } Move-Item $file $newFile -force #Return $newFile }
E esta é a função que verifica se o arquivo esta aberto:
function checkFileStatus($filePath) { try { $sw = new-object system.io.streamwriter $filePath $sw.close() return $true } catch { Write-Host "teste false" return $false } }
Obrigado
- Editado Mateus Mollo quinta-feira, 27 de dezembro de 2012 18:00 formatacao da mensagem
-
Mateus,
Ao que parece algum objeto está aberto e utilizando o Excel.
Será que não falta dar um "close" em algum objeto antes de fazer a cópia.
Eu desconfio desta linha
$data = Get-ACEData -FilePath $script:filexl -Worksheet $($sheet+ "$")
Não sei como fechar, poderia tentar um $data=$null antes de fazer a cópia.
Fábio de Paula Junior
-
Pois é Fabio... o problema é como fechar a planilha q esta em aberto. Eu alterei o nome da aba da planilha pra testar o processo e tratamento de erro, e cai neste problema.
Pesquisei bastante, e encontrei o codido da funcao checkFileStatus:function checkFileStatus($filePath) { try { $sw = new-object system.io.streamwriter $filePath $sw.close() return $true } catch { Write-Host "teste false" return $false } }
Executando o script pelo PowerShell ISE, esta funcao consegue fechar o arquivo!!! Assim, move normalmente o arquivo! O que não consigo entender é pq funciona no powershell ISE mas nao funciona executando o script pelo prompt de comando... ele cai no loop e nao consegue fechar o arquivo.
Qualquer outra duvida sobre o codigo, me peca q eu explico.
Agradeco demais sua atencao!!!
- Editado Mateus Mollo quinta-feira, 27 de dezembro de 2012 18:01 formatacao da mensagem
-
-
Fabio, fiz o teste com o $data=$null, mesmo resultado:
"Move-Item : The process cannot access the file because it is being used by another process."E sim, a função já estava no início do script... probleminha chato esse rsrsrs
Vou continuar pesquisando... tbem nao encontrei um modo de fechar o $data... a tentativa da função deu certo somente executando pelo PowerShell ISE...
Bom, no aguardo e mais uma vez obrigado pela sua ajuda e atencao!!!
-
Consegui resolver da seguinte maneira, fiz um loop, pois depois de uns 2 minutos, dependendo do tamanho da planilha, ele fecha a planilha. O LimitTime é para que não passe de uma hora, pois o processo roda a noite então da pra esperar este tempo para tentar mover corretamente a planilha.
Obrigado pela ajuda!!!
$test = $false $StartTime = (Get-Date) $LimitTime = (Get-Date) $LimitTime = $LimitTime.AddHours(1) while (($test -eq $false) -and ($StartTime -le $LimitTime)) { $StartTime = (Get-Date) try { $ErrorActionPreference = "Stop"; #Make all errors terminating Move-Item $file $newFile -force $test = $true } catch { $test = $false Start-Sleep -s 5 } finally { $ErrorActionPreference = "Continue"; #Reset the error action pref to default } }
- Marcado como Resposta Mateus Mollo sexta-feira, 11 de janeiro de 2013 13:13