DLL Dynamic-Link Library Search Order

本文详细介绍了Windows系统中DLL文件的加载顺序,包括Windows Store应用和桌面应用的不同搜索顺序。此外,还介绍了如何通过注册表设置应用程序特定路径来解决DLL加载问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://msdn.microsoft.com/en-us/library/windows/desktop/ms682586(v=vs.85).aspx

A system can contain multiple versions of the same dynamic-link library (DLL).

Applications can control the location from which a DLL is loaded by specifying a full path or

using another mechanism such as a manifest.

If these methods are not used, the system searches for the DLL at load time as described in this topic. 

  • Factors That Affect Searching
  • Search Order for Windows Store apps
    • Standard Search Order for Windows Store apps
    • Alternate Search Order for Windows Store apps
  • Search Order for Desktop Applications
    • Standard Search Order for Desktop Applications
    • Alternate Search Order for Desktop Applications
    • Search Order Using LOAD_LIBRARY_SEARCH Flags
  • Related topics

Factors That Affect Searching

The following factors affect whether the system searches for a DLL:

  • If a DLL with the same module name is already loaded in memory, the system checks only for redirection and a manifest before resolving to the loaded DLL, no matter which directory it is in. The system does not search for the DLL.
  • If the DLL is on the list of known DLLs for the version of Windows on which the application is running, the system uses its copy of the known DLL (and the known DLL's dependent DLLs, if any) instead of searching for the DLL. For a list of known DLLs on the current system, see the following registry key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs.
  • If a DLL has dependencies, the system searches for the dependent DLLs as if they were loaded with just their module names. This is true even if the first DLL was loaded by specifying a full path.

 Search Order for Windows Store apps

When a Windows Store app loads a packaged module by calling the LoadPackagedLibraryfunction, the DLL must be in the package dependency graph of the process. For more information, see LoadPackagedLibrary. When a Windows Store app loads a module by other means and does not specify a full path, the system searches for the DLL and its dependencies at load time as described in this section.

Windows 7, Windows Server 2008 R2, Windows Vista, Windows Server 2008, Windows Server 2003, and Windows XP:  Windows Store apps are supported starting with Windows 8 and Windows Server 2012.

Before the system searches for a DLL, it checks the following:

  • If a DLL with the same module name is already loaded in memory, the system uses the loaded DLL, no matter which directory it is in. The system does not search for the DLL.
  • If the DLL is on the list of known DLLs for the version of Windows on which the application is running, the system uses its copy of the known DLL (and the known DLL's dependent DLLs, if any). The system does not search for the DLL. For a list of known DLLs on the current system, see the following registry key:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs.

If the system must search for a module or its dependencies, it always uses the search order for Windows Store apps even if a dependency is not Windows Store app code.

Standard Search Order for Windows Store apps

If the module is not already loaded or on the list of known DLLs, the system searches these locations in this order:

  1. The package dependency graph of the process. This is the application's package plus any dependencies specified as <PackageDependency> in the <Dependencies> section of the application's package manifest. Dependencies are searched in the order they appear in the manifest.
  2. The directory the calling process was loaded from.
  3. The system directory (%SystemRoot%\system32).

If a DLL has dependencies, the system searches for the dependent DLLs as if they were loaded with just their module names. This is true even if the first DLL was loaded by specifying a full path.

Alternate Search Order for Windows Store apps

If a module changes the standard search order by calling the LoadLibraryEx function withLOAD_WITH_ALTERED_SEARCH_PATH, the system searches the directory the specified module was loaded from instead of the directory of the calling process. The system searches these locations in this order:

  1. The package dependency graph of the process. This is the application's package plus any dependencies specified as <PackageDependency> in the <Dependencies> section of the application's package manifest. Dependencies are searched in the order they appear in the manifest.
  2. The directory the specified module was loaded from.
  3. The system directory (%SystemRoot%\system32).

Search Order for Desktop Applications

Desktop applications can control the location from which a DLL is loaded by specifying a full path, using DLL redirection, or by using a manifest. If none of these methods are used, the system searches for the DLL at load time as described in this section.

Before the system searches for a DLL, it checks the following:

  • If a DLL with the same module name is already loaded in memory, the system uses the loaded DLL, no matter which directory it is in. The system does not search for the DLL.
  • If the DLL is on the list of known DLLs for the version of Windows on which the application is running, the system uses its copy of the known DLL (and the known DLL's dependent DLLs, if any). The system does not search for the DLL. For a list of known DLLs on the current system, see the following registry key:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs.

If a DLL has dependencies, the system searches for the dependent DLLs as if they were loaded with just their module names. This is true even if the first DLL was loaded by specifying a full path.

Important  If an attacker gains control of one of the directories that is searched, it can place a malicious copy of the DLL in that directory. For ways to help prevent such attacks, see Dynamic-Link Library Security.

Standard Search Order for Desktop Applications

The standard DLL search order used by the system depends on whether safe DLL search mode is enabled or disabled. Safe DLL search mode places the user's current directory later in the search order.

Safe DLL search mode is enabled by default. To disable this feature, create theHKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode registry value and set it to 0. Calling the SetDllDirectoryfunction effectively disables SafeDllSearchMode while the specified directory is in the search path and changes the search order as described in this topic.

Windows XP:  Safe DLL search mode is disabled by default. To enable this feature, create theSafeDllSearchMode registry value and set it to 1. Safe DLL search mode is enabled by default starting with Windows XP with Service Pack 2 (SP2).

If SafeDllSearchMode is enabled, the search order is as follows:

  1. The directory from which the application loaded.
  2. The system directory. Use the GetSystemDirectory function to get the path of this directory.
  3. The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
  4. The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
  5. The current directory.
  6. The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.

If SafeDllSearchMode is disabled, the search order is as follows:

  1. The directory from which the application loaded.
  2. The current directory.
  3. The system directory. Use the GetSystemDirectory function to get the path of this directory.
  4. The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
  5. The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
  6. The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.

Alternate Search Order for Desktop Applications

The standard search order used by the system can be changed by calling the LoadLibraryExfunction with LOAD_WITH_ALTERED_SEARCH_PATH. The standard search order can also be changed by calling the SetDllDirectory function.

Windows XP:  Changing the standard search order by calling SetDllDirectory is not supported until Windows XP with Service Pack 1 (SP1).

If you specify an alternate search strategy, its behavior continues until all associated executable modules have been located. After the system starts processing DLL initialization routines, the system reverts to the standard search strategy.

The LoadLibraryEx function supports an alternate search order if the call specifiesLOAD_WITH_ALTERED_SEARCH_PATH and the lpFileName parameter specifies an absolute path.

Note that the standard search strategy and the alternate search strategy specified byLoadLibraryEx with LOAD_WITH_ALTERED_SEARCH_PATH differ in just one way: The standard search begins in the calling application's directory, and the alternate search begins in the directory of the executable module that LoadLibraryEx is loading.

If SafeDllSearchMode is enabled, the alternate search order is as follows:

  1. The directory specified by lpFileName.
  2. The system directory. Use the GetSystemDirectory function to get the path of this directory.
  3. The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
  4. The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
  5. The current directory.
  6. The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.

If SafeDllSearchMode is disabled, the alternate search order is as follows:

  1. The directory specified by lpFileName.
  2. The current directory.
  3. The system directory. Use the GetSystemDirectory function to get the path of this directory.
  4. The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
  5. The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
  6. The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.

The SetDllDirectory function supports an alternate search order if the lpPathName parameter specifies a path. The alternate search order is as follows:

  1. The directory from which the application loaded.
  2. The directory specified by the lpPathName parameter of SetDllDirectory.
  3. The system directory. Use the GetSystemDirectory function to get the path of this directory. The name of this directory is System32.
  4. The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched. The name of this directory is System.
  5. The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
  6. The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.

If the lpPathName parameter is an empty string, the call removes the current directory from the search order.

SetDllDirectory effectively disables safe DLL search mode while the specified directory is in the search path. To restore safe DLL search mode based on the SafeDllSearchMode registry value and restore the current directory to the search order, call SetDllDirectory with lpPathName as NULL.

Search Order Using LOAD_LIBRARY_SEARCH Flags

An application can specify a search order by using one or more LOAD_LIBRARY_SEARCH flags with the LoadLibraryEx function. An application can also use LOAD_LIBRARY_SEARCH flags with the SetDefaultDllDirectories function to establish a DLL search order for a process. The application can specify additional directories for the process DLL search order by using theAddDllDirectory or SetDllDirectory functions.

Windows 7, Windows Server 2008 R2, Windows Vista, and Windows Server 2008:  TheLOAD_LIBRARY_SEARCH flags are available on systems with KB2533623 installed.

Windows Server 2003 and Windows XP:  The LOAD_LIBRARY_SEARCH flags are not supported.

The directories that are searched depend on the flags specified with SetDefaultDllDirectoriesor LoadLibraryEx. If more than one flag is used, the corresponding directories are searched in the following order:

  1. The directory that contains the DLL (LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR). This directory is searched only for dependencies of the DLL to be loaded.
  2. The application directory (LOAD_LIBRARY_SEARCH_APPLICATION_DIR).
  3. Paths explicitly added with the AddDllDirectory function (LOAD_LIBRARY_SEARCH_USER_DIRS) or the SetDllDirectory function. If more than one path has been added, the order in which the paths are searched is unspecified.
  4. The System directory (LOAD_LIBRARY_SEARCH_SYSTEM32).

If the application does not call LoadLibraryEx with any LOAD_LIBRARY_SEARCH flags or establish a DLL search order for the process, the system searches for DLLs using either the standard search order or the alternate search order.

Related topics

AddDllDirectory Application Registration Dynamic-Link Library Redirection Dynamic-Link Library Security LoadLibrary LoadLibraryEx LoadPackagedLibrary SetDefaultDllDirectories SetDllDirectory

---恢复内容结束---

http://msdn.microsoft.com/en-us/library/windows/desktop/ms682586(v=vs.85).aspx

A system can contain multiple versions of the same dynamic-link library (DLL).

Applications can control the location from which a DLL is loaded by specifying a full path or

using another mechanism such as a manifest.

If these methods are not used, the system searches for the DLL at load time as described in this topic. 

  • Factors That Affect Searching
  • Search Order for Windows Store apps
    • Standard Search Order for Windows Store apps
    • Alternate Search Order for Windows Store apps
  • Search Order for Desktop Applications
    • Standard Search Order for Desktop Applications
    • Alternate Search Order for Desktop Applications
    • Search Order Using LOAD_LIBRARY_SEARCH Flags
  • Related topics

Factors That Affect Searching

The following factors affect whether the system searches for a DLL:

  • If a DLL with the same module name is already loaded in memory, the system checks only for redirection and a manifest before resolving to the loaded DLL, no matter which directory it is in. The system does not search for the DLL.
  • If the DLL is on the list of known DLLs for the version of Windows on which the application is running, the system uses its copy of the known DLL (and the known DLL's dependent DLLs, if any) instead of searching for the DLL. For a list of known DLLs on the current system, see the following registry key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs.
  • If a DLL has dependencies, the system searches for the dependent DLLs as if they were loaded with just their module names. This is true even if the first DLL was loaded by specifying a full path.

 Search Order for Windows Store apps

When a Windows Store app loads a packaged module by calling the LoadPackagedLibraryfunction, the DLL must be in the package dependency graph of the process. For more information, see LoadPackagedLibrary. When a Windows Store app loads a module by other means and does not specify a full path, the system searches for the DLL and its dependencies at load time as described in this section.

Windows 7, Windows Server 2008 R2, Windows Vista, Windows Server 2008, Windows Server 2003, and Windows XP:  Windows Store apps are supported starting with Windows 8 and Windows Server 2012.

Before the system searches for a DLL, it checks the following:

  • If a DLL with the same module name is already loaded in memory, the system uses the loaded DLL, no matter which directory it is in. The system does not search for the DLL.
  • If the DLL is on the list of known DLLs for the version of Windows on which the application is running, the system uses its copy of the known DLL (and the known DLL's dependent DLLs, if any). The system does not search for the DLL. For a list of known DLLs on the current system, see the following registry key:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs.

If the system must search for a module or its dependencies, it always uses the search order for Windows Store apps even if a dependency is not Windows Store app code.

Standard Search Order for Windows Store apps

If the module is not already loaded or on the list of known DLLs, the system searches these locations in this order:

  1. The package dependency graph of the process. This is the application's package plus any dependencies specified as <PackageDependency> in the <Dependencies> section of the application's package manifest. Dependencies are searched in the order they appear in the manifest.
  2. The directory the calling process was loaded from.
  3. The system directory (%SystemRoot%\system32).

If a DLL has dependencies, the system searches for the dependent DLLs as if they were loaded with just their module names. This is true even if the first DLL was loaded by specifying a full path.

Alternate Search Order for Windows Store apps

If a module changes the standard search order by calling the LoadLibraryEx function withLOAD_WITH_ALTERED_SEARCH_PATH, the system searches the directory the specified module was loaded from instead of the directory of the calling process. The system searches these locations in this order:

  1. The package dependency graph of the process. This is the application's package plus any dependencies specified as <PackageDependency> in the <Dependencies> section of the application's package manifest. Dependencies are searched in the order they appear in the manifest.
  2. The directory the specified module was loaded from.
  3. The system directory (%SystemRoot%\system32).

Search Order for Desktop Applications

Desktop applications can control the location from which a DLL is loaded by specifying a full path, using DLL redirection, or by using a manifest. If none of these methods are used, the system searches for the DLL at load time as described in this section.

Before the system searches for a DLL, it checks the following:

  • If a DLL with the same module name is already loaded in memory, the system uses the loaded DLL, no matter which directory it is in. The system does not search for the DLL.
  • If the DLL is on the list of known DLLs for the version of Windows on which the application is running, the system uses its copy of the known DLL (and the known DLL's dependent DLLs, if any). The system does not search for the DLL. For a list of known DLLs on the current system, see the following registry key:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs.

If a DLL has dependencies, the system searches for the dependent DLLs as if they were loaded with just their module names. This is true even if the first DLL was loaded by specifying a full path.

Important  If an attacker gains control of one of the directories that is searched, it can place a malicious copy of the DLL in that directory. For ways to help prevent such attacks, see Dynamic-Link Library Security.

Standard Search Order for Desktop Applications

The standard DLL search order used by the system depends on whether safe DLL search mode is enabled or disabled. Safe DLL search mode places the user's current directory later in the search order.

Safe DLL search mode is enabled by default. To disable this feature, create theHKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode registry value and set it to 0. Calling the SetDllDirectoryfunction effectively disables SafeDllSearchMode while the specified directory is in the search path and changes the search order as described in this topic.

Windows XP:  Safe DLL search mode is disabled by default. To enable this feature, create theSafeDllSearchMode registry value and set it to 1. Safe DLL search mode is enabled by default starting with Windows XP with Service Pack 2 (SP2).

If SafeDllSearchMode is enabled, the search order is as follows:

  1. The directory from which the application loaded.
  2. The system directory. Use the GetSystemDirectory function to get the path of this directory.
  3. The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
  4. The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
  5. The current directory.
  6. The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.

If SafeDllSearchMode is disabled, the search order is as follows:

  1. The directory from which the application loaded.
  2. The current directory.
  3. The system directory. Use the GetSystemDirectory function to get the path of this directory.
  4. The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
  5. The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
  6. The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.

Alternate Search Order for Desktop Applications

The standard search order used by the system can be changed by calling the LoadLibraryExfunction with LOAD_WITH_ALTERED_SEARCH_PATH. The standard search order can also be changed by calling the SetDllDirectory function.

Windows XP:  Changing the standard search order by calling SetDllDirectory is not supported until Windows XP with Service Pack 1 (SP1).

If you specify an alternate search strategy, its behavior continues until all associated executable modules have been located. After the system starts processing DLL initialization routines, the system reverts to the standard search strategy.

The LoadLibraryEx function supports an alternate search order if the call specifiesLOAD_WITH_ALTERED_SEARCH_PATH and the lpFileName parameter specifies an absolute path.

Note that the standard search strategy and the alternate search strategy specified byLoadLibraryEx with LOAD_WITH_ALTERED_SEARCH_PATH differ in just one way: The standard search begins in the calling application's directory, and the alternate search begins in the directory of the executable module that LoadLibraryEx is loading.

If SafeDllSearchMode is enabled, the alternate search order is as follows:

  1. The directory specified by lpFileName.
  2. The system directory. Use the GetSystemDirectory function to get the path of this directory.
  3. The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
  4. The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
  5. The current directory.
  6. The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.

If SafeDllSearchMode is disabled, the alternate search order is as follows:

  1. The directory specified by lpFileName.
  2. The current directory.
  3. The system directory. Use the GetSystemDirectory function to get the path of this directory.
  4. The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
  5. The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
  6. The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.

The SetDllDirectory function supports an alternate search order if the lpPathName parameter specifies a path. The alternate search order is as follows:

  1. The directory from which the application loaded.
  2. The directory specified by the lpPathName parameter of SetDllDirectory.
  3. The system directory. Use the GetSystemDirectory function to get the path of this directory. The name of this directory is System32.
  4. The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched. The name of this directory is System.
  5. The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
  6. The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.

If the lpPathName parameter is an empty string, the call removes the current directory from the search order.

SetDllDirectory effectively disables safe DLL search mode while the specified directory is in the search path. To restore safe DLL search mode based on the SafeDllSearchMode registry value and restore the current directory to the search order, call SetDllDirectory with lpPathName as NULL.

Search Order Using LOAD_LIBRARY_SEARCH Flags

An application can specify a search order by using one or more LOAD_LIBRARY_SEARCH flags with the LoadLibraryEx function. An application can also use LOAD_LIBRARY_SEARCH flags with the SetDefaultDllDirectories function to establish a DLL search order for a process. The application can specify additional directories for the process DLL search order by using theAddDllDirectory or SetDllDirectory functions.

Windows 7, Windows Server 2008 R2, Windows Vista, and Windows Server 2008:  TheLOAD_LIBRARY_SEARCH flags are available on systems with KB2533623 installed.

Windows Server 2003 and Windows XP:  The LOAD_LIBRARY_SEARCH flags are not supported.

The directories that are searched depend on the flags specified with SetDefaultDllDirectoriesor LoadLibraryEx. If more than one flag is used, the corresponding directories are searched in the following order:

  1. The directory that contains the DLL (LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR). This directory is searched only for dependencies of the DLL to be loaded.
  2. The application directory (LOAD_LIBRARY_SEARCH_APPLICATION_DIR).
  3. Paths explicitly added with the AddDllDirectory function (LOAD_LIBRARY_SEARCH_USER_DIRS) or the SetDllDirectory function. If more than one path has been added, the order in which the paths are searched is unspecified.
  4. The System directory (LOAD_LIBRARY_SEARCH_SYSTEM32).

If the application does not call LoadLibraryEx with any LOAD_LIBRARY_SEARCH flags or establish a DLL search order for the process, the system searches for DLLs using either the standard search order or the alternate search order.

Related topics

AddDllDirectory Application Registration Dynamic-Link Library Redirection Dynamic-Link Library Security LoadLibrary LoadLibraryEx LoadPackagedLibrary SetDefaultDllDirectories SetDllDirectory

Dynamic-Link Library Redirection

Applications can depend on a specific version of a shared DLL and

start to fail if another application is installed with a newer or older version of the same DLL.

There are two ways to ensure that your application uses the correct DLL:

DLL redirection and side-by-side components.

Developers and administrators should use DLL redirection for existing applications,

because it does not require any changes to the application.

If you are creating a new application or updating an application

and want to isolate your application from potential problems, create a side-by-side component.

To use DLL redirection, create a redirection file for your application.

The redirection file must be named as follows: 

App_name.local

For example, if the application name is Editor.exe, the redirection file should be named Editor.exe.local.

You must install the .local file in the application directory.

You must also install the DLLs in the application directory.

The contents of a redirection file are ignored,

but its presence causes Windows to check the application directory first whenever it loads a DLL,

regardless of the path specified to LoadLibrary orLoadLibraryEx.

If the DLL is not found in the application directory, then these functions use their usual search order.

For example, if the application

c:\myapp\myapp.exe

calls LoadLibrary using the following path:

c:\program files\common files\system\mydll.dll

And, if both

c:\myapp\myapp.exe.local and c:\myapp\mydll.dll

exist, LoadLibrary loads c:\myapp\mydll.dll.

Otherwise, LoadLibrary loads c:\program files\common files\system\mydll.dll.

 

Alternatively, if a directory named

c:\myapp\myapp.exe.local

exists and contains mydll.dll, LoadLibrary loads

c:\myapp\myapp.exe.local\mydll.dll

Known DLLs cannot be redirected.

For a list of known DLLs, see the following registry key: 

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs

The system uses Windows File Protection to ensure that system DLLs such as these are not updated or deleted

except by operating system updates such as service packs.

If the application has a manifest, then any .local files are ignored.

If you are using DLL redirection and the application does not have access to all drives and directories in the search order, 

LoadLibrary stops searching as soon as access is denied.

(If you are not using DLL redirection, LoadLibrary skips directories that it cannot access and then continues searching.)

It is good practice to install application DLLs in the same directory that contains the application,

even if you are not using DLL redirection.

This ensures that installing the application does not overwrite other copies of the DLL

and cause other applications to fail.

Also, if you follow this good practice, other applications do not overwrite your copy of the DLL

and cause your application to fail.

Windows 7: Running application using App Paths vs Batch File

I have an (PowerBuilder) application (let's call it MyApp.exe) in a folder with a sub-directory that has all the required dlls.

I am able to run this application, by adding the application path and associated path variable to Windows App Paths registry key.

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\App Paths\MyApp.EXE]
"Path"="C:\\Prog32\\MyAPP;C:\\Prog32\\MyAPP\\DLL\\;"
@="C:\\Prog32\\MyApp\\MyApp.EXE"

 

The above runs file. I didn't even have to register DLLs.

If possible, I would like to run it using a batch file though,

as users may install multiple versions of the same application in separate folders.

When I tried to do the same thing in a batch file, it cannot find the DLLs.

@SETLOCAL
SET CURDIR=%~dp0
CD %CURDIR%
PUSHD %CURDIR%

SET PATH=%CURDIR%;%CURDIR%\dll;%PATH%
start "" %CURDIR%\myApp.exe
POPD

ENDLOCAL

 

 

I created this batch in the same directory as the executable, MyApp.exe.

I was expecting it would find the DLLs, same way App Paths PATH setting did.

The Batch file errors out not being able to find the DLLs.

Do we need to register DLLs in this case?

Why is it treated differently?

Notes:

  1. If I copied all the required DLLs to the same directory as the executable
    (without a DLL sub-directory), it runs fine without needing to worry about PATH or registering dlls.

  2. We used to use installShield to install before, but admins have automated scripts to copy files,
    they shied away from InstallShield programs after the first install.
    I am trying to refine the process, so what they copy will be simplified.

Thanks in advance for all your valuable comments and suggestions.-Sam

Because Windows is a mess when searching for libraries. See

http://msdn.microsoft.com/en-us/library/windows/desktop/ms682586.aspx#search_order_for_desktop_applications

There are many elements to how the search order is determined, but in general it is like this

Check for the library...

  1. already loaded in memory
  2. on the KnownDLL list
  3. in the application's directory
  4. in the System directory
  5. in the 16-bit System directory
  6. in the Windows directory
  7. in the current working directory
  8. in the directories listed in the PATH environment variable

Overall I would agree with what MSDN states on their DLL Redirection page

It is good practice to install application DLLs in the same directory that contains the application

 

However, if using sub-folders is how you want to organize your application, you might take a look into using Application Manifests.

Something else to try would be to set the library directory as the working directory

@ECHO off
SETLOCAL
SET "CURDIR=%~dp0"
PUSHD "%CURDIR%\dll"
start "" /D "%CURDIR%\dll" "%CURDIR%\myApp.exe"
POPD
ENDLOCAL

 

 

Application Registration

This topic discusses how applications can expose information about themselves necessary to enable certain scenarios. This includes information needed to locate the application, the verbs that the application supports and the types of files that an application can handle.

This topic is organized as follows:

 

  • Finding an Application Executable
  • Registering Applications
    • Using the App Paths Subkey
    • Using the Applications Subkey
  • Registering Verbs and Other File Association Information
  • Registering a Perceived Type
  • Related topics

Note  Applications can also be registered in the Set Program Access and Computer Defaults (SPAD) and Set Your Default Programs (SYDP) control panel applications. For information about SPAD and SYDP application registration, see Guidelines for File Associations and Default Programs, and Set Program Access and Computer Defaults (SPAD).

Finding an Application Executable

When the ShellExecuteEx function is called with the name of an executable file in its lpFileparameter, there are several places where the function looks for the file. We recommend registering your application in the App Paths registry subkey. Doing so avoids the need for applications to modify the system PATH environment variable.

The file is sought in the following locations:

  • The current working directory.
  • The Windows directory only (no subdirectories are searched).
  • The Windows\System32 directory.
  • Directories listed in the PATH environment variable.
  • Recommended:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths

Registering Applications

Both the App Paths and Applications registry subkeys are used to register and control the behavior of the system on behalf of applications. The App Paths subkey is the preferred location.

Using the App Paths Subkey

In Windows 7 and later, we strongly recommend you install applications per user rather than per machine. An application that is installed for per user can be registered underHKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\App Paths. An application that is installed for all users of the computer can be registered underHKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\App Paths.

The entries found under App Paths are used primarily for the following purposes:

  • To map an application's executable file name to that file's fully qualified path.
  • To pre-pend information to the PATH environment variable on a per-application, per-process basis.

If the name of a subkey of App Paths matches the file name, the Shell performs two actions:

  • The (Default) entry is used as the file's fully qualified path.
  • The Path entry for that subkey is pre-pended to the PATH environment variable of that process. If this is not required, the Path value can be omitted.

Potential issues to be aware of include:

  • The Shell limits the length of a command line to MAX_PATH * 2 characters. If there are many files listed as registry entries or their paths are long, file names later in the list could be lost as the command line is truncated.
  • Some applications do not accept multiple file names in a command line.
  • Some applications that accept multiple file names do not recognize the format in which the Shell provides them. The Shell provides the parameter list as a quoted string, but some applications might require strings without quotes.
  • Not all items that can be dragged are part of the file system; for example, printers. These items do not have a standard Win32 path, so there is no way to provide a meaningfullpParameters value to ShellExecuteEx.

Using the DropTarget entry avoids these potential issues by providing access to all of the clipboard formats, including CFSTR_SHELLIDLIST (for long file lists) and CFSTR_FILECONTENTS(for non-file-system objects).

To register and control the behavior of your applications with the App Paths subkey:

  1. Add a subkey with the same name as your executable file to the App Paths subkey, as shown in the following registry entry.

     

    HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER
       SOFTWARE
          Microsoft
             Windows
                CurrentVersion
                   App Paths
                      file.exe
                         (Default)
                         DontUseDesktopChangeRouter
                         DropTarget
                         Path
                         UseUrl
  2. See the following table for details of the App Paths subkey entries.
    Registry entryDetails
    (Default)Is the fully qualified path to the application. The application name provided in the (Default) entry can be stated with or without its .exe extension. If necessary, the ShellExecuteExfunction adds the extension when searching App Pathssubkey. The entry is of the REG_SZ type.
    DontUseDesktopChangeRouterIs mandatory for debugger applications to avoid file dialog deadlocks when debugging the Windows Explorer process. Setting the DontUseDesktopChangeRouter entry produces a slightly less efficient handling of the change notifications, however. The entry is of the REG_DWORD type and the value is 0x1.
    DropTargetIs a class identifier (CLSID). The DropTarget entry contains the CLSID of an object (usually a local server rather than an in-process server) that implements IDropTarget. By default, when the drop target is an executable file, and no DropTarget value is provided, the Shell converts the list of dropped files into a command-line parameter and passes it to ShellExecuteEx through lpParameters.
    PathSupplies a string (in the form of a semicolon-separated list of directories) to append to the PATH environment variable when an application is launched by calling ShellExecuteEx. It is the fully qualified path to the .exe. It is of REG_SZ. InWindows 7 and later, the type can be REG_EXPAND_SZ, and is commonly REG_EXPAND_SZ %ProgramFiles%.

    Note  In addition to the (Default), Path, and DropTarget entries recognized by the Shell, an application can also add custom values to its executable file's App Paths subkey. We encourage application developers to use the App Pathssubkey to provide an application-specific path instead of making additions to the global system path.

    UseUrl

    Indicates that your application can accept a URL (instead of a file name) on the command line. Applications that can open documents directly from the internet, like web browsers and media players, should set this entry.

    When the ShellExecuteEx function starts an application and the UseUrl=1 value is not set, ShellExecuteEx downloads the document to a local file and invokes the handler on the local copy.

    For example, if the application has this entry set and a user right-clicks on a file stored on a web server, the Open verb will be made available. If not, the user will have to download the file and open the local copy.

    The UseUrl entry is of REG_DWORD type, and the value is 0x1.

    In Windows Vista and earlier, this entry indicated that the URL should be passed to the application along with a local file name, when called via ShellExecuteEx. In Windows 7, it indicates that the application can understand any http or https url that is passed to it, without having to supply the cache file name as well. The registry key SupportedProtocols contains multiple registry values to indicate which URL schemes are supported.

     

Using the Applications Subkey

Through the inclusion of registry entries under theHKEY_CLASSES_ROOT\Applications\ApplicationName.exe subkey, applications can provide the application-specific information shown in the following table.

Registry entryDescription
shell\verbProvides the verb method for calling the application from OpenWith. Without a verb definition specified here, the system assumes that the application supportsCreateProcess, and passes the file name on the command line. This functionality applies to all the verb methods, including DropTarget, ExecuteCommand, and Dynamic Data Exchange (DDE).
DefaultIconEnables an application to provide a specific icon to represent the application instead of the first icon stored in the .exe file.
FriendlyAppNameProvides a way to get a localizable name to display for an application instead of just the version information appearing, which may not be localizable. The association query ASSOCSTR reads this registry entry value and falls back to use the FileDescription name in the version information. If that name is missing, the association query defaults to the display name of the file. Applications should useASSOCSTR_FRIENDLYAPPNAME to retrieve this information to obtain the proper behavior.
SupportedTypesLists the file types that the application supports. Doing so enables the application to be listed in the cascade menu of the Open with dialog box.
NoOpenWithIndicates that no application is specified for opening this file type. Be aware that if an OpenWithProgIDs subkey has been set for an application by file type, and the ProgID subkey itself does not also have a NoOpenWith entry, that application will appear in the list of recommended or available applications even if it has specified the NoOpenWith entry.

For more information, see How to How to Include an Application in the Open With Dialog Box and How to exclude an Application from the Open with Dialog Box.

IsHostAppIndicates that the process is a host process, such as Rundll32.exe or Dllhost.exe, and should not be considered for Start menu pinning or inclusion in the Most Frequently Used (MFU) list. When launched with a shortcut that contains a non-null argument list or an explicit Application User Model IDs (AppUserModelIDs), the process can be pinned (as that shortcut). Such shortcuts are candidates for inclusion in the MFU list.
NoStartPageIndicates that the application executable and shortcuts should be excluded from the Start menu and from pinning or inclusion in the MFU list. This entry is typically used to exclude system tools, installers and uninstallers, and readme files.
UseExecutableForTaskbarGroupIconCauses the taskbar to use the default icon of this executable if there is no pinnable shortcut for this application, and instead of the icon of the window that was first encountered.
TaskbarGroupIconSpecifies the icon used to override the taskbar icon. The window icon is normally used for the taskbar. Setting the TaskbarGroupIcon entry causes the system to use the icon from the .exe for the application instead.

 

Examples

Some examples of application registrations through theHKEY_CLASSES_ROOT\Applications\ApplicationName.exe subkey are as follows. All registry entry values are of REG_SZ type, with the exception of DefaultIcon which is ofREG_EXPAND_SZ type.

 

HKEY_CLASSES_ROOT
   Applications
      wordpad.exe
         FriendlyAppName = @%SystemRoot%\System32\shell32.dll,-22069

 

HKEY_CLASSES_ROOT
   Applications
      wmplayer.exe
         SupportedTypes
            .3gp2

 

HKEY_CLASSES_ROOT
   Applications
      wmplayer.exe
         DefaultIcon
            (Default) = %SystemRoot%\system32\wmploc.dll,-730

 

HKEY_CLASSES_ROOT
   Applications
      WScript.exe
         NoOpenWith

 

HKEY_CLASSES_ROOT
   Applications
      photoviewer.dll
         shell
            open
               DropTarget
                  Clsid = {FFE2A43C-56B9-4bf5-9A79-CC6D4285608A}

 

HKEY_CLASSES_ROOT
   Applications
      mspaint.exe
         SupportedTypes
            .bmp
            .dib
            .rle
            .jpg
            .jpeg
            .jpe
            .jfif
            .gif
            .emf
            .wmf
            .tif
            .tiff
            .png
            .ico

Registering Verbs and Other File Association Information

Subkeys registered under HKEY_CLASSES_ROOT\SystemFileAssociations enable the Shell to define the default behavior of attributes for file types and enable shared file associations. When users change the default application for a file type, the ProgID of the new default application has priority in providing verbs and other association information. This priority is due to it being the first entry in the association array. If the default program is changed, the information under the previous ProgID is no longer available.

To deal proactively with the consequences of a change to default programs, you can useHKEY_CLASSES_ROOT\SystemFileAssociations to register verbs and other association information. Due to their location after the ProgID in the association array, these registrations are lower priority. These SystemFileAssociationsregistrations are stable even when users change the default programs, and provide a location to register secondary verbs that will always be available for a particular file type. For a registry example, see Registering a Perceived Type later in this topic.

The following registry example shows what happens when the user runs the Default Programsitem in Control Panel to change the default for .mp3 files to App2ProgID. After changing the default, Verb1 is no longer available, and Verb2 becomes the default.

 

HKEY_CLASSES_ROOT
   .mp3
      (Default) = App1ProgID

 

HKEY_CLASSES_ROOT
   App1ProgID
      shell
         Verb1

 

HKEY_CLASSES_ROOT
   App2ProgID
      shell
         Verb2

Registering a Perceived Type

Registry values for perceived types are defined as subkeys of theHKEY_CLASSES_ROOT\SystemFileAssociations registry subkey. For example, the perceived type text is registered as follows:

 

HKEY_CLASSES_ROOT
   SystemFileAssociations
      text
         shell
            edit
               command
                  (Default) = "%SystemRoot%\system32\NOTEPAD.EXE" "%1"
            open
               command
                  (Default) = "%SystemRoot%\system32\NOTEPAD.EXE" "%1"

A file type's perceived type is indicated by including a PerceivedType value in the file type's subkey. The PerceivedType value is set to the name of the perceived type registered underHKEY_CLASSES_ROOT\SystemFileAssociations registry subkey, as shown in the previous registry example. To declare .cpp files as being of perceived type "text", for example, add the following registry entry:

 

HKEY_CLASSES_ROOT
   .cpp
      PerceivedType = text

Related topics

File Types How File Associations Work Content View By File Type or Kind File Type Verifier File Type Handlers Programmatic Identifiers Perceived Types Association Arrays

LoadLibrary unable to load a library even when given a full path

 I tried to load a C++ DLL from a C++ application using LoadLibrary.
 
I gave it the full path but it couldn't find the DLL (and obviously, the DLL is found where I said it is if a person looks for it using Windows Explorer).
 
Eventually, the only way I got my application to find the said DLL was to put the application in the same folder as the DLL.
 
<Rhetorical>
So what's the point of writing the full path then!?
</Rhetorical>
 
How can this happen, and what can I do to solve this problem?
I really would rather not have to put the application in the same folder as the DLL. 

Also, COM DLLs in the same folder as the DLL in question cannot find the DLL either.
I suppose the COM doesn't have a strong enough idea as to where it is located with respect to other modules.

...
HMODULE hmDLL = LoadLibrary(_T("C:\\MyPath\\MyDLL.dll"));
DWORD dwError = 0;
if(NULL == hmDLL)
{
    dwError = GetLastError();
}
// break here and inspect dwError
// -> find out dwError = 0x7e
...

 

After reading the first 4 solutions, here's some information to help you...it has to do with the DLL Search Path [^].
 
As the article says, the typical search order is

1.The directory from which the application loaded.
2.The current directory. 
3.The system directory. Use the GetSystemDirectory function to get the path of this directory. 
4.The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
5.The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
6.The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. 
The App Paths key is not used when computing the DLL search path.

 

So, as you see, it looks in the app directory first, and in your case, didn't find it. Then it looks in the current directory - but still didn't find it, and so on.
 
Since you gave the full path, it probably found your NAMED DLL, but couldn't find the dependency DLLs becuase if follows the DLL Search algorithm.
 
However, if you put your EXE in the DLL directory (not generally a good idea) it finds your DLL and all the dependencies (becuse the directory from which the app loaded contains all the needed DLLs).
 
If you put your dll in the app directory, it finds it, but not the dependent DLLs.
 
Hope this helps you - be sure to read the entire article.

Application Specific Paths for DLL Loading

Configuring workstations to handle shared DLLs is difficult.

In many organizations, the PATH environment becomes a point of contention between project teams.

Configuring a PATH specific to your application can solve the problems associated with using a common search PATH,

and eliminate many configuration errors in your application as well.

This article first describes the current methods of application configuration and the problems associated with them.

Finally, the specific details of adding an application specific path in the registry are described.

The solution is compatible with both NT and '95.

As many of you already know, and as the Visual C++ documentation illustrates,

the operating system will use the following algorithm for locating a DLL. (Load Visual C++ help on LoadLibrary()).

  1. The directory where the executable module for the current process is located.
  2. The current directory.
  3. The Windows system directory. The GetSystemDirectory function retrieves the path of this directory.
  4. The Windows directory. The GetWindowsDirectory function retrieves the path of this directory.
  5. The directories listed in the PATH environment variable. 

Now, imagine the following situation in which two applications (ONE.EXE and TWO.EXE)

need to share a common DLL (COMMON.DLL).

The applications install the files into the following directories.

 

Application 1Application 2
C:\Program Files\ONE\ONE.exeC:\Program Files\TWO\TWO.exe
C:\Program Files\Common\COMMON.DLLC:\Program Files\Common\COMMON.DLL

There are several ways to configure the machine using the above search algorithm.

1) Put all applications into a single directory

Hmm, one big directory. Sounds great until you need to remove one application,

and can't figure out which files to delete. While your at it, why not just make one big .EXE file?

2) Modify the current directory

Faced with the above problems, many programs were configured to be started with the current directory pointing to the DLL.

This is easily set in the short-cut which starts the application.

While this gives each program control of the DLLs that it loads, it also has several side effects:

  1. Any documents written will be written to the DLL location.
  2. File Open dialogs start out in the DLL location.
  3. Programmatically changing the current directory may cause future DLL loads to fail.
  4. It's difficult to control current directory if one program invokes another.
3) Put common files into the Windows or System directory

Many applications store DLLs in the Windows or System directory.

This creates a maintenance problem, particularly if the system files need to be replaced.

Many organizations have begun locking down the Windows and System directories, in an effort to reduce maintenance costs.

4) Modify the PATH environment variable

Certainly the most straight forward approach is to have C:\Program Files\Common added to the path.

This was how things were done in the Win 3.1 days. There are several problems:

  1. If the workstation includes several applications, the PATH becomes incredibly long.
  2. The order in which directories appear on the path becomes important.
  3. The system spends a great deal of time searching directories that are never used by the application.
  4. The program cannot determine which location is used to load a DLL.
  5. Installation programs require re-boots for the path changes to take effect.

Finally, Application Specific Paths!

Microsoft has offered a solution to all these problems.

Each application can now store it own path the registry under the following key:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths

The use the application path, set a key for your application, using ONE.EXE from the example above:

HKEY_LOCAL_MACHINE\...\CurrentVersion\App Paths\ONE.exe

Set the (Default) value to the full path of your executable, for example:

C:\Program Files\ONE\ONE.exe

Add a sub-key named Path, set it's value to the full path of the DLL, for example:

C:\Program Files\Common

With an App Path registry entry, the system will load DLLs in the following order.

  1. The directories listed in the App Path registry key
  2. The directory where the executable module for the current process is located.
  3. The current directory.
  4. The Windows system directory. The GetSystemDirectory function retrieves the path of this directory.
  5. The Windows directory. The GetWindowsDirectory function retrieves the path of this directory.
  6. The directories listed in the PATH environment variable.

Run REGEDIT to see examples of other applications, and how they setup their App Path keys.

 

转载于:https://www.cnblogs.com/shangdawei/p/4056967.html

我正在学习NX二次开发,用的是Visual Studio 2019,ug版本是12.0,开发平台是c++,uf函数为主nxopen函数为辅。需要你辅助我开发,重点注意开发模版是c++,优先使用uf函数,要求你先搞清楚你提供给我的代码真实有效性,语句与标点符号的正确位置,避免出现ug12.0没有提供的接口成员出现!确保所有方法调用都符合 NX12 的 API 签名,深度思考下再回答,每次回答前先回顾下前面的所有对话避免问题重复出现,每行代码都用中文注解具体意思与作用。 //============================================================================== // WARNING!! This file is overwritten by the Block UI Styler while generating // the automation code. Any modifications to this file will be lost after // generating the code again. // // Filename: D:\NXopen\BaiduSyncdisk\studio\qiaowei_tool\ui\qiaowei_tool.cpp // // This file was generated by the NX Block UI Styler // Created by: MICH-ROG // Version: NX 12 // Date: 08-07-2025 (Format: mm-dd-yyyy) // Time: 21:38 (Format: hh-mm) // //============================================================================== //============================================================================== // Purpose: This TEMPLATE file contains C++ source to guide you in the // construction of your Block application dialog. The generation of your // dialog file (.dlx extension) is the first step towards dialog construction // within NX. You must now create a NX Open application that // utilizes this file (.dlx). // // The information in this file provides you with the following: // // 1. Help on how to load and display your Block UI Styler dialog in NX // using APIs provided in NXOpen.BlockStyler namespace // 2. The empty callback methods (stubs) associated with your dialog items // have also been placed in this file. These empty methods have been // created simply to start you along with your coding requirements. // The method name, argument list and possible return values have already // been provided for you. //============================================================================== //------------------------------------------------------------------------------ //These includes are needed for the following template code //------------------------------------------------------------------------------ #include "qiaowei_tool.hpp" using namespace NXOpen; using namespace NXOpen::BlockStyler; //------------------------------------------------------------------------------ // Initialize static variables //------------------------------------------------------------------------------ Session *(qiaowei_tool::theSession) = NULL; UI *(qiaowei_tool::theUI) = NULL; //------------------------------------------------------------------------------ // Constructor for NX Styler class //------------------------------------------------------------------------------ qiaowei_tool::qiaowei_tool() { try { // Initialize the NX Open C++ API environment qiaowei_tool::theSession = NXOpen::Session::GetSession(); qiaowei_tool::theUI = UI::GetUI(); theDlxFileName = "qiaowei_tool.dlx"; theDialog = qiaowei_tool::theUI->CreateDialog(theDlxFileName); // Registration of callback functions theDialog->AddApplyHandler(make_callback(this, &qiaowei_tool::apply_cb)); theDialog->AddOkHandler(make_callback(this, &qiaowei_tool::ok_cb)); theDialog->AddUpdateHandler(make_callback(this, &qiaowei_tool::update_cb)); theDialog->AddInitializeHandler(make_callback(this, &qiaowei_tool::initialize_cb)); theDialog->AddDialogShownHandler(make_callback(this, &qiaowei_tool::dialogShown_cb)); } catch(exception& ex) { //---- Enter your exception handling code here ----- throw; } } //------------------------------------------------------------------------------ // Destructor for NX Styler class //------------------------------------------------------------------------------ qiaowei_tool::~qiaowei_tool() { if (theDialog != NULL) { delete theDialog; theDialog = NULL; } } //------------------------------- DIALOG LAUNCHING --------------------------------- // // Before invoking this application one needs to open any part/empty part in NX // because of the behavior of the blocks. // // Make sure the dlx file is in one of the following locations: // 1.) From where NX session is launched // 2.) $UGII_USER_DIR/application // 3.) For released applications, using UGII_CUSTOM_DIRECTORY_FILE is highly // recommended. This variable is set to a full directory path to a file // containing a list of root directories for all custom applications. // e.g., UGII_CUSTOM_DIRECTORY_FILE=$UGII_BASE_DIR\ugii\menus\custom_dirs.dat // // You can create the dialog using one of the following way: // // 1. USER EXIT // // 1) Create the Shared Library -- Refer "Block UI Styler programmer's guide" // 2) Invoke the Shared Library through File->Execute->NX Open menu. // //------------------------------------------------------------------------------ extern "C" DllExport void ufusr(char *param, int *retcod, int param_len) { qiaowei_tool *theqiaowei_tool = NULL; try { UF_initialize(); //开发的许可函数,初始化 theqiaowei_tool = new qiaowei_tool(); // The following method shows the dialog immediately theqiaowei_tool->Show(); } catch(exception& ex) { //---- Enter your exception handling code here ----- qiaowei_tool::theUI->NXMessageBox()->Show("Block Styler", NXOpen::NXMessageBox::DialogTypeError, ex.what()); } if(theqiaowei_tool != NULL) { delete theqiaowei_tool; theqiaowei_tool = NULL; }UF_terminate(); //释放许可函数,结束化 } //------------------------------------------------------------------------------ // This method specifies how a shared image is unloaded from memory // within NX. This method gives you the capability to unload an // internal NX Open application or user exit from NX. Specify any // one of the three constants as a return value to determine the type // of unload to perform: // // // Immediately : unload the library as soon as the automation program has completed // Explicitly : unload the library from the "Unload Shared Image" dialog // AtTermination : unload the library when the NX session terminates // // // NOTE: A program which associates NX Open applications with the menubar // MUST NOT use this option since it will UNLOAD your NX Open application image // from the menubar. //------------------------------------------------------------------------------ extern "C" DllExport int ufusr_ask_unload() { //return (int)Session::LibraryUnloadOptionExplicitly; return (int)Session::LibraryUnloadOptionImmediately; //return (int)Session::LibraryUnloadOptionAtTermination; } //------------------------------------------------------------------------------ // Following method cleanup any housekeeping chores that may be needed. // This method is automatically called by NX. //------------------------------------------------------------------------------ extern "C" DllExport void ufusr_cleanup(void) { try { //---- Enter your callback code here ----- } catch(exception& ex) { //---- Enter your exception handling code here ----- qiaowei_tool::theUI->NXMessageBox()->Show("Block Styler", NXOpen::NXMessageBox::DialogTypeError, ex.what()); } } int qiaowei_tool::Show() { try { theDialog->Show(); } catch(exception& ex) { //---- Enter your exception handling code here ----- qiaowei_tool::theUI->NXMessageBox()->Show("Block Styler", NXOpen::NXMessageBox::DialogTypeError, ex.what()); } return 0; } //------------------------------------------------------------------------------ //---------------------Block UI Styler Callback Functions-------------------------- //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ //Callback Name: initialize_cb //------------------------------------------------------------------------------ void qiaowei_tool::initialize_cb() { try { group0 = dynamic_cast<NXOpen::BlockStyler::Group*>(theDialog->TopBlock()->FindBlock("group0")); bianjie_edge = dynamic_cast<NXOpen::BlockStyler::CurveCollector*>(theDialog->TopBlock()->FindBlock("bianjie_edge")); chuliao_edge = dynamic_cast<NXOpen::BlockStyler::CurveCollector*>(theDialog->TopBlock()->FindBlock("chuliao_edge")); group = dynamic_cast<NXOpen::BlockStyler::Group*>(theDialog->TopBlock()->FindBlock("group")); expression_clcq = dynamic_cast<NXOpen::BlockStyler::ExpressionBlock*>(theDialog->TopBlock()->FindBlock("expression_clcq")); expression_smh = dynamic_cast<NXOpen::BlockStyler::ExpressionBlock*>(theDialog->TopBlock()->FindBlock("expression_smh")); expression_jlcq = dynamic_cast<NXOpen::BlockStyler::ExpressionBlock*>(theDialog->TopBlock()->FindBlock("expression_jlcq")); expression_dqjiaodu = dynamic_cast<NXOpen::BlockStyler::ExpressionBlock*>(theDialog->TopBlock()->FindBlock("expression_dqjiaodu")); group1 = dynamic_cast<NXOpen::BlockStyler::Group*>(theDialog->TopBlock()->FindBlock("group1")); toggle_daojiao = dynamic_cast<NXOpen::BlockStyler::Toggle*>(theDialog->TopBlock()->FindBlock("toggle_daojiao")); expression_rjiao = dynamic_cast<NXOpen::BlockStyler::ExpressionBlock*>(theDialog->TopBlock()->FindBlock("expression_rjiao")); toggle_pianzhi = dynamic_cast<NXOpen::BlockStyler::Toggle*>(theDialog->TopBlock()->FindBlock("toggle_pianzhi")); expression_pianzhi = dynamic_cast<NXOpen::BlockStyler::ExpressionBlock*>(theDialog->TopBlock()->FindBlock("expression_pianzhi")); vector0 = dynamic_cast<NXOpen::BlockStyler::SpecifyVector*>(theDialog->TopBlock()->FindBlock("vector0")); } catch(exception& ex) { //---- Enter your exception handling code here ----- qiaowei_tool::theUI->NXMessageBox()->Show("Block Styler", NXOpen::NXMessageBox::DialogTypeError, ex.what()); } } //------------------------------------------------------------------------------ //Callback Name: dialogShown_cb //This callback is executed just before the dialog launch. Thus any value set //here will take precedence and dialog will be launched showing that value. //------------------------------------------------------------------------------ void qiaowei_tool::dialogShown_cb() { try { //---- Enter your callback code here ----- } catch(exception& ex) { //---- Enter your exception handling code here ----- qiaowei_tool::theUI->NXMessageBox()->Show("Block Styler", NXOpen::NXMessageBox::DialogTypeError, ex.what()); } } //------------------------------------------------------------------------------ //Callback Name: apply_cb //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ //Callback Name: apply_cb // // 应用按钮回调函数 //------------------------------------------------------------------------------ int qiaowei_tool::apply_cb() { int errorCode = 0; // 错误代码,0表示成功 try { // 获取NX会话和工作部件 NXOpen::Session* theSession = NXOpen::Session::GetSession(); NXOpen::Part* workPart = theSession->Parts()->Work(); NXOpen::UI* theUI = NXOpen::UI::GetUI(); // ===== 1. 获取边界边曲线 ===== std::vector<NXOpen::Curve*> boundaryCurves; if (bianjie_edge) { // 获取曲线选择器属性列表 std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(bianjie_edge->GetProperties()); // 获取选中的对象集合 std::vector<NXOpen::TaggedObject*> selObjs = props->GetTaggedObjectVector("SelectedObjects"); // 遍历选中对象并转换为曲线 for (NXOpen::TaggedObject* obj : selObjs) { if (NXOpen::Curve* curve = dynamic_cast<NXOpen::Curve*>(obj)) { boundaryCurves.push_back(curve); } } } // ===== 2. 获取出料边曲线 ===== std::vector<NXOpen::Curve*> dischargeCurves; if (chuliao_edge) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(chuliao_edge->GetProperties()); std::vector<NXOpen::TaggedObject*> selObjs = props->GetTaggedObjectVector("SelectedObjects"); for (NXOpen::TaggedObject* obj : selObjs) { if (NXOpen::Curve* curve = dynamic_cast<NXOpen::Curve*>(obj)) { dischargeCurves.push_back(curve); } } } // ===== 3. 获取出料沉桥值 ===== double materialThickness = 0.0; if (expression_clcq) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(expression_clcq->GetProperties()); // 获取表达式数值 materialThickness = props->GetDouble("Value"); } // ===== 4. 获取上模厚度值 ===== double scanHeight = 0.0; if (expression_smh) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(expression_smh->GetProperties()); scanHeight = props->GetDouble("Value"); } // ===== 5. 获取进料沉桥值 ===== double clearanceValue = 0.0; if (expression_jlcq) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(expression_jlcq->GetProperties()); clearanceValue = props->GetDouble("Value"); } // ===== 6. 获取倒桥角度值 ===== double currentAngle = 0.0; if (expression_dqjiaodu) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(expression_dqjiaodu->GetProperties()); currentAngle = props->GetDouble("Value"); } // ===== 7. 获取倒角开关状态 ===== bool chamferToggle = false; if (toggle_daojiao) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(toggle_daojiao->GetProperties()); // 获取开关状态(选中/未选中) chamferToggle = props->GetLogical("Value"); } // ===== 8. 获取倒角半径值 ===== double chamferRadius = 0.0; if (expression_rjiao && chamferToggle) // 仅在倒角开启时获取 { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(expression_rjiao->GetProperties()); chamferRadius = props->GetDouble("Value"); } // ===== 9. 获取偏移开关状态 ===== bool offsetToggle = false; if (toggle_pianzhi) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(toggle_pianzhi->GetProperties()); offsetToggle = props->GetLogical("Value"); } // ===== 10. 获取偏移距离值 ===== double offsetDistance = 0.0; if (expression_pianzhi && offsetToggle) // 仅在偏移开启时获取 { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(expression_pianzhi->GetProperties()); offsetDistance = props->GetDouble("Value"); } // ===== 11. 获取矢量方向 ===== NXOpen::Vector3d directionVector(0.0, 0.0, 1.0); // 默认Z轴方向 if (vector0) { std::unique_ptr<NXOpen::BlockStyler::PropertyList> props(vector0->GetProperties()); // 获取用户指定的矢量方向 directionVector = props->GetVector("Vector"); } // ===== 12. 验证必要输入 ===== if (boundaryCurves.size() < 2) { throw std::runtime_error("需要选择两条桥位边界曲线!"); } if (dischargeCurves.empty()) { throw std::runtime_error("出料边曲线未选择!"); } if (scanHeight <= 0) { throw std::runtime_error("上模厚度必须大于0!"); } // ===== 13. 计算两条边界曲线端点间的最短距离并创建两条连接直线 ===== tag_t line1Tag = NULL_TAG; tag_t line2Tag = NULL_TAG; double minDist = 0.0; double remainingDist = 0.0; try { // 获取前两条边界曲线 NXOpen::Curve* curve1 = boundaryCurves[0]; NXOpen::Curve* curve2 = boundaryCurves[1]; // 获取曲线端点 double curve1Start[3] = { 0.0 }, curve1End[3] = { 0.0 }; double curve2Start[3] = { 0.0 }, curve2End[3] = { 0.0 }; // 获取曲线1端点 UF_EVAL_p_t evaluator1 = NULL; if (UF_EVAL_initialize(curve1->Tag(), &evaluator1) != 0) { throw std::runtime_error("无法初始化曲线1的评估器"); } double limits1[2]; if (UF_EVAL_ask_limits(evaluator1, limits1) != 0) { UF_EVAL_free(evaluator1); throw std::runtime_error("无法获取曲线1的参数范围"); } if (limits1[0] > limits1[1]) std::swap(limits1[0], limits1[1]); if (UF_EVAL_evaluate(evaluator1, 0, limits1[0], curve1Start, NULL) != 0 || UF_EVAL_evaluate(evaluator1, 0, limits1[1], curve1End, NULL) != 0) { UF_EVAL_free(evaluator1); throw std::runtime_error("无法评估曲线1的端点"); } UF_EVAL_free(evaluator1); // 获取曲线2端点 UF_EVAL_p_t evaluator2 = NULL; if (UF_EVAL_initialize(curve2->Tag(), &evaluator2) != 0) { throw std::runtime_error("无法初始化曲线2的评估器"); } double limits2[2]; if (UF_EVAL_ask_limits(evaluator2, limits2) != 0) { UF_EVAL_free(evaluator2); throw std::runtime_error("无法获取曲线2的参数范围"); } if (limits2[0] > limits2[1]) std::swap(limits2[0], limits2[1]); if (UF_EVAL_evaluate(evaluator2, 0, limits2[0], curve2Start, NULL) != 0 || UF_EVAL_evaluate(evaluator2, 0, limits2[1], curve2End, NULL) != 0) { UF_EVAL_free(evaluator2); throw std::runtime_error("无法评估曲线2的端点"); } UF_EVAL_free(evaluator2); // 转换为NXOpen点对象 NXOpen::Point3d p1_start(curve1Start[0], curve1Start[1], curve1Start[2]); NXOpen::Point3d p1_end(curve1End[0], curve1End[1], curve1End[2]); NXOpen::Point3d p2_start(curve2Start[0], curve2Start[1], curve2Start[2]); NXOpen::Point3d p2_end(curve2End[0], curve2End[1], curve2End[2]); // 计算两点间距离的函数 auto distance = [](const NXOpen::Point3d& a, const NXOpen::Point3d& b) -> double { return sqrt(pow(a.X - b.X, 2) + pow(a.Y - b.Y, 2) + pow(a.Z - b.Z, 2)); }; // 计算四种可能的端点组合距离 double dist1 = distance(p1_start, p2_start); double dist2 = distance(p1_start, p2_end); double dist3 = distance(p1_end, p2_start); double dist4 = distance(p1_end, p2_end); // 找出最小距离对应的点对 minDist = std::min({ dist1, dist2, dist3, dist4 }); NXOpen::Point3d minPoint1, minPoint2; int minIndex = 0; if (minDist == dist1) { minPoint1 = p1_start; minPoint2 = p2_start; } else if (minDist == dist2) { minPoint1 = p1_start; minPoint2 = p2_end; } else if (minDist == dist3) { minPoint1 = p1_end; minPoint2 = p2_start; } else { minPoint1 = p1_end; minPoint2 = p2_end; } // 确定剩余的两个端点 auto isPointEqual = [](const NXOpen::Point3d& a, const NXOpen::Point3d& b, double tol = 1e-6) -> bool { return (fabs(a.X - b.X) < tol) && (fabs(a.Y - b.Y) < tol) && (fabs(a.Z - b.Z) < tol); }; NXOpen::Point3d remainingPoint1 = isPointEqual(minPoint1, p1_start) ? p1_end : p1_start; NXOpen::Point3d remainingPoint2 = isPointEqual(minPoint2, p2_start) ? p2_end : p2_start; remainingDist = distance(remainingPoint1, remainingPoint2); // ===== 创建两条连接直线 ===== // 创建第一条直线(最短距离连接) UF_CURVE_line_t line1Coords; line1Coords.start_point[0] = minPoint1.X; line1Coords.start_point[1] = minPoint1.Y; line1Coords.start_point[2] = minPoint1.Z; line1Coords.end_point[0] = minPoint2.X; line1Coords.end_point[1] = minPoint2.Y; line1Coords.end_point[2] = minPoint2.Z; if (UF_CURVE_create_line(&line1Coords, &line1Tag) != 0 || line1Tag == NULL_TAG) { throw std::runtime_error("创建最短距离直线失败"); } // 设置第一条直线属性 int workLayer = workPart->Layers()->WorkLayer(); UF_OBJ_set_layer(line1Tag, workLayer); // 创建第二条直线(剩余端点连接) UF_CURVE_line_t line2Coords; line2Coords.start_point[0] = remainingPoint1.X; line2Coords.start_point[1] = remainingPoint1.Y; line2Coords.start_point[2] = remainingPoint1.Z; line2Coords.end_point[0] = remainingPoint2.X; line2Coords.end_point[1] = remainingPoint2.Y; line2Coords.end_point[2] = remainingPoint2.Z; if (UF_CURVE_create_line(&line2Coords, &line2Tag) != 0 || line2Tag == NULL_TAG) { throw std::runtime_error("创建剩余端点直线失败"); } // 设置第二条直线属性 UF_OBJ_set_layer(line2Tag, workLayer); // 更新显示 UF_DISP_refresh(); // 显示成功信息 char msg[256]; snprintf(msg, sizeof(msg), "已创建两条连接直线:\n" "1. 最短距离直线: %.2f mm\n" "2. 剩余端点直线: %.2f mm", minDist, remainingDist); theUI->NXMessageBox()->Show("操作成功", NXOpen::NXMessageBox::DialogTypeInformation, msg); } catch (std::exception& ex) { char errMsg[256]; snprintf(errMsg, sizeof(errMsg), "端点距离计算或直线创建失败: %s", ex.what()); theUI->NXMessageBox()->Show("错误", NXOpen::NXMessageBox::DialogTypeError, errMsg); errorCode = 2; return errorCode; // 提前返回,不再继续后续操作 } // ===== 14. 创建拉伸特征(新建体) ===== try { // 设置撤销标记 NXOpen::Session::UndoMarkId markId = theSession->SetUndoMark( NXOpen::Session::MarkVisibilityVisible, "桥位拉伸"); // 创建拉伸构建器 NXOpen::Features::ExtrudeBuilder* extrudeBuilder = workPart->Features()->CreateExtrudeBuilder(nullptr); // 创建截面 NXOpen::Section* section = workPart->Sections()->CreateSection( 0.001, 0.001, 0.05); extrudeBuilder->SetSection(section); // 准备截面曲线:边界曲线 + 连接直线 std::vector<NXOpen::Curve*> sectionCurves; sectionCurves.push_back(boundaryCurves[0]); sectionCurves.push_back(boundaryCurves[1]); // 将直线标签转换为曲线对象 NXOpen::Curve* line1Curve = dynamic_cast<NXOpen::Curve*>( NXOpen::NXObjectManager::Get(line1Tag)); NXOpen::Curve* line2Curve = dynamic_cast<NXOpen::Curve*>( NXOpen::NXObjectManager::Get(line2Tag)); if (line1Curve) sectionCurves.push_back(line1Curve); if (line2Curve) sectionCurves.push_back(line2Curve); // 创建曲线规则 std::vector<NXOpen::SelectionIntentRule*> rules; if (!sectionCurves.empty()) { NXOpen::SelectionIntentRule* curveRule = workPart->ScRuleFactory()->CreateRuleCurveDumb(sectionCurves); rules.push_back(curveRule); } // 获取帮助点(中点) NXOpen::Point3d helpPoint(0.0, 0.0, 0.0); if (!sectionCurves.empty()) { tag_t curveTag = sectionCurves[0]->Tag(); UF_EVAL_p_t evaluator = NULL; double limits[2]; if (UF_EVAL_initialize(curveTag, &evaluator) == 0) { if (UF_EVAL_ask_limits(evaluator, limits) == 0) { if (limits[0] > limits[1]) std::swap(limits[0], limits[1]); double midParam = (limits[0] + limits[1]) / 2.0; double midPoint[3]; if (UF_EVAL_evaluate(evaluator, 0, midParam, midPoint, NULL) == 0) { helpPoint = NXOpen::Point3d(midPoint[0], midPoint[1], midPoint[2]); } } UF_EVAL_free(evaluator); } } // 添加到截面 section->AddToSection( rules, sectionCurves[0], NULL, NULL, helpPoint, NXOpen::Section::ModeCreate ); // 设置拉伸方向 NXOpen::Point3d origin(0.0, 0.0, 0.0); NXOpen::Direction* extrudeDirection = workPart->Directions()->CreateDirection( origin, directionVector, NXOpen::SmartObject::UpdateOptionWithinModeling ); extrudeBuilder->SetDirection(extrudeDirection); // 设置拉伸范围 NXOpen::GeometricUtilities::Limits* limits = extrudeBuilder->Limits(); limits->StartExtend()->Value()->SetRightHandSide( std::to_string(materialThickness).c_str()); double endDistance = scanHeight - clearanceValue; limits->EndExtend()->Value()->SetRightHandSide( std::to_string(endDistance).c_str()); // ===== 设置布尔操作为新建体 ===== extrudeBuilder->BooleanOperation()->SetType( NXOpen::GeometricUtilities::BooleanOperation::BooleanTypeCreate); // 执行拉伸操作 NXOpen::NXObject* featureNXObject = nullptr; std::vector<NXOpen::Body*> resultBodies; try { // 提交拉伸操作 featureNXObject = extrudeBuilder->Commit(); // 将特征对象转换为Feature类型 NXOpen::Features::Feature* extrudeFeature = dynamic_cast<NXOpen::Features::Feature*>(featureNXObject); if (extrudeFeature) { // 正确获取拉伸创建的实体 resultBodies = extrudeFeature->GetBodies(); } else { throw std::runtime_error("拉伸特征创建失败"); } // 显示结果信息 char successMsg[256]; if (!resultBodies.empty()) { snprintf(successMsg, sizeof(successMsg), "创建新实体成功!\n实体数量: %d\n起始距离: %.2f mm\n结束距离: %.2f mm", resultBodies.size(), materialThickness, endDistance); } else { snprintf(successMsg, sizeof(successMsg), "拉伸操作完成但未创建实体!\n起始距离: %.2f mm\n结束距离: %.2f mm", materialThickness, endDistance); } theUI->NXMessageBox()->Show("操作结果", NXOpen::NXMessageBox::DialogTypeInformation, successMsg); // 清理资源 extrudeBuilder->Destroy(); section->Destroy(); } catch (std::exception& ex) { char errMsg[256]; snprintf(errMsg, sizeof(errMsg), "创建拉伸特征失败: %s", ex.what()); theUI->NXMessageBox()->Show("错误", NXOpen::NXMessageBox::DialogTypeError, errMsg); errorCode = 3; // 特殊错误处理:当布尔操作设置可能冲突时 if (std::string(ex.what()).find("boolean") != std::string::npos) { theUI->NXMessageBox()->Show("布尔操作错误", NXOpen::NXMessageBox::DialogTypeError, "请检查布尔操作设置是否与现有几何冲突"); errorCode = 4; } // 确保资源被清理 if (extrudeBuilder) { extrudeBuilder->Destroy(); } if (section) { section->Destroy(); } } // ===== 最终清理和返回 ===== // 删除临时创建的直线 if (line1Tag != NULL_TAG) { UF_OBJ_delete_object(line1Tag); } if (line2Tag != NULL_TAG) { UF_OBJ_delete_object(line2Tag); } // 刷新显示 UF_DISP_refresh(); return errorCode; } // 注意:这里是apply_cb函数的结束括号 //------------------------------------------------------------------------------ //Callback Name: update_cb //------------------------------------------------------------------------------ int qiaowei_tool::update_cb(NXOpen::BlockStyler::UIBlock* block) { try { if(block == bianjie_edge) { //---------Enter your code here----------- } else if(block == chuliao_edge) { //---------Enter your code here----------- } else if(block == expression_clcq) { //---------Enter your code here----------- } else if(block == expression_smh) { //---------Enter your code here----------- } else if(block == expression_jlcq) { //---------Enter your code here----------- } else if(block == expression_dqjiaodu) { //---------Enter your code here----------- } else if(block == toggle_daojiao) { //---------Enter your code here----------- } else if(block == expression_rjiao) { //---------Enter your code here----------- } else if(block == toggle_pianzhi) { //---------Enter your code here----------- } else if(block == expression_pianzhi) { //---------Enter your code here----------- } else if(block == vector0) { //---------Enter your code here----------- } } catch(exception& ex) { //---- Enter your exception handling code here ----- qiaowei_tool::theUI->NXMessageBox()->Show("Block Styler", NXOpen::NXMessageBox::DialogTypeError, ex.what()); } return 0; } //------------------------------------------------------------------------------ //Callback Name: ok_cb //------------------------------------------------------------------------------ int qiaowei_tool::ok_cb() { int errorCode = 0; try { errorCode = apply_cb(); } catch(exception& ex) { //---- Enter your exception handling code here ----- errorCode = 1; qiaowei_tool::theUI->NXMessageBox()->Show("Block Styler", NXOpen::NXMessageBox::DialogTypeError, ex.what()); } return errorCode; } //------------------------------------------------------------------------------ //Function Name: GetBlockProperties //Description: Returns the propertylist of the specified BlockID //------------------------------------------------------------------------------ PropertyList* qiaowei_tool::GetBlockProperties(const char *blockID) { return theDialog->GetBlockProperties(blockID); } 以上代码报错:严重性 代码 说明 项目 文件 行 禁止显示状态 错误(活动) E0530 try 块至少需要一个处理程序 qiaowei_tool D:\NXopen\BaiduSyncdisk\studio\qiaowei_tool\qiaowei_tool.cpp 694 错误(活动) E0135 class "NXOpen::Features::Feature" 没有成员 "GetBodies" qiaowei_tool D:\NXopen\BaiduSyncdisk\studio\qiaowei_tool\qiaowei_tool.cpp 623 出错部分参考以下帮助文档:#ifndef NXOpen_FEATURES_FEATURE_HXX_INCLUDED #define NXOpen_FEATURES_FEATURE_HXX_INCLUDED //-------------------------------------------------------------------------- // Header for C++ interface to JA API //-------------------------------------------------------------------------- // // Source File: // Features_Feature.ja // // Generated by: // apiwrap // // WARNING: // This file is automatically generated - do not edit by hand // #ifdef _MSC_VER #pragma once #endif #include <NXOpen/NXDeprecation.hxx> #include <vector> #include <NXOpen/NXString.hxx> #include <NXOpen/Callback.hxx> #include <NXOpen/IFitTo.hxx> #include <NXOpen/INXObject.hxx> #include <NXOpen/IProfile.hxx> #include <NXOpen/NXObject.hxx> #include <NXOpen/ugmath.hxx> #include <NXOpen/libnxopencpp_features_exports.hxx> #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable:4996) #endif #ifdef __GNUC__ #pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif namespace NXOpen { namespace Features { class Feature; } namespace Assemblies { class Component; } class BasePart; class Expression; namespace Features { class IContainerFeature; } class IFitTo; class INXObject; class IProfile; class NXColor; class NXObject; class Section; namespace Features { class _FeatureBuilder; class FeatureImpl; /** Represents a feature on a part <br> This is an abstract class, and cannot be instantiated. <br> <br> Created in NX3.0.0. <br> */ class NXOPENCPP_FEATURESEXPORT Feature : public NXOpen::NXObject, public virtual NXOpen::IProfile, public virtual NXOpen::IFitTo { /** Boolean operation type. */ public: enum BooleanType { BooleanTypeCreate/** Create */, BooleanTypeUnite/** Unite */, BooleanTypeSubtract/** Subtract */, BooleanTypeIntersect/** Intersect */, BooleanTypeEmbossNormalSide/** Emboss, keep tool on normal side of sheet */ = 8, BooleanTypeEmbossOppositeNormalSide/** Emboss, keep tool opposite of normal side of sheet */ }; /** Diagnostic type */ public: enum DiagnosticType { DiagnosticTypeInformation/** Information alert */ = 1, DiagnosticTypeWarning/** Warning */ }; private: FeatureImpl * m_feature_impl; private: friend class _FeatureBuilder; protected: Feature(); public: ~Feature(); /** Returns the expressions created by the feature. The order in which expressions are returned is not significant and may change @return <br> Created in NX3.0.0. <br> <br> License requirements : solid_modeling ("SOLIDS MODELING") OR cam_base ("CAM BASE") OR geometric_tol ("GDT") OR insp_programming ("INSPECTION PROGRAMMING") */ public: std::vector<NXOpen::Expression *> GetExpressions ( ); /** Returns the immediate parent features. The order in which parents are returned is not significant and may change @return <br> Created in NX3.0.0. <br> <br> License requirements : solid_modeling ("SOLIDS MODELING") */ public: std::vector<NXOpen::Features::Feature *> GetParents ( ); /** Returns the immediate child features. The order in which children are returned is not significant and may change @return <br> Created in NX3.0.0. <br> <br> License requirements : solid_modeling ("SOLIDS MODELING") OR cam_base ("CAM BASE") OR geometric_tol ("GDT") OR insp_programming ("INSPECTION PROGRAMMING") */ public: std::vector<NXOpen::Features::Feature *> GetChildren ( ); /** Returns all immediate child features. The order in which children are returned is not significant and may change @return <br> Created in NX9.0.1. <br> <br> License requirements : solid_modeling ("SOLIDS MODELING") OR cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: std::vector<NXOpen::Features::Feature *> GetAllChildren ( ); /**Returns the algorithm version of the feature <br> @deprecated Deprecated in NX8.5.0. Algorithm version is for internal use only. There is no replacement for this method. <br> <br> Created in NX3.0.0. <br> <br> License requirements : solid_modeling ("SOLIDS MODELING") OR cam_base ("CAM BASE") OR geometric_tol ("GDT") OR insp_programming ("INSPECTION PROGRAMMING") */ public: NX_DEPRECATED("Deprecated in NX8.5.0. Algorithm version is for internal use only. There is no replacement for this method.") int AlgorithmVersion ( ); /**Returns the location of the feature <br> Created in NX3.0.0. <br> <br> License requirements : solid_modeling ("SOLIDS MODELING") OR cam_base ("CAM BASE") OR insp_programming ("INSPECTION PROGRAMMING") */ public: NXOpen::Point3d Location ( ); /**Returns the timestamp of the feature <br> Created in NX3.0.0. <br> <br> License requirements : None */ public: int Timestamp ( ); /**Returns the feature type <br> Created in NX3.0.0. <br> <br> License requirements : None */ public: NXString FeatureType ( ); /** Highlight the body created by the feature <br> Created in NX3.0.0. <br> <br> License requirements : None */ public: void Highlight ( ); /** Unhighlight the body created by the feature <br> Created in NX3.0.0. <br> <br> License requirements : None */ public: void Unhighlight ( ); /** Make current feature <br> Created in NX3.0.0. <br> <br> License requirements : solid_modeling ("SOLIDS MODELING") OR cam_base ("CAM BASE") OR geometric_tol ("GDT") OR insp_programming ("INSPECTION PROGRAMMING") */ public: void MakeCurrentFeature ( ); /** Show the body created by the feature. The feature curves are to be moved to work layer if the curves are non-selectable when move_curves is true. <br> Created in NX3.0.0. <br> <br> License requirements : solid_modeling ("SOLIDS MODELING") OR cam_base ("CAM BASE") OR geometric_tol ("GDT") OR insp_programming ("INSPECTION PROGRAMMING") */ public: void ShowBody ( bool moveCurves /** move curves */ ); /** Show the body created by the parent feature. The parent curves of feature are to be moved to work layer if the curves are non-selectable when move_curves is true. <br> Created in NX3.0.0. <br> <br> License requirements : solid_modeling ("SOLIDS MODELING") OR cam_base ("CAM BASE") OR geometric_tol ("GDT") OR insp_programming ("INSPECTION PROGRAMMING") */ public: void ShowParents ( bool moveCurves /** move curves */ ); /** Hide the body created by the feature <br> Created in NX3.0.0. <br> <br> License requirements : solid_modeling ("SOLIDS MODELING") OR cam_base ("CAM BASE") OR geometric_tol ("GDT") OR insp_programming ("INSPECTION PROGRAMMING") */ public: void HideBody ( ); /** Hide the body created by the parent feature <br> Created in NX3.0.0. <br> <br> License requirements : solid_modeling ("SOLIDS MODELING") OR cam_base ("CAM BASE") OR geometric_tol ("GDT") OR insp_programming ("INSPECTION PROGRAMMING") */ public: void HideParents ( ); /** Suppress the feature <br> Created in NX3.0.0. <br> <br> License requirements : solid_modeling ("SOLIDS MODELING") OR cam_base ("CAM BASE") OR geometric_tol ("GDT") OR insp_programming ("INSPECTION PROGRAMMING") */ public: void Suppress ( ); /** Unsuppress the feature <br> Created in NX3.0.0. <br> <br> License requirements : solid_modeling ("SOLIDS MODELING") OR cam_base ("CAM BASE") OR geometric_tol ("GDT") OR insp_programming ("INSPECTION PROGRAMMING") */ public: void Unsuppress ( ); /**Returns the suppression status of the feature <br> Created in NX3.0.0. <br> <br> License requirements : None */ public: bool Suppressed ( ); /** Returns the entities created by the feature. The order in which entities are returned is not significant and may change. @return <br> Created in NX4.0.0. <br> <br> License requirements : solid_modeling ("SOLIDS MODELING") OR cam_base ("CAM BASE") OR geometric_tol ("GDT") OR insp_programming ("INSPECTION PROGRAMMING") */ public: std::vector<NXOpen::NXObject *> GetEntities ( ); /** Returns the feature error messages. error_messages can be NULL. The order in which error messags are returned is not significant and may change @return <br> Created in NX5.0.0. <br> <br> License requirements : None */ public: std::vector<NXString> GetFeatureErrorMessages ( ); /** Returns the feature informational messages. info_messages can be NULL. The order in which informational messags are returned is not significant and may change @return <br> Created in NX5.0.0. <br> <br> License requirements : None */ public: std::vector<NXString> GetFeatureInformationalMessages ( ); /** Delete all informational alerts from the features <br> Created in NX5.0.0. <br> <br> License requirements : None */ public: void DeleteInformationalAlerts ( ); /** Delete all warning alerts from the features <br> Created in NX10.0.0. <br> <br> License requirements : None */ public: void DeleteWarningAlerts ( ); /** Returns the feature warning messages. warning_messages can be NULL. The order in which warning messags are returned is not significant and may change @return <br> Created in NX5.0.0. <br> <br> License requirements : None */ public: std::vector<NXString> GetFeatureWarningMessages ( ); /** Returns the feature clue messages. clue_messages can be NULL. The order in which clue messags are returned is not significant and may change @return <br> Created in NX8.0.1. <br> <br> License requirements : None */ public: std::vector<NXString> GetFeatureClueMessages ( ); /** Delete all clue alerts from the features <br> Created in NX8.0.1. <br> <br> License requirements : None */ public: void DeleteClueAlerts ( ); /** Returns both clue and hint messages of the feature. num_clueHint can be NULL. The order in which clue and hint messags are returned is not significant and may change @return <br> Created in NX8.0.1. <br> <br> License requirements : None */ public: std::vector<NXString> GetFeatureClueHintMessages ( ); /** Returns the feature hint messages. hint_messages can be NULL. The order in which hint messags are returned is not significant and may change @return <br> Created in NX8.0.1. <br> <br> License requirements : None */ public: std::vector<NXString> GetFeatureHintMessages ( ); /** Delete all clue alerts from the features <br> Created in NX8.0.1. <br> <br> License requirements : None */ public: void DeleteHintAlerts ( ); /** Make the parent sketch internal if referenced only by this feature. <br> Created in NX5.0.1. <br> <br> License requirements : solid_modeling ("SOLIDS MODELING") OR cam_base ("CAM BASE") OR geometric_tol ("GDT") OR insp_programming ("INSPECTION PROGRAMMING") */ public: void MakeSketchInternal ( ); /** Make the parent sketch external for reuse by other features. <br> Created in NX5.0.1. <br> <br> License requirements : solid_modeling ("SOLIDS MODELING") OR cam_base ("CAM BASE") OR geometric_tol ("GDT") OR insp_programming ("INSPECTION PROGRAMMING") */ public: void MakeSketchExternal ( ); /** Remove all the feature faces before a NoHistory mode edit. <br> Created in NX6.0.0. <br> <br> License requirements : solid_modeling ("SOLIDS MODELING") OR cam_base ("CAM BASE") OR geometric_tol ("GDT") OR insp_programming ("INSPECTION PROGRAMMING") */ public: void RemoveForEdit ( bool dependent /** dependent */ ); /** Remove Local feature parameters in history free mode. <br> Created in NX7.0.0. <br> <br> License requirements : solid_modeling ("SOLIDS MODELING") OR cam_base ("CAM BASE") OR geometric_tol ("GDT") OR insp_programming ("INSPECTION PROGRAMMING") */ public: void RemoveParameters ( ); /**Returns true if the feature is internal. <br> Created in NX6.0.0. <br> <br> License requirements : solid_modeling ("SOLIDS MODELING") OR cam_base ("CAM BASE") OR geometric_tol ("GDT") OR insp_programming ("INSPECTION PROGRAMMING") */ public: bool IsInternal ( ); /** Show all feature dimensions of a feature. <br> Created in NX6.0.0. <br> <br> License requirements : solid_modeling ("SOLIDS MODELING") OR cam_base ("CAM BASE") OR geometric_tol ("GDT") OR insp_programming ("INSPECTION PROGRAMMING") */ public: void ShowDimensions ( ); /** Returns the displayed name of the feature. @return displayed name <br> Created in NX6.0.0. <br> <br> License requirements : None */ public: NXString GetFeatureName ( ); /** Queries a feature for list of its sections. The order in which sections are returned is not significant and may change @return Array of sections <br> Created in NX7.5.0. <br> <br> License requirements : solid_modeling ("SOLIDS MODELING") OR cam_base ("CAM BASE") OR geometric_tol ("GDT") OR insp_programming ("INSPECTION PROGRAMMING") */ public: std::vector<NXOpen::Section *> GetSections ( ); /** Set a feature group as active group. If input is NULL, set no feature group active <br> Created in NX7.5.1. <br> <br> License requirements : solid_modeling ("SOLIDS MODELING") OR cam_base ("CAM BASE") OR geometric_tol ("GDT") OR insp_programming ("INSPECTION PROGRAMMING") */ public: void SetGroupActive ( bool active /** active */ ); /** Log a diagnostic alert for this feature <br> Created in NX8.0.0. <br> <br> License requirements : solid_modeling ("SOLIDS MODELING") OR cam_base ("CAM BASE") OR geometric_tol ("GDT") OR insp_programming ("INSPECTION PROGRAMMING") */ public: void LogDiagnostic ( int errorCode /** errorcode */ , const NXString & message /** message */ , NXOpen::Features::Feature::DiagnosticType diagnosticType /** diagnostictype */ ); /** Log a diagnostic alert for this feature <br> Created in NX8.0.0. <br> <br> License requirements : solid_modeling ("SOLIDS MODELING") OR cam_base ("CAM BASE") OR geometric_tol ("GDT") OR insp_programming ("INSPECTION PROGRAMMING") */ void LogDiagnostic ( int errorCode /** errorcode */ , const char * message /** message */ , NXOpen::Features::Feature::DiagnosticType diagnosticType /** diagnostictype */ ); /**Returns true if the feature is a contained feature. If it is a contained feature, use the property @link NXOpen::Features::Feature::ContainerFeature NXOpen::Features::Feature::ContainerFeature@endlink to get the container feature for this feature. <br> @deprecated Deprecated in NX9.0.0. Use @link NXOpen::Features::Feature::ContainerFeature NXOpen::Features::Feature::ContainerFeature@endlink and check if it is NULL instead. <br> <br> Created in NX8.5.0. <br> <br> License requirements : solid_modeling ("SOLIDS MODELING") OR cam_base ("CAM BASE") OR geometric_tol ("GDT") OR insp_programming ("INSPECTION PROGRAMMING") */ public: NX_DEPRECATED("Deprecated in NX9.0.0. Use NXOpen::Features::Feature::ContainerFeature and check if it is NULL instead.") bool IsContainedFeature ( ); /**Returns the container feature for this feature. Will be set to NULL if this feature is not a contained feature. <br> Created in NX8.5.0. <br> <br> License requirements : solid_modeling ("SOLIDS MODELING") OR cam_base ("CAM BASE") OR geometric_tol ("GDT") OR insp_programming ("INSPECTION PROGRAMMING") */ public: NXOpen::Features::IContainerFeature * ContainerFeature ( ); /** Change Boolean Type <br> Created in NX9.0.0. <br> <br> License requirements : solid_modeling ("SOLIDS MODELING") OR cam_base ("CAM BASE") OR geometric_tol ("GDT") OR insp_programming ("INSPECTION PROGRAMMING") */ public: void ChangeBooleanType ( ); /** The feature color @return <br> Created in NX9.0.1. <br> <br> License requirements : None */ public: NXOpen::NXColor * GetFeatureColor ( ); /** Break Wave Link Feature @return <br> Created in NX11.0.1. <br> <br> License requirements : solid_modeling ("SOLIDS MODELING") OR cam_base ("CAM BASE") OR geometric_tol ("GDT") OR insp_programming ("INSPECTION PROGRAMMING") */ public: bool BreakWaveLink ( ); }; } } #ifdef _MSC_VER #pragma warning(pop) #endif #ifdef __GNUC__ #ifndef NX_NO_GCC_DEPRECATION_WARNINGS #pragma GCC diagnostic warning "-Wdeprecated-declarations" #endif #endif #undef EXPORTLIBRARY #endif
08-09
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值