2012-09-28 53 views
17

Mã bên dưới không khởi động được tài liệu. Tôi gặp lỗi 193 (% 1 không phải là một ứng dụng Win32 hợp lệ). Bắt đầu thực thi hoạt động tốt. Các tệp được liên kết đúng cách, chúng bắt đầu ứng dụng tương ứng khi nhấp đúp. Tôi đã tìm kiếm SO và các nơi khác cho các thông báo lỗi, công cụ CreateProcess vv (Ví dụ Why is CreateProcess failing in Windows Server 2003 64-bit? tôi biết về trích dẫn dòng lệnh.Tại sao CreateProcess cung cấp lỗi 193 (% 1 không phải là một ứng dụng Win32 hợp lệ)

  • Đây là một Delphi XE2 (Cập nhật 4) ứng dụng Win32 trong một 64bit Win7 VMWare VM.

  • mã này cũng không thành công trên máy chủ (Win7 64 bit) và tại một máy tính ảo VM với 32bit XP.

  • các ứng dụng mà nên bắt đầu trong Win7 VM (Excel 2003 và Crimson Trình chỉnh sửa) là 32 bit.

  • Sự thất bại xảy ra cả khi bắt đầu từ IDE hoặc khi chạy ứng dụng thử nghiệm độc

  • Nó được sử dụng để được mã Delphi2007, ứng dụng D2007 biên soạn nơi mã này xuất phát từ tác phẩm mỹ ở khắp mọi nơi.

Có vấn đề gì với mã? Nó gần như thể tôi đang nhìn cái gì đó rất rõ ràng ....

Cảm ơn trước,

Jan

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

gì sẽ xảy ra cho nói cuối cùng một nếu bạn đặc biệt gọi notepad vào file văn bản không? – BugFinder

+9

Tôi không quen thuộc với Delphi, nhưng WINAPI 'CreateProcess()' có thể được sử dụng để bắt đầu '.exe chỉ. Nếu muốn _run_ các loại tệp khác bạn cần sử dụng ['ShellExecute()'] (http://msdn.microsoft.com/en-us/library/windows/desktop/bb762153 (v = vs.85) .aspx). – hmjd

+0

@hjmd Mã đó được sử dụng để làm việc trong phiên bản mã trước đó, gọi các tệp .XLS. –

Trả lời

23

Những lời giải thích khả năng nhất cho lỗi đó là:

  1. Tệp bạn đang cố gắng tải không phải là tệp thi hành. CreateProcess yêu cầu bạn cung cấp tệp thi hành. Nếu bạn muốn có thể mở bất kỳ tệp nào có ứng dụng được liên kết thì bạn cần ShellExecute thay vì CreateProcess.
  2. Có sự cố khi tải một trong các phụ thuộc của tệp thực thi, tức là các tệp DLL được liên kết với tệp thực thi. Lý do phổ biến nhất cho điều đó là sự không phù hợp giữa tệp thực thi 32 bit và DLL 64 bit hoặc ngược lại. Để điều tra, hãy sử dụng chế độ cấu hình Dependency Walker's để kiểm tra chính xác những gì đang xảy ra.

Reading xuống dưới cùng của mã này, tôi có thể thấy rằng vấn đề là số 1.

+1

O lòng tốt của tôi. Chúng tôi đang viết lại mã của chúng tôi từ D2007 để XE2 và trong quá trình làm đi với một số thư viện bên ngoài. Trong quá trình đó, chúng tôi đã ném đi một thành phần 'Launcher' của bên thứ ba đã sử dụng ShellExecute và thay thế nó bằng thành phần 'Launcher' của riêng chúng tôi, nó chỉ thích hợp cho thực thi và do đó được sử dụng CreateProcess. Làm thế nào khó hiểu nó có thể nhận được. Xin lỗi các bạn. –

+1

# 2 bit tôi hôm qua. Delphi bổ sung cả hai đường dẫn BPL 32 bit và BPL 64 bit vào cùng một đường dẫn toàn cục, vì vậy các tên DLL PHẢI khác nhau, tôi đã học được ngày hôm qua, sau một số cơn đau. Câu hỏi này rất hữu ích. Giữ nó. –

+0

Trừ khi bạn chỉ định đường dẫn đầy đủ, chỉ có hai cách cho 32 và 64 bit DLL để sử dụng cùng một tên. Chúng được đặt trong system32, nhưng chỉ có MS là có nghĩa là để làm điều đó, hoặc họ sống trong cùng một thư mục như thực thi. –

6

Button2ClickButton3Click của bạn chức năng vượt qua klad.xlssmimime.txt. Các tệp này rất có thể không phải là thực thi thực tế.

Để mở tập tin tùy ý sử dụng các ứng dụng liên kết với chúng, sử dụng ShellExecute

+1

Tôi yêu câu trả lời! :) –

Các vấn đề liên quan