Проблема Использование UnArc.dll в программе на языке C#

Timick

Старожил
Приветствую!

Возникло тут у меня желание сделать что - то типа инсталлятора на языке C# и тут же возникла проблема (ну как обычно).

Сколько бы я не пытался распаковать какой - бы то ни было архив, появляется просто пустое черное окно программы и, спустя какое - то время, вылетает ошибка -1.
Распаковываю с unarc.dll с помощью примера из самого FreeArc.

Код прилагаю (он стандартный, из примеров).
Source - стандартный код
UnArcTest - мой тестовый проект

P.S.: Архив легко распаковывает arc.exe. Уже скомпилированная программа - пример (так же из самого FreeArc) выдает просто какой - то отчет и все.

Заранее спасибо!)
 

Вложения

Avengerz13

Участник
@Timick, не разбирал исходный код unarc.dll и чем она отличается от взятой с ISDone 0.6, последний доработанный/исправленный получается. Независимый запуск функций выдавал аналогичный пустой результат, проблема получается не в .NET
Код:
RUNDLL32.EXE unarc.dll,FreeArcExtract x test.arc
Замена unarc.dll от ISDone 0.6 помогло решить проблему.
Дополнительно в коде при импорте лучше указать точку входа наименовании функций.
C#:
[DllImport("unarc.dll", EntryPoint = "FreeArcExtract", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
Вложениях добавил доработанный пример проекта.
 

Вложения

Timick

Старожил
@Avengerz13, спасибо за помощь и проведенное тестирование!
Теперь хотя бы есть от чего оттолкнуться)
 

sergey3695

Ветеран
Модератор
Я так подключаю
C++:
#include <windows.h>
#include <Strsafe.h>

#define call __stdcall

// Loads function from a unarc.dll
FARPROC LoadFromDLL(char *funcname)
{
    static HMODULE unarc_dll = 0;
    WCHAR path[MAX_PATH];
    GetCurrentDirectory(MAX_PATH, path);
    StringCchCat(path, MAX_PATH, L"\\unarc.dll");
    if (!unarc_dll)
       unarc_dll = LoadLibraryEx(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
    return GetProcAddress(unarc_dll, funcname);
}

typedef int Number;
typedef int __stdcall cbtype(char *what, Number int1, Number int2, char *str);

int __stdcall callback(char *what, Number int1, Number int2, char *str)
{
/*    if (strequ(what, "password?"))
    {
        printf("Enter password:"); gets(str);
    }

    printf("callback(\"%s\", %d, %d, \"%s\")\n", what, int1, int2, str);
    if (strequ(what, "password?"))
        return 'y';
    else if (strequ(what, "overwrite?"))
        return 'y';
    else
        return 1;
*/
}

void call ISArcExtract()
{
    // Load function from unarc.dll
    int(*FreeArcExtract) (cbtype *callback, ...) = (int(*) (cbtype *callback, ...)) LoadFromDLL("FreeArcExtract");
    if (!FreeArcExtract) { MessageBox(NULL, TEXT("PZDC!"), TEXT(""), MB_OK); }
}
не c# конечно, но вдруг надо.
с помощью примера из самого FreeArc
там еще надо дописывать, где dll. если в системной папке unarc не лежит, то работать естественно не будет.
 

sergey3695

Ветеран
Модератор
Вот пример c получением пути dll. Проверил в inno dll, функционал unarc.dll читает. Чудеса какие-то )
shlwapi.lib добавить в проект надо будет. (shlwapi.lib;%(AdditionalDependencies))
C++:
#include <windows.h>
#include <strsafe.h>
#include <shlwapi.h>

WCHAR path[MAX_PATH];

// Loads function from a unarc.dll
FARPROC LoadFromDLL(char *funcname)
{
    static HMODULE unarc_dll = 0;
    MessageBox(NULL, path, TEXT(""), MB_OK);
    if (!unarc_dll)
        unarc_dll = LoadLibraryEx(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
    return GetProcAddress(unarc_dll, funcname);
}

typedef int Number;
typedef int __stdcall cbtype(char *what, Number int1, Number int2, char *str);

int __stdcall callback(char *what, Number int1, Number int2, char *str)
{
    /*    if (strequ(what, "password?"))
    {
    printf("Enter password:"); gets(str);
    }

    printf("callback(\"%s\", %d, %d, \"%s\")\n", what, int1, int2, str);
    if (strequ(what, "password?"))
    return 'y';
    else if (strequ(what, "overwrite?"))
    return 'y';
    else
    return 1;
    */
}

void call ISArcExtract()
{
    // Load function from unarc.dll
    int(*FreeArcExtract) (cbtype *callback, ...) = (int(*) (cbtype *callback, ...)) LoadFromDLL("FreeArcExtract");
    if (!FreeArcExtract) { MessageBox(NULL, TEXT("PZDC!"), TEXT(""), MB_OK); }
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
    switch (fdwReason)
    {
    case DLL_PROCESS_ATTACH:
    {
        GetModuleFileName(hinstDLL, path, MAX_PATH);
        PathRemoveFileSpec(path);
        StringCchCat(path, MAX_PATH, L"\\unarc.dll");
        break;
    }

    case DLL_THREAD_ATTACH:
        break;

    case DLL_THREAD_DETACH:
        break;

    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}
 

Masquerade

Новичок
Приношу свои извинения за то, что откопал такую древнюю тему!

Я сейчас занимаюсь тем, что пытаюсь заставить FreeArc работать на C#.

Мой вопрос в том, возможно ли, чтобы UNARC.DLL запускался и его прогресс отображался в индикаторе выполнения? Мое понимание в этой области в лучшем случае ограничено. Если это невозможно с UNARC.DLL, то возможно ли это с UNARC.EXE? Спасибо!

Я также планирую включить текущий извлеченный файл в текстовое поле, но это достаточно легко сделать, поэтому мне не нужна помощь здесь.

Переведено с помощью www.DeepL.com/Translator (бесплатная версия)
 
Сверху