Книга знаний

1С:Предприятие

Кислотно-щелочной баланс или сбор информации об окружении

Тема нашей последней лекции - кислотно-щелочной баланс, или среда в которой мы живем. Согласитесь иногда полезно знать то, что нас окружает, точнее не нас, а разработанные нами конфигурации, внешние отчеты и обработки. Да и заодно вывернуть пятки, типа круты мы не по-детски и в рот нам килограмм печенья. А помогать выворачивать пятки и кушать печенье буду я, Guk, mszsuz, Ковычки. Если кого не упомянул, не обессудьте. Склероз под старость совсем извел. ;))Автор статьи: skunk | Редакторы: Волшебник
Последняя редакция №6 от 23.01.06 | История
URL: http://kb.mista.ru/article.php?id=66

Что за имя у меня?


Пожалуй, самая трудная часть нашего фокуса. Начнем, наверное, с него. Будем определять имя стартовой программы 1С. Ибо в имени этом много вкусного. Но ребятишки из всеми любимой нами фирмы забыли воткнуть в язык один Си данную функцию. И если с определением пути, откуда стартанула система траблов нет, то с именем возникает лажа. Сейчас я вам покажу, как устранить эту лажу в 1С.

Сперва я, как последний Левка Баранов, определял имя программы путем поиска первого файла, удовлетворяющего маске «1Cv7*.exe». Что было не очень гуд, так как, тот же Левка, мог записать в рабочую папку 1С два разных файла 1Cv7s.exe и 1Cv7l.exe, просто от не фих делать. И мы получали грабли. Найденный файл мог оказаться совсем не тем, который был нужен нам. Конечно ситуация довольно редкая, я в реале столкнулся только когда готовил данный материал. Но кто знает, где оно летает. Не правда ли? И тут на помощь пришел человек, единственное, что о нем знаю, так это его никнэйм Ковычки. Он показал, как получить PID процесса запущенного 1С, но и заодно имя программы, породившее данный процесс. PID в данном случае нам не нужен. А вот определять имя будем его способом, и только в крайнем случае, тылкнемя к поиску по маске. Вот весь код функции:

//*******************************************
function vlFileName()
    Answer = createobject("valuelist");
    strPathFile = upper(bindir());
    Answer.AddValue(strPathFile, "Path");
    oleWSH = createobject("WScript.Shell");
    objExec = oleWSH.Exec("rundll32.exe kernel32,SleepEx");
    oleLocator = createobject("WbemScripting.SWbemLocator");
    objService = oleLocator.ConnectServer();
    strProcID = objService.Get("Win32_Process.Handle=" + objExec.ProcessID).ParentProcessID;
    objExec.Terminate();
    strNameFile = upper(objService.Get("Win32_Process.Handle=" + strProcID).ExecutablePath);
    strNameFile = strreplace(strNameFile, strPathFile, "");
    Answer.AddValue(strNameFile, "Name");
    return Answer;
endfunction


Данная функция вернет список значений, состоящий из двух значений. У которого с представлением «Name» будет значение имени файла 1С. Ну, а под представлением «Path», будет находиться значение пути до данного файла.


Что в имени моем тебе надо?


Имя самой стартовой программы нам нужно, что бы знать за проперти. А для чего они нам нужны. Ясно для чего, чтобы что-то килишить. Один раз я это заюзал в троянчике, впаривая его лоху сказал, что данная обработка сосет патчи с обновлениями для эсины. Так же свойства имею для определения имени OLE сервера 1С. Ну а версию или релиз надо проверять, если используете в обработке какие-нибудь не документированные фичи. Короче глядим на проперти:

//*******************************************
function vlProperty(File = "", Path = "")
    Answer = createobject("valuelist");
    if fs.ExistFile(Path + File) = 0 then
        Answer.AddValue("хорошо подумал... свойства чего ты хочешь получить", "error");
    else
        oleShell = createobject("Shell.Application");
        objFolder = oleShell.NameSpace(Path);
        objFile = objFolder.ParseName(File);
        strPlatform = objFolder.GetDetailsOf(objFile, 31);
        if find(strPlatform, "for SQL") > 0 then
            Answer.AddValue("for SQL", "Platform");
            Answer.AddValue("V77S.Application", "NameOLEServer");
        elsif find(strPlatform, "multi-user") > 0 then
            Answer.AddValue("многопользовательская", "Platform");
            Answer.AddValue("V77.Application", "NameOLEServer");
        elsif find(strPlatform, "single-user") > 0 then
            Answer.AddValue("однопользовательская", "Platform");
            Answer.AddValue("V77L.Application", "NameOLEServer");
        else
            Answer.AddValue("какой то странный файл", "error");
        endif;
        strVersion = objFolder.GetDetailsOf(objFile, 32);
        if strcountoccur(strVersion, ".") = 3 then
            strVersion = strreplace(strVersion, ".", ",");
            vlTMP = createobject("valuelist");
            vlTMP.FromSeparatedString(strVersion);
            Answer.AddValue(string(vlTMP.GetValue(1)) + "." + string(vlTMP.GetValue(2)), "Version");
            Answer.AddValue(string(vlTMP.GetValue(4)), "Release");

        else
            Answer.AddValue(strVersion, "Version");
        endif;

    endif;
    return Answer;
endfunction


Как видно из примера данная функция тоже возвращает список значений. Правда вот только количество значений в ней плавает. Все зависит от той или иной ситуации. Если есть значение с представлением «error», то во время попытки определения пропертей возникли траблы. Если для вас это будет не критично, то продолжайте работу, нет валить клозетом обработку на фих. Если все гуд, то функция вернет четыре значения: «Platform» - тип платформы 1С, «NameOLEServer» - имя сервера автоматизации 1С, «Version» - версию исполняемого файла и «Release» - его релиз.


Компоненты.


Итак дошли до компонентов 1С. Все знают, что это такое. Правда, не все знают, с чем их едят. Я, например, не знаю, зачем определять их присутствие. Но кое-кто попросил, пришлось сделать. Может и вам на что-нибудь сгодиться. Смотрим код:

//*******************************************
function vlGetComponent()
    Answer = createobject("valuelist");
    Path = bindir();
    oleShell = createobject("Shell.Application");
    objFolder = oleShell.NameSpace(Path);
    if fs.ExistFile(Path + "Account.dll") > 0  then
        objFile = objFolder.ParseName("Account.dll");
        if find(lower(objFolder.GetDetailsOf(objFile, 31)), "accounting") > 0 then
            Answer.AddValue(1, "Account");
        endif;
    endif;
    if fs.ExistFile(Path + "DistrDB.dll") > 0  then
        objFile = objFolder.ParseName("DistrDB.dll");
        if find(lower(objFolder.GetDetailsOf(objFile, 31)), "distrdbd") > 0 then
            Answer.AddValue(1, "DistrDB");
        endif;
    endif;
    if fs.ExistFile(Path + "Salary.dll") > 0  then
        objFile = objFolder.ParseName("Salary.dll");
        if find(lower(objFolder.GetDetailsOf(objFile, 31)), "salary") > 0 then
            Answer.AddValue(1, "Salary");
        endif;
    endif;
    if fs.ExistFile(Path + "Trade.dll") > 0  then
        objFile = objFolder.ParseName("Trade.dll");
        if find(lower(objFolder.GetDetailsOf(objFile, 31)), "trade") > 0 then
            Answer.AddValue(1, "Trade");
        endif;
    endif;
    return Answer;
endfunction


Опять получаем список из неизвестного числа значений. Смотрим, если есть представление «Account» - значиться есть бух учет, есть «DistrDB» - имеем УРИБ, есть «Salary» - работает зарплата, ну и если есть «Trade» - можно работать с регистрами.


Что у нас за «база»?


Эта фича в наглую закоммуниздина мною, у Gukа. Функция просто возвращает строку, в которой указан тип информационной базы. Короче смотрим, все по-русски:

//*******************************************
function strTypeIB()
    if fs.ExistFile(ibdir() + "1Cv7.dd") > 0 then
        Answer = "DBF";
    else
        Answer = "SQL";
    endif;
    return Answer;
endfunction



Что у нас еще имеется?


Иногда, бывает полезным знать какие базы еще зарегистрированны в компьютере. Например, при работе с OLE. Для этого мы воспользуемся функцией, которую любезно обнародовал всеми уважаемый mszsuz. Я просто взял на себя немного труда и внес небольшие изменения. Изменив код так, что он теперь возвращает список значений, где в качестве представления выступает представление информационной базы на компьютере, а в качестве значения – путь до базы.

//*******************************************
function vlGetListBase()
    try
        oleShell = createobject("MSScriptControl.ScriptControl");
        oleShell.Language = "VBScript";
        lstCode = 
        "function strGetListBase()
        |  const RootKey = &H80000001
        |  set Reg = GetObject(""winmgmts:{impersonationLevel=impersonate}!\\."" &_
        |                      ""\root\default:StdRegProv"")
        |  PathKey = ""Software\1C\1Cv7\7.7\Titles""
        |  Reg.EnumValues RootKey, PathKey, Arr
        |  Answer = ""{""""СписокЗначений"""",{""
        |  for x = LBound(Arr) to UBound(Arr)
        |    call Reg.GetStringValue(RootKey, PathKey, Arr(x), Value)
        |    Answer = Answer & ""{{""""Строка"""","""""" &_
        |             Arr(x) & """"""},"""""" & replace(Value, """""""", """""""""""") &_
        |             """""",""""0""""}""
        |    if x <> UBound(Arr) then Answer = Answer & "",""
        |  next
        |  Answer = Answer & ""}}""
        |  strGetListBase = Answer
        |end function";
        oleShell.AddCode(lstCode);
        Answer = valuefromstring(oleShell.Run("strGetListBase"));
        Answer.SortByPresent();
    except
        Answer = createobject("valuelist");
        Answer.AddValue("что-то не получилось", "error");
    endtry;
    return Answer;
endfunction



Десерт.


Ну и на закуску. Небольшая фича основанная на проверке файла <ПутьДоБазы\UsrDEF\Users.USR>. Его наличие дает нам все основания предполагать, что для подключения к данной базе требуется авторизация. Для Львов Барановых, чтобы начать работать с данной базой, требуется ввести логин и пассворд. Сама функция проста, как ежик под новогодней елкой:

//*******************************************
function intCheckBase(strPathBase)
    return fs.ExistFile(strPathBase + "\UsrDEF\Users.USR");
endfunction


Передаете ей путь до нужной базы и получаете, либо 1 – есть авторизация, либо 0 – админ жжот. На следующих уроках я расскажу вам еще один трюк с этим файлом. Будем пускать робота для работы с базой.


Как прочитать параметры подключения 1с к SQL

Автор способа вроде бы Docent...

Function XOR(Val ParA, Val ParB)
  Res = 0;
  Koef = 1;
  For BitNumber = 1 To 8 Do
    BitA = ParA % 2;
    BitB = ParB % 2;
    ParA = Int(ParA / 2);
    ParB = Int(ParB / 2);
    BitC = (BitA + BitB) % 2;
    Res = Res + BitC * Koef;
    Koef = Koef * 2;
  EndDo;
  Return Res;
EndFunction

//*******************************************               
// индексы значений с списке  
// server = 2, db = 4, uid = 6, pwd = 8, checksum = 10
Function ConnectionString()  export
    Var SQLKeyCode[36], ConnectCode[200];
    ConnectFile = IBDir() + "1Cv7.DBA";
    If FS.ExistFile(ConnectFile) = 0 Then
        Message("Это не SQL - база!", "!");
        Return (0);
    EndIF;
    FSO = CreateObject("Scripting.FileSystemObject");
    F = FSO.OpenTextFile(ConnectFile, 1);
    ConnectLen = 0;
    While F.AtEndOfStream = 0 Do
        ConnectLen = ConnectLen + 1;
        ConnectCode[ConnectLen] = Asc(F.Read(1));
    EndDo;
    F.Close();
    FSO = 0;
    SQLKey = "19465912879oiuxc ensdfaiuo3i73798kjl";
    For i = 1 To 36 Do
        SQLKeyCode[i] = Asc(Сред(SQLKey, i, 1));
    EndDo;
    Connect = "";
    For i = 1 To ConnectLen Do
        Connect = Connect + Chr(XOR(ConnectCode[i], SQLKeyCode[(i - 1) % 36 + 1]));
    EndDo; 
    vl=createobject("ValueList");
    Connect=StrReplace(Connect,"{",""); 
    Connect=StrReplace(Connect,"}","");
    vl.fromSeparatedString(Connect); 
    return (vl);
EndFunction


Вызов производится так:
    if ExclusiveMode()=0 then
        if FS.ExistFile(IbDir()+"1cv7.dds")=1 then
            constr=ConnectionString();
            if ConStr<>0 then
                server=constr.getValue(2);database=constr.getValue(4);uid=constr.getValue(6); pwd=constr.getValue(8);


На сегодня все. Всем пока. Да чуть не забыл. Это наш последний урок в этом году. Так что разрешите всех заздравить и конечно поздравить. Достойно проводите старый, и пусть в новом у вас будем в жизни немного меньше дерьма, чем в прошлом. Ну, все-таки пусть его немного останется, ведь без него жизнь становится скучной. Всего-всего, что сами себе желаете. Короче удачи, счастья и т.п. Пух … ой Скунк ;))

Санкт-Петербург, Декабрь 2005 года.
skunk

Файлы:
http://www.kb.mista.ru/files/System.zip

Описание | Рубрикатор | Поиск | ТелепатБот | Захваченные статьи | Установки | Форум
© Станислав Митичкин (Волшебник), 2005-2025 | Mista.ru

Яндекс.Метрика