Чтение параметров в автосоздаваемые переменные из ini файла одним сниппетом

seodamage

Client
Регистрация
08.09.2014
Сообщения
224
Благодарностей
67
Баллы
28
Привет, подскажите плиз как правильно вписать путь до конфига, если у меня есть несколько папок, в каждой папке проект, а сам ini фаил на одну или две папки выше уровнем. Чтобы не пихать в каждую папку по копии конфига, а чтобы был один для всех проектов сразу.

можно это как то сделать не используя абсолютный путь ? Чтобы было не так C:\superproject\etc\config.ini
а чтобы было что то типа ../../config.ini ?



upd: если конфиг лежит на 1 папку выше то надо прописать вот так
C#:
//если несколько проектов юзают один и тот же конфиг
string config_file = "../config.ini";
string config_path = Path.Combine(project.Directory,config_file);
p.s. способ шикарный)

❤
 
Последнее редактирование:

zlodey

Client
Регистрация
24.04.2011
Сообщения
135
Благодарностей
9
Баллы
18
Подскажите пожалуйста, в каком формате нужно прописать данные в строке ini что бы положить в переменную зенки построчное значение, пример: в макросе ЗП должно быть значение построчно data1, data2, data3
пробовал в ini var1=data1\ndata2\ndata3\n не работает
 
Последнее редактирование:

dadoo

Новичок
Регистрация
20.05.2022
Сообщения
8
Благодарностей
1
Баллы
3
Excellent thank you. I personnaly use json file with name project. In this cas I can use array, object etc.
 

zlodey

Client
Регистрация
24.04.2011
Сообщения
135
Благодарностей
9
Баллы
18
Можно избавиться от регулярок и связанних проверок, если задействовать уже имеющиеся возможности для работы с ini-файлами.
Работа через WinAPI, но это лучше, чем регулярки.

Общий код:
Код:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO;
using System.Text.RegularExpressions;
using ZennoLab.CommandCenter;
using ZennoLab.InterfacesLibrary;
using ZennoLab.InterfacesLibrary.ProjectModel;
using ZennoLab.InterfacesLibrary.ProjectModel.Collections;
using ZennoLab.InterfacesLibrary.ProjectModel.Enums;
using ZennoLab.Macros;
using Global.ZennoExtensions;
using ZennoLab.Emulation;

namespace ZennoLab.OwnCode
{
    /// <summary>
    /// A simple class of the common code
    /// </summary>
    public class CommonCode
    {
        /// <summary>
        /// Lock this object to mark part of code for single thread execution
        /// </summary>
        public static object SyncObject = new object();

        // Insert your code here
    }

    public static class IniFileHelper
    {
        public static int capacity = 512;


        [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
        private static extern int GetPrivateProfileString(string section, string key, string defaultValue, StringBuilder value, int size, string filePath);

        [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
        static extern int GetPrivateProfileString(string section, string key, string defaultValue, [In, Out] char[] value, int size, string filePath);

        [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
        private static extern int GetPrivateProfileSection(string section, IntPtr keyValue, int size, string filePath);

        [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool WritePrivateProfileString(string section, string key, string value, string filePath);

        public static bool WriteValue(string section, string key, string value, string filePath)
        {
            return WritePrivateProfileString(section, key, value, filePath);
        }

        public static bool DeleteSection(string section, string filepath)
        {
            return WritePrivateProfileString(section, null, null, filepath);
        }

        public static bool DeleteKey(string section, string key, string filepath)
        {
            return WritePrivateProfileString(section, key, null, filepath);
        }

        public static string ReadValue(string section, string key, string filePath, string defaultValue = "")
        {
            var value = new StringBuilder(capacity);
            GetPrivateProfileString(section, key, defaultValue, value, value.Capacity, filePath);
            return value.ToString();
        }

        public static string[] ReadSections(string filePath)
        {
            // first line will not recognize if ini file is saved in UTF-8 with BOM
            while (true)
            {
                char[] chars = new char[capacity];
                int size = GetPrivateProfileString(null, null, "", chars, capacity, filePath);

                if (size == 0)
                {
                    return null;
                }

                if (size < capacity - 2)
                {
                    string result = new String(chars, 0, size);
                    string[] sections = result.Split(new char[] { '\0' }, StringSplitOptions.RemoveEmptyEntries);
                    return sections;
                }

                capacity = capacity * 2;
            }
        }

        public static string[] ReadKeys(string section, string filePath)
        {
            // first line will not recognize if ini file is saved in UTF-8 with BOM
            while (true)
            {
                char[] chars = new char[capacity];
                int size = GetPrivateProfileString(section, null, "", chars, capacity, filePath);

                if (size == 0)
                {
                    return null;
                }

                if (size < capacity - 2)
                {
                    string result = new String(chars, 0, size);
                    string[] keys = result.Split(new char[] { '\0' }, StringSplitOptions.RemoveEmptyEntries);
                    return keys;
                }

                capacity = capacity * 2;
            }
        }

        public static string[] ReadKeyValuePairs(string section, string filePath)
        {
            while (true)
            {
                IntPtr returnedString = Marshal.AllocCoTaskMem(capacity * sizeof(char));
                int size = GetPrivateProfileSection(section, returnedString, capacity, filePath);

                if (size == 0)
                {
                    Marshal.FreeCoTaskMem(returnedString);
                    return null;
                }

                if (size < capacity - 2)
                {
                    string result = Marshal.PtrToStringAuto(returnedString, size - 1);
                    Marshal.FreeCoTaskMem(returnedString);
                    string[] keyValuePairs = result.Split('\0');
                    return keyValuePairs;
                }

                Marshal.FreeCoTaskMem(returnedString);
                capacity = capacity * 2;
            }
        }
    }
}
Код с MSDN'а.

Сниппет:
Код:
//берем папку + имя проекта и заменяем расширение на ini
string config_file = project.Path + project.Name.Replace("xmlz","ini");
//если несколько проектов юзают один и тот же конфиг
//string config_file = project.Path + "config.ini";
string config_path = Path.Combine(project.Directory,config_file);
//проверяем отсутствие конфига
if (!File.Exists(config_path)) {
    project.SendWarningToLog("Отсутствует файл конфигурации: "+config_path);
    return "";
}
project.SendInfoToLog("Начинаем загрузку конфигурации из файла:"+config_file);
string[] sections = IniFileHelper.ReadSections(config_file);
foreach(string sct in sections)
{
    project.SendInfoToLog("Секция: "+sct);
    string[] keys = IniFileHelper.ReadKeys(sct, config_file);
    foreach(string key in keys)
    {
        string value = IniFileHelper.ReadValue(sct, key, config_file);

        if (!String.IsNullOrEmpty(key)&& !String.IsNullOrEmpty(value)){
            project.SendInfoToLog("\tКлюч: "+key);

            string vParamValue = value;
            string vParamName = String.Empty;
            if (sct == String.Empty){
                vParamName = "cfg_"+key;
            } else {
                vParamName = "cfg_"+sct+"_"+key;
            }

            //проверяем существование переменной, если нет то создаем новую
            if (project.Variables.Keys.Contains(vParamName)){
                project.SendInfoToLog("Переменная "+vParamName+" уже существует - присваиваем ей значение: "+value);
                project.Variables[vParamName].Value = vParamValue;
            } else {
                project.SendInfoToLog("Создаем переменную "+vParamName+" и присваиваем ей значение: "+value);
                object obj = project.Variables;
                obj.GetType().GetMethod("QuickCreateVariable").Invoke(obj,new Object[]{vParamName});
                project.Variables[vParamName].Value = vParamValue;
            }
        }
    }
}
Не работает код на версии 77140 при создании нового проекта, всегда выдает ошибку [Строка: 13; Cтолбец: 19] Ссылка на объект не указывает на экземпляр объекта.

Кто может проверить и поправить?
 

Кто просматривает тему: (Всего: 2, Пользователи: 0, Гости: 2)