2012-09-28 141 views
17

下面的代碼無法啓動文檔。我收到錯誤193(%1不是有效的Win32應用程序)。啓動可執行文件正常工作。 文件正確關聯,雙擊時會啓動相應的應用程序。 我已經搜索SO和其他地方的錯誤消息,CreateProcess的東西等(例如Why is CreateProcess failing in Windows Server 2003 64-bit? 我知道引用命令行。爲什麼CreateProcess會給出錯誤193(%1不是有效的Win32應用程序)

  • 這是一個Delphi XE2(更新4)在一個64位的Win7的Win32應用VMware虛擬機。

  • 的代碼也沒有在主機上(Win7的64位),並在虛擬PC虛擬機與32位XP。

  • 應在Win7的虛擬機(Excel 2003和深紅啓動應用程序編輯器)是32位。

  • 發生故障無論是從IDE啓動或運行測試程序獨立位置

  • 它曾經是Delphi2007代碼,編譯後的D2007的應用程序,其中的代碼來自於世界各地的作品很好,當時。

代碼有什麼問題?這是幾乎一樣,如果我忽視的東西很明顯的....提前

感謝,

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

的說上一句,如果你專門調用記事本上的文本文件,會發生什麼? – BugFinder

+9

我對Delphi並不熟悉,但WINAPI'CreateProcess()'只能用於啓動'.exe's。如果想要運行其他類型的文件,您需要使用['ShellExecute()'](http://msdn.microsoft.com/en-us/library/windows/desktop/bb762153(v = vs.85).aspx )。 – hmjd

+0

@hjmd該代碼用於在以前的代碼版本中工作,調用.XLS文件。 –

回答

23

該錯誤最可能的解釋是:

  1. 您正在嘗試加載的文件不是可執行文件。 CreateProcess要求您提供可執行文件。如果您希望能夠使用其關聯的應用程序打開任何文件,則需要ShellExecute而不是CreateProcess
  2. 加載可執行文件的依賴關係之一,即鏈接到可執行文件的DLL時出現問題。最常見的原因是32位可執行文件和64位DLL之間不匹配,反之亦然。要進行調查,請使用Dependency Walker's配置文件模式來檢查到底發生了什麼問題。

讀下來的代碼的底部,我可以看到的問題是1號。

+1

我的天啊。我們正在將我們的代碼從D2007重寫到XE2,並且在這個過程中廢除了一些外部庫。在那個過程中,我們扔掉了一個使用了ShellExecute的第三方'Launcher'組件,並用我們自己的'Launcher'組件取而代之,該組件僅適用於可執行文件,因此使用了CreateProcess。它有多混淆。對不起大家。 –

+1

#2昨天我咬了我一口。 Delphi將32位BPL和64位BPL路徑添加到同一個全局路徑中,所以這些DLL名稱必須有所不同,昨天我經歷了一些痛苦之後才得知。這個問題本身是有用的。收下。 –

+0

除非您指定完整路徑,否則32位和64位DLL只能使用兩種方式使用相同的名稱。它們被放置在system32中,但是隻有MS纔會這樣做,或者它們與可執行文件位於同一個目錄中。 –

6

Button2ClickButton3Click功能通過klad.xlssmimime.txt。這些文件很可能不是真正的可執行文件。

爲了打開使用與之相關的應用程序的任意文件,使用ShellExecute

+1

我喜歡輕描淡寫! :) –

相關問題