2012-09-28 451 views
17

El código siguiente no puede iniciar documentos. Obtengo el error 193 (% 1 no es una aplicación Win32 válida). Iniciar ejecutables funciona bien. Los archivos están asociados correctamente, inician la aplicación correspondiente al hacer doble clic. He buscado SO y en otras partes del mensaje de error, etc. cosas CreateProcess (Ej Why is CreateProcess failing in Windows Server 2003 64-bit? que sé de citar la línea de comandos.¿Por qué CreateProcess proporciona el error 193 (% 1 no es una aplicación Win32 válida)

  • Ésta es una XE2 Delphi (Update 4) Win32 aplicación de 64 bits en un Win7 VMWare VM.

  • el código también falla en la máquina host (Win7 64 bits) y en un PC virtual VM con 32 bits de XP.

  • las aplicaciones que deben comenzar en el Win7 VM (Excel 2003 y carmesí Editor) son 32 bits.

  • Se produce el fallo tanto cuando se parte de la IDE o cuando se ejecuta la aplicación de pruebas autónomo

  • lo que solía ser Delphi2007 código, la aplicación D2007 compilado en el código proviene de las obras excelentes en todas partes.

¿Qué pasa con el código? Es casi como si estuviera pasando por alto algo muy obvio ....

Gracias de antemano,

Ene

procedure StartProcess(WorkDir, Filename: string; Arguments : string = ''); 
var 
    StartupInfo : TStartupInfo; 
    ProcessInfo : TProcessInformation; 
    lCmd   : string; 
    lOK   : Boolean; 
    LastErrorCode: Integer; 
begin 
    FillChar(StartupInfo, SizeOf(TStartupInfo), 0); 
    StartupInfo.cb := SizeOf(TStartupInfo); 
    StartupInfo.dwFlags := STARTF_USESHOWWINDOW; 
    StartupInfo.wShowWindow := sw_Normal; 

    FillChar(ProcessInfo, SizeOf(TProcessInformation), 0); 

    lCmd := '"' + WorkDir + FileName + '"';  // Quotes are needed https://stackoverflow.com/questions/265650/paths-and-createprocess 
    if Arguments <> '' then lCmd := lCmd + ' ' + Arguments; 

    lOk := CreateProcess(nil, 
         PChar(lCmd), 
         nil, 
         nil, 
         FALSE, // TRUE makes no difference 
         0,  // e.g. CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS makes no difference 
         nil, 
         nil, // PChar(WorkDir) makes no difference 
         StartupInfo, 
         ProcessInfo); 

    if lOk then 
    begin 
    try 
     WaitForSingleObject(ProcessInfo.hProcess, INFINITE); 
    finally 
     CloseHandle(ProcessInfo.hThread); 
     CloseHandle(ProcessInfo.hProcess); 
    end; 
    end 
    else 
    begin 
    LastErrorCode := GetLastError; 
    ShowMessage(IntToStr(LastErrorCode) + ': ' + SysErrorMessage(LastErrorCode)); 
    end; 
end; 

procedure TFrmStartProcess.Button1Click(Sender: TObject); 
begin 
    StartProcess('c:\program files (x86)\axe3\','axe.exe'); // Works 
end; 

procedure TFrmStartProcess.Button2Click(Sender: TObject); 
begin 
    StartProcess('d:\','klad.xls');       // Fails 
end; 

procedure TFrmStartProcess.Button3Click(Sender: TObject); 
begin 
    StartProcess('d:\','smimime.txt');       // Fails 
end; 
+0

¿Qué ocurre para decir el último si se llama específicamente bloc de notas en el archivo de texto? – BugFinder

+9

No estoy familiarizado con Delphi, pero WINAPI 'CreateProcess()' se puede utilizar para iniciar '.exe's solamente. Si desea ejecutar otros tipos de archivos, debe usar ['ShellExecute()'] (http://msdn.microsoft.com/en-us/library/windows/desktop/bb762153 (v = vs.85) .aspx) – hmjd

+0

@hjmd Ese código solía funcionar en la versión de código anterior, llamando a archivos .XLS. –

Respuesta

23

Las explicaciones más probables para que el error son:

  1. El archivo que está intentando cargar no es un archivo ejecutable. CreateProcess requiere que proporcione un archivo ejecutable. Si desea poder abrir cualquier archivo con su aplicación asociada, entonces necesita ShellExecute en lugar de CreateProcess.
  2. Hay un problema al cargar una de las dependencias del ejecutable, es decir, las DLL que están vinculadas al ejecutable. La razón más común es una discrepancia entre un archivo ejecutable de 32 bits y un archivo DLL de 64 bits, o viceversa. Para investigar, use el modo de perfil Dependency Walker's para verificar exactamente qué está fallando.

lectura hasta el final del código, puedo ver que el problema es el número 1.

+1

Dios mío. Estamos reescribiendo nuestro código de D2007 a XE2 y en el proceso eliminando algunas bibliotecas externas. En ese proceso, descartamos un componente de 'Launcher' de terceros que usaba ShellExecute, y lo reemplazamos con nuestro propio componente 'Launcher' que solo era adecuado para ejecutable y, por lo tanto, usamos CreateProcess. Qué tan confuso puede ser. Lo siento chicos. –

+1

# 2 me mordió ayer. Delphi agrega las rutas BPL de 32 bits y BPL de 64 bits a la misma ruta global, por lo que los nombres DLL DEBEN diferir, supe ayer, después de un poco de dolor. Esta pregunta es útil por sí misma. Quédatelo. –

+0

A menos que especifique rutas completas, solo hay dos maneras para que las DLL de 32 y 64 bits usen el mismo nombre. Se colocan en system32, pero solo se pretende que MS lo haga, o viven en el mismo directorio que el ejecutable. –

6

Sus Button2Click y Button3Click funciones pasan klad.xls y smimime.txt. Es muy probable que estos archivos no sean realmente ejecutables.

Con el fin de abrir archivos arbitrarios utilizando la aplicación asociada con ellos, utilizar ShellExecute

+1

¡Adoro los subterfugios! :) –

Cuestiones relacionadas