2012-02-06 4 views
1

Я не знаю, как это объяснить, но я попробую. Вот что я использую:Как получить текущий путь сборки сборки

C++:

extern "C" __declspec(dllexport) void c(char path[]) 
{ 
    //some code with the path. 
}  

C#:

[DllImport("DLL")] 
static extern void c(char[] path); 

Как вы можете видеть, что я использую экспортируемую функцию из C++. Мой вопрос: есть ли более простой способ получить путь к приложению из DLL, не передавая его как параметр экспортируемой функции?

+1

'Path.GetDirectoryName (Assembly.GetExecutingAssembly(). Location)' Я не вижу, как ваш код P/Invoke вообще связан с тем, что вы просите ... – ildjarn

+0

Вы спрашиваете, как получить вызов исполняемого каталога управляемой сборки из функции C++, вызванной C++? – Cameron

+0

@ildjarn Я хочу получить путь от родной dll, я уже могу это сделать, но я спрашиваю, есть ли более простой способ без необходимости передавать параметр. – method

ответ

1

Это очень легко, но требует некоторой предусмотрительности:

Первое, что нужно сделать, это осуществить в более DllMain родной DLL, которая будет кэшировать дескриптор модуля при загрузке DLL. Это выглядит следующим образом:

EXTERN_C BOOL WINAPI DllMain(_In_ HINSTANCE hinstDLL, _In_ DWORD fdwReason, _In_opt_ LPVOID lpvReserved) 
{ 
    UNREFERENCED_PARAMETER(lpvReserved); 

    if (fdwReason == DLL_PROCESS_ATTACH) 
    { 
     DisableThreadLibraryCalls(hinstDLL); 

     g_Handle = hinstDLL; 
    } 

    return TRUE; 
} 

Позже, когда вы хотите, чтобы получить имя, просто позвоните GetModuleFileName, например, так:

TCHAR dllName[MAX_PATH + 1]; 
GetModuleFileName(g_Handle, dllName, MAX_PATH); 

Единственная сложная часть, если вы хотите назвать это, что, хранящую ручку от DllMain. Вызов GetModuleHandle(NULL) даст вам исполняемый модуль, а не DLL (такой же, как GetExecutingAssembly в C#).

+0

Я получаю эту ошибку: '' g_Handle ': uneclared identifier', есть что-то не хватает, я должен объявить? – method

+1

Вам нужен HINSTANCE (или HMODULE), называемый g_Handle, или что-нибудь еще, что вам нравится. Это просто глобальная переменная, доступ к которой могут получить функции DllMain и более поздние. – ssube

0

Путь для отдельного приложения и службы Windows (но не для веб-сайтов):

AppDomain.CurrentDomain.BaseDirectory 
+0

Вы ошиблись, я хочу получить путь из родной DLL. – method

2

@peachykeen (у кого есть отличное название) прямо с предложением GetModuleFileName. Трюк для получения пути EXE должен передать NULL в качестве параметра hModule.

Из MSDN:

HMODULE [в, по выбору] Дескриптор загруженного модуля, путь которого запрашивается. Если этот параметр равен NULL, GetModuleFileName возвращает путь к исполняемому файлу текущего процесса.

+0

Интересно, что это вернет, когда исполняемый файл является сборкой .Net, а DLL является родной. Я подозреваю, что это будет путь сборки .Net, так как это отображается в проводнике процессов, но никогда не пробовал. – ssube

+0

Да, он вернул путь сборки, если я передал null вместо g_Handle. Спасибо вам всем. – method

Смежные вопросы