Переписать исходник из DLL в EXE

Автор pr0100, 04.05.21, 08:29:27

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

pr0100

Добрый день, помогите переписать исходник из справки ПОЛИНОМА в компилируемое приложение.
Дело все в том, что я не могу скомпилированный пример подключить к компасу, так-как нет прав на компас администратора...
Но запустить exeшник написанный на шарпе типо "привет компас" могу...


Пример вставки на C#

using Kompas6API5;
using System;
using Microsoft.Win32;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Runtime.Versioning;
using stdole;
using System.Text;

namespace Steps.NET
{
// Класс Step1 - Самая простая библиотека на C#
  [ClassInterface(ClassInterfaceType.AutoDual)]
public class InsertPL
{
// Имя библиотеки
[return: MarshalAs(UnmanagedType.BStr)] public string GetLibraryName()
{
return "Вставка СИ из Polynom";
}

//Создаем описание экспортируемых функций из plclient_kompas.dll
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
private delegate void _PLInsertByLocation3D([Out] out IDispatch retVal, byte[] location, ksPlacement aPlacement);

[UnmanagedFunctionPointer(CallingConvention.StdCall)]
private delegate void _PLConnect(byte[] connectionString, bool isWindowsAuthorization, byte[] userName, byte[] password);

[UnmanagedFunctionPointer(CallingConvention.StdCall)]
private delegate void _PLDisconnect();


//Создаем описание экспортируемых функций из kernel32.dll
const string _KERNEL32 = "kernel32.dll";
[DllImport(_KERNEL32, CharSet = CharSet.Unicode, SetLastError = true)]
[ResourceExposure(ResourceScope.Process)]
public static extern IntPtr LoadLibrary(string libFilename);
[DllImport(_KERNEL32, CharSet = CharSet.Ansi, BestFitMapping = false, ThrowOnUnmappableChar = true)]
static internal extern IntPtr GetProcAddress(IntPtr HModule, [MarshalAs(UnmanagedType.LPStr), In] string funcName/*lpcstr*/);

[DllImport(_KERNEL32, CharSet = CharSet.Unicode, SetLastError = true)]
[ResourceExposure(ResourceScope.Process)]
public static extern bool FreeLibrary(IntPtr hModule);

//Меняем кодировку строки
public static byte[] GetBytesFromStringWithZero(Encoding encoding, string str)
{
int len = encoding.GetByteCount(str);
byte[] bytes = new byte[len + encoding.GetByteCount("\0")];
encoding.GetBytes(str, 0, str.Length, bytes, 0);
return bytes;
}

// Головная функция библиотеки
public void ExternalRunCommand([In] short command, [In] short mode, [In, MarshalAs(UnmanagedType.IDispatch)] object kompas_)
{
KompasObject kompas = (KompasObject) kompas_;
//Указываем путь к экземпляру plclient_kompas.dll который должен загружаться в Компас.
const string _DLLPATH = "D:\\source\\rdm\\Build\\Debug\\x64\\plclient_kompas.dll";
IntPtr pDll = IntPtr.Zero;
pDll = LoadLibrary(_DLLPATH);

if (pDll == IntPtr.Zero)
throw new Exception("Не могу найти plclient_kompas.dll");

var _connectFunc = GetProcAddress(pDll, "PLConnect");
var connectFunc = (_PLConnect)Marshal.GetDelegateForFunctionPointer(_connectFunc, typeof(_PLConnect));

var _disconnectFunc = GetProcAddress(pDll, "PLDisconnect");
var disconnectFunc = (_PLDisconnect)Marshal.GetDelegateForFunctionPointer(_disconnectFunc, typeof(_PLDisconnect));

var _PLInsert3D = GetProcAddress(pDll, "PLInsertByLocation3D");
var PLInsert3D = (_PLInsertByLocation3D)Marshal.GetDelegateForFunctionPointer(_PLInsert3D, typeof(_PLInsertByLocation3D));

var username = "admin";
var pass = "111";
var ConnectionString = @"Server=10.44.0.169;Database=PolynomBase;Storage=Develop;User ID=admin;Password=111;Persist Security Info=False;";

connectFunc(GetBytesFromStringWithZero(Encoding.Unicode, ConnectionString), false, GetBytesFromStringWithZero(Encoding.Unicode, username), GetBytesFromStringWithZero(Encoding.Unicode, pass));

IDispatch kPart;
const string id = "SHORTLOC:B46A_2A75D01A8C354E59[6;4;4,5;15;63;Сталь 15ГС ТУ 14-3-420-75]";

PLInsert3D(out kPart, GetBytesFromStringWithZero(Encoding.Unicode, id), null);

disconnectFunc();

}


#region COM Registration
// Эта функция выполняется при регистрации класса для COM
// Она добавляет в ветку реестра компонента раздел Kompas_Library,
// который сигнализирует о том, что класс является приложением Компас,
// а также заменяет имя InprocServer32 на полное, с указанием пути.
// Все это делается для того, чтобы иметь возможность подключить
// библиотеку на вкладке ActiveX.
[ComRegisterFunction]
public static void RegisterKompasLib(Type t)
{
try
{
RegistryKey regKey = Registry.LocalMachine;
string keyName = @"SOFTWARE\Classes\CLSID\{" + t.GUID.ToString() + "}";
regKey = regKey.OpenSubKey(keyName, true);
regKey.CreateSubKey("Kompas_Library");
regKey = regKey.OpenSubKey("InprocServer32", true);
regKey.SetValue(null, System.Environment.GetFolderPath(Environment.SpecialFolder.System) + @"\mscoree.dll");
regKey.Close();
}
catch (Exception ex)
{
MessageBox.Show(string.Format("При регистрации класса для COM-Interop произошла ошибка:\n{0}", ex));
}
}

// Эта функция удаляет раздел Kompas_Library из реестра
[ComUnregisterFunction]
public static void UnregisterKompasLib(Type t)
{
RegistryKey regKey = Registry.LocalMachine;
string keyName = @"SOFTWARE\Classes\CLSID\{" + t.GUID.ToString() + "}";
RegistryKey subKey = regKey.OpenSubKey(keyName, true);
subKey.DeleteSubKey("Kompas_Library");
subKey.Close();
}
#endregion
}
}

Alexander982

Можно попробовать добавить следующий метод

public static void Main(){
  #if __LIGHT_VERSION__
Type t = Type.GetTypeFromProgID("KOMPASLT.Application.5");
  #else
Type t = Type.GetTypeFromProgID("KOMPAS.Application.5");
  #endif
  kompas = (KompasObject)Activator.CreateInstance(t);
  ExternalRunCommand(0, 0, kompas);
}

Если проблемы с ExternalRunCommand то вместо нее здесь вставить код который внутри этого метода. И надо собрать проект как исполняемый файл.

KilkennyCat

"И надо собрать проект как исполняемый файл." - И что это даст? Что исполнятся-то будет, точки входа main нет.

Alexander982


pr0100

Добился от наших администраторов права на мой рабочий ПК. Компилирую dll все работает. Опытным путем добавил в код несколько строк
connectFunc(GetBytesFromStringWithZero(Encoding.Unicode, ConnectionString), true, GetBytesFromStringWithZero(Encoding.Unicode, username), GetBytesFromStringWithZero(Encoding.Unicode, pass));IDispatch kPart;//const string id = "SHORTLOC:Root±30±20±10±80±10±©{}20[9;Цинковое, хроматированное;Сталь 20 ГОСТ 1050-2013;1,5;10]";//const string id ="PART:68143c47-2d0a-2fe9-3da8-4bab1f35d8cc";const string id = "BOSimple***PART:c67ab3d4-6a98-40e1-b947-abe600f5270e";PLInsert3D(out kPart, GetBytesFromStringWithZero(Encoding.Unicode, id), null);const string id1 = "BOSimple***PART:16428a09-f949-4371-ac23-acef00a27eb1";PLInsert3D(out kPart, GetBytesFromStringWithZero(Encoding.Unicode, id1), null);disconnectFunc();

Как можно прочитать какоq-то текстовый файл. Запустить цикл в PLInsert3D, считывая построчно данные с файла.
чтобы не создавать переменную id1, id2 и т.д.

pr0100

Добился от наших администраторов права на мой рабочий ПК. Компилирую dll все работает. Опытным путем добавил в код несколько строк
connectFunc(GetBytesFromStringWithZero(Encoding.Unicode, ConnectionString), true, GetBytesFromStringWithZero(Encoding.Unicode, username), GetBytesFromStringWithZero(Encoding.Unicode, pass));
IDispatch kPart;
const string id = "SHORTLOC:Root±30±20±10±80±10±©{}20[9;Цинковое, хроматированное;Сталь 20 ГОСТ 1050-2013;1,5;10]";
const string id ="PART:68143c47-2d0a-2fe9-3da8-4bab1f35d8cc";
const string id = "BOSimple***PART:c67ab3d4-6a98-40e1-b947-abe600f5270e";
PLInsert3D(out kPart, GetBytesFromStringWithZero(Encoding.Unicode, id), null);
const string id1 = "BOSimple***PART:16428a09-f949-4371-ac23-acef00a27eb1";
PLInsert3D(out kPart, GetBytesFromStringWithZero(Encoding.Unicode, id1), null);[/code]
disconnectFunc();[/code]


Как можно прочитать какой-то текстовый файл. Запустить цикл в PLInsert3D, считывая построчно данные с файла.
чтобы не создавать переменную id1, id2 и т.д.

KilkennyCat

Цитата: Alexander982 от 29.05.21, 16:47:28Внимательнее читаем)
М-да.... ну я и смаразматил! )

[/quote]
Цитата: pr0100 от 10.06.21, 09:27:38Как можно прочитать какой-то текстовый файл. Запустить цикл в PLInsert3D, считывая построчно данные с файла.
Ну, это общий вопрос работы в C#, к Компасу не имеет отношения...
Например: https://docs.microsoft.com/ru-ru/troubleshoot/dotnet/csharp/read-write-text-file

DmitriyLvov

Добрый день,

Подскажите, при вызове функции "connectFunc" появляется следующая ошибка:
"Попытка чтения или записи в защищенную память. Это часто свидетельствует о том, что другая память повреждена".

Не зависит от того, что указано в строке подключения. С чем это может быть связано?