LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

LaunchExecutableEx only works for external application in same folder as main application

Solved!
Go to solution

Hello!  I have an issue using LaunchExecutableEx() in my CVI 2019 app. I want to spawn an external app as it starts up, and it does work, but only if I have the external app located in the same folder as the CVI app. If i have it anywhere else, and use the full pathname as indicated in the documentation, the function returns 0, but the app does not get launched at all. So there appears to be a false sense of security happening when it is anywhere but the local folder.

 

Here is an example of what works:


status = LaunchExecutableEx("TDL_Central_CFTS.exe", LE_SHOWNORMAL, NULL);
if (status < 0)
{
sprintf(g_StatusBuffer,"ERROR: TM app failed to launch: error code = %d\n", status);
SetCtrlVal(gh_panel,PANEL_TXT_STATUS,g_StatusBuffer);
}

 

And what does *not work for me: 


status = LaunchExecutableEx("C:\\Users\\1116823\\Downloads\\TDL\\TDL_Central_CFTS.exe", LE_SHOWNORMAL, NULL);
if (status < 0)
{
sprintf(g_StatusBuffer,"ERROR: TM app failed to launch: error code = %d\n", status);
SetCtrlVal(gh_panel,PANEL_TXT_STATUS,g_StatusBuffer);
}

 

What I am missing? Thank you!

0 Kudos
Message 1 of 8
(1,603 Views)
Solution
Accepted by AbbyMize

I notice the Download path name. Did you really try in a normal installer location like \"C:\\Program Files (x86)\\Your App\\YourApplication.exe\"? And yes don't forget the quotes in the string since the path contains spaces.

 

Under recent Windows versions you can't just launch downloaded exe files from anywhere without first telling the Windows shell that it is safe to do so.

 

You can open the Properties dialog of an executable file in Explorer and on there you can check a checkbox to allow the program to be executable. But better would be to install it in a real program location.

Rolf Kalbermatter
My Blog
0 Kudos
Message 2 of 8
(1,588 Views)

OK maybe that was it, thank you! It works like that with the full path when I have it on the C:/ drive or C:/Program Files. And I was running it from a separate F: disk drive.  Good to go now!

0 Kudos
Message 3 of 8
(1,544 Views)

Hello again,

 

I noticed something about using this function, that output files from the secondary executable, are not saved in that application's local folder, but in the LabWindows app that is launching it.  I don't understand why that could be, since all it did was launch the secondary app and let it run on its own. The 2 apps are in completely different locations.

 

Thanks!

0 Kudos
Message 4 of 8
(1,521 Views)

Well, when a process starts another process, it is initialized as child process by default. This means that the child process inherits many attributes of the calling process, including often things like access rights to handles, and yes also the so called current directory.

 

LaunchExecutableEx() doesn't seem to provide a parameter for the "default directory" to use which is kind of unfortunate. You may have to resort to using directly Windows API functions such a CreateProcess() to achieve this, or early on in your launched process determine the path to your executable and then set it as current directory.

 

 

TCHAR filename[MAX_PATH);
DWORD retval = GetModuleFileName(NULL, filename, MAX_PATH);
if (retval)
{
    PathRemoveFileSpec(filename);
    SetCurrentDirectory(filename);
}

 

OR even better yet, work with absolute paths in your launched executable. Under modern Windows versions an application has no business in trying to write to its own directory.

 

Rolf Kalbermatter
My Blog
Message 5 of 8
(1,507 Views)

OK, I am trying to use CreateProcessA() now, I just pass the full path to the executable in the first param, and have the other params NULL. But I get a general protection fault when it is called. I have it on a custom folder on the C: drive: 

 

C:/FTS/TDL_Central_Program_CFTS_v0.3.3/Release/TDL_Central_CFTS.exe

 

Do you know what could be happening there?

 

Thanks!

0 Kudos
Message 6 of 8
(1,475 Views)

@AbbyMize wrote:

OK, I am trying to use CreateProcessA() now, I just pass the full path to the executable in the first param, and have the other params NULL. But I get a general protection fault when it is called. I have it on a custom folder on the C: drive: 


Nowhere in the documentation does it say that lpStartupInfo may be NULL In fact there is some vital information in there that you will need to use to get a handle on the newly created process and you will also need to close all handles in there that are properly closed. Nobody said that CreateProcess() was easy to use.

 

lpStartupInfo

A pointer to a STARTUPINFO or STARTUPINFOEX structure.

To set extended attributes, use a STARTUPINFOEX structure and specify EXTENDED_STARTUPINFO_PRESENT in the dwCreationFlags parameter.

Handles in STARTUPINFO or STARTUPINFOEX must be closed with CloseHandle when they are no longer needed.

Important  The caller is responsible for ensuring that the standard handle fields in STARTUPINFO contain valid handle values. These fields are copied unchanged to the child process without validation, even when the dwFlags member specifies STARTF_USESTDHANDLES. Incorrect values can cause the child process to misbehave or crash. Use the Application Verifier runtime verification tool to detect invalid handles.
Rolf Kalbermatter
My Blog
0 Kudos
Message 7 of 8
(1,471 Views)

I had this problem recently, found this discussion, and 'SetDir()' was exactly the solution.  Thanks!

0 Kudos
Message 8 of 8
(175 Views)