Winexec com problema

Delphi

14/03/2006

Tenho o seguinte comando para zipar arquivos
WinExec(PChar(´C:\Arquivo de Programas\WinZip\WinZip32, etc
no meu computador funciona, no do cliente funcionava e de uma hora para outra parou de funcionar (não sei o que ele fez), simplesmente não reconhece o ´nome grande´, se trocar para c:\arquiv~!\winzip\winzip32 ele volta a funcionar, alguém sabe qual é o problema? O Windows é o XP


Edilcimar

Edilcimar

Curtidas 0

Respostas

Paullsoftware

Paullsoftware

14/03/2006

olá Eldicimar, tente substituir o comando WinExec() por essa procedure que fiz depois de ter problemas semelhantes ao seu...

procedure ExecProg(Nome, Parametros: String; Janela:Integer);
Var
 Comando: Array[0..1024] of Char;
 Parms: Array[0..1024] of Char;
begin
  Nome := ´"´ + Nome + ´"´;//Coloca o endereço entre aspas, deve ser usado em path´s muito longas...
  StrPCopy (Comando, Nome);
  StrPCopy (Parms, Parametros);
  ShellExecute (0, Nil, Comando, Parms, Nil, Janela);
end;


espero ter ajudado :wink:


GOSTEI 0
Turbo Drive

Turbo Drive

14/03/2006

Aproveitando a dúvida do nosso colega, vc poderia colocar um exemplo de como se utiliza esta procedure para o winzip ?


Grato pela atenção.


GOSTEI 0
Turbo Drive

Turbo Drive

14/03/2006

Aproveitando a dúvida do nosso colega, vc poderia colocar um exemplo de como se utiliza esta procedure para o winzip ?


Grato pela atenção.


GOSTEI 0
Edilcimar

Edilcimar

14/03/2006

Ok, PaullSoftware, mas vc sabe o porquê deste problema?


GOSTEI 0
Edilcimar

Edilcimar

14/03/2006

e acabei de descobrir que em um dos computadores mesmo com o nome ´curto´, c:\arquiv~1\winzip\winzip32 não funciona!


GOSTEI 0
Paullsoftware

Paullsoftware

14/03/2006

Ok, PaullSoftware, mas vc sabe o porquê deste problema?

Normalmente o Windows se encarrega de substituir espaços em branco por ~ tipo assim:

para acessar a pasta C:\Paulo Ricardo\Arquivos muitas vezes ele faz assim: C:\Paul~1\arquivos e na época do dos para se acessar paths que continham espaços era preciso colocá-lo entre aspas assim:
´C:\Paulo Ricardo\Arquivos´ entedeu?


GOSTEI 0
Edilcimar

Edilcimar

14/03/2006

1) no DOS eu sei que ele transforma o nome grande em nome pequeno, com 8 caracteres
2) tem computador que está aceitando nome grande, tem computador que está aceitando nome pequeno e tem computador que não está aceitando nem o nome grande nem o nome pequeno
3) o meu comando do winexec() está entre aspas
Eu sempre achei que o xp não trocasse o nome grande pelo pequeno, e pelo tipo de erro que está dando não creio que seja este relamente o problema, mas sim um outro que não descobri


GOSTEI 0
Martins

Martins

14/03/2006

e acabei de descobrir que em um dos computadores mesmo com o nome ´curto´, c:\arquiv~1\winzip\winzip32 não funciona!


Interessante isso [b:5deb70c036]Edilcimar[/b:5deb70c036], vc já tentou pelo prompt? Tente colocar no prompt assim:

[b:5deb70c036]´C:\Arquivo de Programas\WinZip\WinZip32... etc´[/b:5deb70c036]

coloque entre aspas.

Boa sorte!!!


GOSTEI 0
Edilcimar

Edilcimar

14/03/2006

se eu colocar no ´executar´ do windows, na máquina onde o winexec não funciona dentro do programa, o comando c:\arquivos de programas\winzip\winzip32 não funciona, porém se colocar entre aspas funciona, mas dentro do meu programa ele está com aspas, e na máquina onde o nem longo nem nome curto não funcionam, o executar do windows funciona normalmente entre aspas


GOSTEI 0
Edilcimar

Edilcimar

14/03/2006

se eu colocar no ´executar´ do windows, na máquina onde o winexec não funciona dentro do programa, o comando c:\arquivos de programas\winzip\winzip32 não funciona, porém se colocar entre aspas funciona, mas dentro do meu programa ele está com aspas, e na máquina onde o nem longo nem nome curto não funcionam, o executar do windows funciona normalmente entre aspas


GOSTEI 0
Edilcimar

Edilcimar

14/03/2006

sobe


GOSTEI 0
Martins

Martins

14/03/2006

sobe


Muito estrranho isso aí viu [b:5647079e2d]Edilcimar[/b:5647079e2d], poderia ser vírus ou alguma config. do Windows?

Pq nunca vi isso.


GOSTEI 0
Edilcimar

Edilcimar

14/03/2006

Não sei se tem virus ou se é uma configuração do windows, mas talvez seja configuração do windows, pois todos os computadores do cliente estão em rede e em cada um acontece uma das coisas, e no meu computador está funcionando perfeitamente


GOSTEI 0
Martins

Martins

14/03/2006

Não sei se tem virus ou se é uma configuração do windows, mas talvez seja configuração do windows, pois todos os computadores do cliente estão em rede e em cada um acontece uma das coisas, e no meu computador está funcionando perfeitamente


Então pode ser a config. mas é estranho, não caberia encontrar outra solução para esse problema?

Podemos tentar.


GOSTEI 0
Aroldo Zanela

Aroldo Zanela

14/03/2006

Colega,

Fiz algumas pesquisas para ver se alguém na comunidade internacional já tinha passado pelo problema e infelizmente, não encontrei nada. Esta funcionalidade da API (Kernel32) já não é recomendada há algum tempo e ShellExecute deve ser usada em sua substituição.

Mesmo assim, encontrei uma função escrita por Pat Ritchey (TeamB) e aprimorada por Xavier Pacheco (TeamB) para executar um processo e aguardar sua finalização. Como não se trata de uma API, podemos efetuar qualquer correção que seja necessária.

function WinExecAndWait32(FileName:String; Visibility : integer):
LongWord;
var { by Pat Ritchey }
  zAppName:array[0..512] of char;
  zCurDir:array[0..255] of char;
  WorkDir:String;
  StartupInfo:TStartupInfo;
  ProcessInfo:TProcessInformation;
begin
  StrPCopy(zAppName,FileName);
  GetDir(0,WorkDir);
  StrPCopy(zCurDir,WorkDir);
  FillChar(StartupInfo,Sizeof(StartupInfo),#0);
  StartupInfo.cb := Sizeof(StartupInfo);
  StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
  StartupInfo.wShowWindow := Visibility;
  if not CreateProcess(nil,
    zAppName, // pointer to command line string
    nil, // pointer to process security attributes
      nil, // pointer to thread security attributes
      false, // handle inheritance flag
      CREATE_NEW_CONSOLE or // creation flags
      NORMAL_PRIORITY_CLASS,
      nil, //pointer to new environment block
      nil, // pointer to current directory name
      StartupInfo, // pointer to STARTUPINFO
      ProcessInfo) // pointer to PROCESS_INF
  then Result := WAIT_FAILED
  else begin
     WaitforSingleObject(ProcessInfo.hProcess, INFINITE);
     GetExitCodeProcess(ProcessInfo.hProcess, Result);
     CloseHandle( ProcessInfo.hProcess );
     CloseHandle( ProcessInfo.hThread );
  end;
end;



GOSTEI 0
Edilcimar

Edilcimar

14/03/2006

Ok, grato, vou testar os 2 processos passados, pelo PaullSoftware e Zanela, para ver se funcionam no cliente, mas a dúvida continua!


GOSTEI 0
Aroldo Zanela

Aroldo Zanela

14/03/2006

Colega,

Encontrei outra funçao aqui na JCL (Jedi), mais especificamente na unit [b:35d48a7d7e]JclMiscel[/b:35d48a7d7e].

function WinExec32(const Cmd: string; const CmdShow: Integer): Boolean;
var
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
begin
  FillChar(StartupInfo, SizeOf(TStartupInfo), #0);
  StartupInfo.cb := SizeOf(TStartupInfo);
  StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
  StartupInfo.wShowWindow := CmdShow;
  Result := CreateProcess(nil, PChar(Cmd), nil, nil, False,
    NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo, ProcessInfo);
  if Result then
  begin
    WaitForInputIdle(ProcessInfo.hProcess, INFINITE);
    CloseHandle(ProcessInfo.hThread);
    CloseHandle(ProcessInfo.hProcess);
  end;
end;



GOSTEI 0
Martins

Martins

14/03/2006

Sei q várias soluções já foram postadas e vão ser testadas por isso gostaria de sugerir o uso da variavel [b:b131012f95]CmdLine[/b:b131012f95].

encontrei esse exemplo e não tive tempo de testar, mas vc poderia dar uma olhada.

function ExecAndWait(const FileName, Params: string;
  const WindowState: Word): boolean;
var
  SUInfo: TStartupInfo;
  ProcInfo: TProcessInformation;
  CmdLine: string;
begin
  { Coloca o nome do arquivo entre aspas. Isto é necessário devido
    aos espaços contidos em nomes longos }
  CmdLine := ´"´ + Filename + ´"´ + Params;
  FillChar(SUInfo, SizeOf(SUInfo), #0);
  with SUInfo do  begin
    cb := SizeOf(SUInfo);
    dwFlags := STARTF_USESHOWWINDOW;
    wShowWindow := WindowState;
  end;
  Result := CreateProcess(nil, PChar(CmdLine), nil, nil, false,
    CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil,
    PChar(ExtractFilePath(Filename)), SUInfo, ProcInfo);

  { Aguarda até ser finalizado }
  if Result then begin
    WaitForSingleObject(ProcInfo.hProcess, INFINITE);
    { Libera os Handles }
    CloseHandle(ProcInfo.hProcess);
    CloseHandle(ProcInfo.hThread);
  end;
end;


Usa-se assim.

ExecAndWait(´c:\windows\notepad.exe´, ´´, SW_SHOW);


Boa sorte


GOSTEI 0
Edilcimar

Edilcimar

14/03/2006

Vou testar todas no final de semana, mas até agora não achei uma resposta plausível par o erro em si, afinal de contas o mesmo não se justifica (exceto o maior problema de todos chamado bill gates)


GOSTEI 0
Ipc$

Ipc$

14/03/2006

Provavelmente vc deve ter um arquivo chamado [b:1bb13f6f6a]Program.exe[/b:1bb13f6f6a] nessa máquina que não funciona.
Se tiver, o Winexec(Pchar(´C:\Program Files´..., executará Program.exe pq ele já encontrou o que executar. Os espaços as vezes pode complicar.


GOSTEI 0
Ipc$

Ipc$

14/03/2006

Desculpe, não prestei atenção na sua chamada; ao invés de C:\Program Files, vc faz C:\Arquivo de ...
Veja se vc tem um [b:8bfa699072]Arquivo.exe[/b:8bfa699072], ou .scr, .bat etc . . .


GOSTEI 0
Edilcimar

Edilcimar

14/03/2006

Martins, Zanela e PaullSoftware, infelizmente devido ao desenvolvimento urgente de outro programa não deu tempo de testar, mas as hipóteses e a promessa de teste não foram descartadas


GOSTEI 0
Paullsoftware

Paullsoftware

14/03/2006

:arrow: blz não esquenta com isso :!:


GOSTEI 0
POSTAR