COMPONENTE BACKGROUNDWORKER ABRIR ARQUIVOS

LUIS.HERRERA 20/05/2013 14:28:37
#423765
Alguém já usou o ToolStripProgressBar para exibir o processo de carregamento / abertura de um arquivo qualquer pelo seu programa associado (extensão no Windows)?

Estou usando o Windows Forms e uma rotina para abrir (via processo) um arquivo pelo seu programa de origem assim:

Num LinkLabel associei o link do arquivo desejado e no clique do LinkLabel abro o arquivo que pode estar no micro local ou na rede do cliente.

linkLabel1.Text = [Ô]Abre Arquivo Word[Ô];
linkLabel1.Links.Add(0, linkLabel1.Text.Length, System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + @[Ô]    emp.doc[Ô]); //abre arquivo do word


private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
string strLink = @e.Link.LinkData.ToString();
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.FileName = [Ô]rundll32.exe[Ô];
process.StartInfo.Arguments = [Ô]url.dll,FileProtocolHandler [Ô] + strLink;
process.StartInfo.UseShellExecute = true;
process.Start();
}


Nesse exemplo o app abre qualquer arquivo, mas quero que o processo seja exibido na barra de progresso da status bar, pois no Dot.Net ou em função de acesso a rede, o arquivo pode demorar e quero que o usuário saiba e não pense que o programa travou.

Tentei ainda pesquisar pelo controle backgroundWorker, mas não consegui nada desse tipo, só com manipulação de dados.

Alguém sabe como fazer isso? C# 2008
LUIS.HERRERA 20/05/2013 15:44:19
#423769
Alevale esse seu link é para download de arquivos (WEB) e não é o meu caso.

O que preciso é controlar o processo de abrir um programa qualquer com o arquivo passado, ou seja, vou passar para o Windows o arquivo e pela extensão dele será aberto o programa associado.

Essa parte está pronta no código acima, o que falta é como iniciar a barra de progresso do StatusStrip e acompanhar tanto a abertura do programa (Word, Excel, AdobeReader, ou qualquer outro e o arquivo passado).

Ao implementar só o código que abre o programa Word (ex), no meu micro demorou 5 segundos com um arquivo local de 50 kb. Meu micro tem: C# 2008, Windows 7 Pro e Pentium 5i de 3 geração (3 Ghz). Agora imagino isso num Dual Core, Windows XP acessando um arquivo em rede de 3 MB, pode levar muito mais tempo e o usuário pode pensar que o micro travou.
OCELOT 20/05/2013 16:18:11
#423773
Infelizmente acho que não tem como colocar um progresso baseado em algo que outro programa está fazendo ou do tempo de um outro programa abrindo, pois não tem como você saber se ele já carregou ou não, a não ser que o programa te informe isso, mas não é o caso.
LUIS.HERRERA 20/05/2013 17:02:03
#423775
Encontrei 2 links:

Como estou usando System.Diagnostics.Process, ou seja, iniciando um processo do Windows, existem várias propriedades e métodos dessa classe segundo a MSDN, mas o problema que não tem exemplos de uso.
http://msdn.microsoft.com/pt-br/library/system.diagnostics.process.aspx

O outro usa Thead com ProgressBar para acompanhar processo. Porém sinceramente não consegui entender.
http://www.dotnetperls.com/threadpool

Será que dá para fazer, pois todos os processos em outros aplicativos possuem barra de progresso, não acredito que o Dot.Net tenha deixado isso de fora.
PROGRAMADORVB6 20/05/2013 17:14:58
#423776
Olá Luis.
Não é em C# como vc pretendia, mas dê uma olhada e veja se serve alguma coisa neste link:
http://dotnet.mvps.org/dotnet/faqs/?id=readfile
OCELOT 21/05/2013 10:07:30
#423797
Citação:

:
Encontrei 2 links:

Como estou usando System.Diagnostics.Process, ou seja, iniciando um processo do Windows, existem várias propriedades e métodos dessa classe segundo a MSDN, mas o problema que não tem exemplos de uso.
http://msdn.microsoft.com/pt-br/library/system.diagnostics.process.aspx

O outro usa Thead com ProgressBar para acompanhar processo. Porém sinceramente não consegui entender.
http://www.dotnetperls.com/threadpool

Será que dá para fazer, pois todos os processos em outros aplicativos possuem barra de progresso, não acredito que o Dot.Net tenha deixado isso de fora.



Para você fazer uma barra de progresso que realmente funciona você deve poder quantificar o processo, por exemplo se fosse para ler um arquivo grande em seu próprio programa você precisaria saber o tamanho do arquivo e a posição atual em que a leitura está, assim você consegue exibir o progresso.

Porém executando um programa externo não tem como fazer isso, não tem como saber o quanto esse programa já carregou, o máximo que você consegue fazer é saber se ele ainda está aberto ou se já foi fechado, por isso não tem como fazer uma barra de progresso.

Quando o programa externo que foi executado simplesmente executa alguma ação e depois se fecha sozinho é comum colocarem uma barra de progresso do tipo indeterminada, aquela que fica simplesmente rodando sem mostrar progresso, ou então colocam uma barra falsa, que vai enchendo bem devagar para fingir que o programa sabe o progresso, e então quando o programa externo termina de executar e é fechado o programa detecta isso e modifica o progresso para mostrar que completou.

E isso não tem nada a ver com o .Net, progresso não é algo que existe lá para você simplesmente pegar um valor, geralmente é você que precisa calcular o progresso e como eu disse para isso você precisa de duas coisas, um valor que corresponde ao final do processo, e um outro que corresponde ao valor atual do progresso, sem ter estes dois valores não tem como exibir um progresso, independente da linguagem usada.
LUIS.HERRERA 21/05/2013 15:23:13
#423813
ProgramadorVB6 O código é interessante, mas não é o que preciso.

OCELOT Acabei pensando isso mesmo. Implementei e deu certo. A barra de progresso fica lenta e em loop até o processo chegar ao fim, quando chega ele coloca True numa variável pública que é monitorada por um Timer no formulário que acionou o processo. Com isso ele manda interromper a barra do form MDI.

A única coisa que achei [Ô]Estranho[Ô] é que tive de criar a classe que aciona o processo no próprio Formulário que a chama, pois quando tentei criar essa classe numa biblioteca para ser reutilizada ela não funcionou, dizia que o objeto chamado não existia, mas o código é o mesmo.

    public class ChamaAplicativo
{
private System.Diagnostics.Process myProcess = new System.Diagnostics.Process();

// Recebe Path + Arquivo a ser aberto pelo programa que o criou (Windows checa extensão para saber quem é).
public void Abrir(string fileName)
{
VariaveisAmbiente.eventHandled = false;

try
{
myProcess.StartInfo.FileName = [Ô]rundll32.exe[Ô];
myProcess.StartInfo.Arguments = [Ô]url.dll,FileProtocolHandler [Ô] + fileName; [txt-color=#e80000]// Erro aqui se colocar numa classe fora do form chamador.[/txt-color]
myProcess.StartInfo.UseShellExecute = true;
myProcess.EnableRaisingEvents = true;
myProcess.Exited += new EventHandler(myProcess_Exited);
myProcess.Start();
}
catch (Exception ex)
{
MessageBox.Show([Ô]ErroNaoPrevisto[Ô] + ex.Message, [Ô]TituloAvisoMSG[Ô], MessageBoxButtons.OK, MessageBoxIcon.Stop);
return;
}
}

// Handle Exited event and display process information.
private void myProcess_Exited(object sender, System.EventArgs e)
{
VariaveisAmbiente.eventHandled = true;
}
}


Tem ideia do que pode ser?

Nota: A única parte diferente e que quando coloquei a classe num arquivo independente (biblioteca) eu retirei a Messagebox do Catch.
Tópico encerrado , respostas não são mais permitidas