Добавьте файлы проекта.
This commit is contained in:
parent
74cf6d2453
commit
438a7c85cc
18
App.config
Normal file
18
App.config
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
|
||||
<section name="SKLADm.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" />
|
||||
</startup>
|
||||
<userSettings>
|
||||
<SKLADm.Properties.Settings>
|
||||
<setting name="SavedStoresJson" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
</SKLADm.Properties.Settings>
|
||||
</userSettings>
|
||||
</configuration>
|
223
Form1.Designer.cs
generated
Normal file
223
Form1.Designer.cs
generated
Normal file
@ -0,0 +1,223 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// Этот код создан программой.
|
||||
// Исполняемая версия:4.0.30319.42000
|
||||
//
|
||||
// Изменения в этом файле могут привести к неправильной работе и будут потеряны в случае
|
||||
// повторной генерации кода.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace OzonInternalLabelPrinter // Убедитесь, что это ваше пространство имен
|
||||
{
|
||||
partial class Form1
|
||||
{
|
||||
/// <summary>
|
||||
/// Обязательная переменная конструктора.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Освободить все используемые ресурсы.
|
||||
/// </summary>
|
||||
/// <param name="disposing">истинно, если управляемый ресурс должен быть удален; иначе ложно.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
// Освобождаем ресурсы, созданные в коде Form1.cs
|
||||
_httpClient?.Dispose();
|
||||
_printDocForSetup?.Dispose(); // Добавлено освобождение PrintDocument
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Код, автоматически созданный конструктором форм Windows
|
||||
|
||||
/// <summary>
|
||||
/// Требуемый метод для поддержки конструктора — не изменяйте
|
||||
/// содержимое этого метода с помощью редактора кода.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.txtOfferId = new System.Windows.Forms.TextBox();
|
||||
this.btnGetData = new System.Windows.Forms.Button();
|
||||
this.lblProductName = new System.Windows.Forms.Label();
|
||||
this.lblProductSku = new System.Windows.Forms.Label();
|
||||
this.lblProductBarcode = new System.Windows.Forms.Label();
|
||||
this.btnPrintLabel = new System.Windows.Forms.Button();
|
||||
this.lblStatus = new System.Windows.Forms.Label();
|
||||
this.cmbStores = new System.Windows.Forms.ComboBox();
|
||||
this.btnManageStores = new System.Windows.Forms.Button();
|
||||
this.labelStore = new System.Windows.Forms.Label();
|
||||
this.btnPageSetup = new System.Windows.Forms.Button(); // Объявление кнопки Настройки
|
||||
this.pageSetupDialog1 = new System.Windows.Forms.PageSetupDialog(); // Объявление диалога Настройки
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// label3
|
||||
//
|
||||
this.label3.AutoSize = true;
|
||||
this.label3.Location = new System.Drawing.Point(12, 94); // Скорректировано
|
||||
this.label3.Name = "label3";
|
||||
this.label3.Size = new System.Drawing.Size(51, 13);
|
||||
this.label3.TabIndex = 4;
|
||||
this.label3.Text = "Артикул:";
|
||||
//
|
||||
// txtOfferId
|
||||
//
|
||||
this.txtOfferId.Enabled = false;
|
||||
this.txtOfferId.Location = new System.Drawing.Point(88, 91); // Скорректировано
|
||||
this.txtOfferId.Name = "txtOfferId";
|
||||
this.txtOfferId.Size = new System.Drawing.Size(176, 20);
|
||||
this.txtOfferId.TabIndex = 3; // TabIndex изменен
|
||||
this.txtOfferId.TextChanged += new System.EventHandler(this.txtOfferId_TextChanged);
|
||||
//
|
||||
// btnGetData
|
||||
//
|
||||
this.btnGetData.Enabled = false;
|
||||
this.btnGetData.Location = new System.Drawing.Point(270, 89); // Скорректировано
|
||||
this.btnGetData.Name = "btnGetData";
|
||||
this.btnGetData.Size = new System.Drawing.Size(118, 23);
|
||||
this.btnGetData.TabIndex = 4; // TabIndex изменен
|
||||
this.btnGetData.Text = "Получить данные";
|
||||
this.btnGetData.UseVisualStyleBackColor = true;
|
||||
this.btnGetData.Click += new System.EventHandler(this.btnGetData_Click);
|
||||
//
|
||||
// lblProductName
|
||||
//
|
||||
this.lblProductName.AutoSize = true;
|
||||
this.lblProductName.Location = new System.Drawing.Point(12, 133); // Скорректировано
|
||||
this.lblProductName.Name = "lblProductName";
|
||||
this.lblProductName.Size = new System.Drawing.Size(60, 13);
|
||||
this.lblProductName.TabIndex = 5;
|
||||
this.lblProductName.Text = "Название:";
|
||||
//
|
||||
// lblProductSku
|
||||
//
|
||||
this.lblProductSku.AutoSize = true;
|
||||
this.lblProductSku.Location = new System.Drawing.Point(12, 156); // Скорректировано
|
||||
this.lblProductSku.Name = "lblProductSku";
|
||||
this.lblProductSku.Size = new System.Drawing.Size(51, 13);
|
||||
this.lblProductSku.TabIndex = 6;
|
||||
this.lblProductSku.Text = "Артикул:";
|
||||
//
|
||||
// lblProductBarcode
|
||||
//
|
||||
this.lblProductBarcode.AutoSize = true;
|
||||
this.lblProductBarcode.Location = new System.Drawing.Point(12, 179); // Скорректировано
|
||||
this.lblProductBarcode.Name = "lblProductBarcode";
|
||||
this.lblProductBarcode.Size = new System.Drawing.Size(59, 13);
|
||||
this.lblProductBarcode.TabIndex = 7;
|
||||
this.lblProductBarcode.Text = "Штрихкод:";
|
||||
//
|
||||
// btnPrintLabel
|
||||
//
|
||||
this.btnPrintLabel.Enabled = false;
|
||||
this.btnPrintLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
|
||||
this.btnPrintLabel.Location = new System.Drawing.Point(16, 214); // Скорректировано
|
||||
this.btnPrintLabel.Name = "btnPrintLabel";
|
||||
this.btnPrintLabel.Size = new System.Drawing.Size(373, 33);
|
||||
this.btnPrintLabel.TabIndex = 8; // TabIndex изменен
|
||||
this.btnPrintLabel.Text = "Печать этикетки";
|
||||
this.btnPrintLabel.UseVisualStyleBackColor = true;
|
||||
this.btnPrintLabel.Click += new System.EventHandler(this.btnPrintLabel_Click);
|
||||
//
|
||||
// lblStatus
|
||||
//
|
||||
this.lblStatus.AutoSize = true;
|
||||
this.lblStatus.Location = new System.Drawing.Point(13, 260); // Скорректировано
|
||||
this.lblStatus.Name = "lblStatus";
|
||||
this.lblStatus.Size = new System.Drawing.Size(44, 13);
|
||||
this.lblStatus.TabIndex = 9;
|
||||
this.lblStatus.Text = "Статус:";
|
||||
//
|
||||
// cmbStores
|
||||
//
|
||||
this.cmbStores.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.cmbStores.FormattingEnabled = true;
|
||||
this.cmbStores.Location = new System.Drawing.Point(88, 24);
|
||||
this.cmbStores.Name = "cmbStores";
|
||||
this.cmbStores.Size = new System.Drawing.Size(176, 21);
|
||||
this.cmbStores.TabIndex = 0;
|
||||
this.cmbStores.SelectedIndexChanged += new System.EventHandler(this.cmbStores_SelectedIndexChanged);
|
||||
//
|
||||
// btnManageStores
|
||||
//
|
||||
this.btnManageStores.Location = new System.Drawing.Point(270, 23);
|
||||
this.btnManageStores.Name = "btnManageStores";
|
||||
this.btnManageStores.Size = new System.Drawing.Size(118, 23);
|
||||
this.btnManageStores.TabIndex = 1;
|
||||
this.btnManageStores.Text = "Упр. магазинами...";
|
||||
this.btnManageStores.UseVisualStyleBackColor = true;
|
||||
this.btnManageStores.Click += new System.EventHandler(this.btnManageStores_Click);
|
||||
//
|
||||
// labelStore
|
||||
//
|
||||
this.labelStore.AutoSize = true;
|
||||
this.labelStore.Location = new System.Drawing.Point(12, 27);
|
||||
this.labelStore.Name = "labelStore";
|
||||
this.labelStore.Size = new System.Drawing.Size(54, 13);
|
||||
this.labelStore.TabIndex = 15;
|
||||
this.labelStore.Text = "Магазин:";
|
||||
//
|
||||
// btnPageSetup
|
||||
// *** Новая кнопка Настройки принтера ***
|
||||
this.btnPageSetup.Location = new System.Drawing.Point(270, 53);
|
||||
this.btnPageSetup.Name = "btnPageSetup";
|
||||
this.btnPageSetup.Size = new System.Drawing.Size(118, 23);
|
||||
this.btnPageSetup.TabIndex = 2; // Изменен TabIndex
|
||||
this.btnPageSetup.Text = "Настройка принтера";
|
||||
this.btnPageSetup.UseVisualStyleBackColor = true;
|
||||
this.btnPageSetup.Click += new System.EventHandler(this.btnPageSetup_Click);
|
||||
//
|
||||
// pageSetupDialog1
|
||||
// *** Диалог настройки страницы ***
|
||||
this.pageSetupDialog1 = new System.Windows.Forms.PageSetupDialog();
|
||||
this.pageSetupDialog1.EnableMetric = true;
|
||||
//
|
||||
// Form1
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(404, 288); // Скорректирован размер
|
||||
this.Controls.Add(this.btnPageSetup); // Добавлена кнопка
|
||||
this.Controls.Add(this.labelStore);
|
||||
this.Controls.Add(this.btnManageStores);
|
||||
this.Controls.Add(this.cmbStores);
|
||||
this.Controls.Add(this.lblStatus);
|
||||
this.Controls.Add(this.btnPrintLabel);
|
||||
this.Controls.Add(this.lblProductBarcode);
|
||||
this.Controls.Add(this.lblProductSku);
|
||||
this.Controls.Add(this.lblProductName);
|
||||
this.Controls.Add(this.btnGetData);
|
||||
this.Controls.Add(this.txtOfferId);
|
||||
this.Controls.Add(this.label3);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
|
||||
this.MaximizeBox = false;
|
||||
this.Name = "Form1";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "Генератор внутренних этикеток Ozon";
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Label label3;
|
||||
private System.Windows.Forms.TextBox txtOfferId;
|
||||
private System.Windows.Forms.Button btnGetData;
|
||||
private System.Windows.Forms.Label lblProductName;
|
||||
private System.Windows.Forms.Label lblProductSku;
|
||||
private System.Windows.Forms.Label lblProductBarcode;
|
||||
private System.Windows.Forms.Button btnPrintLabel;
|
||||
private System.Windows.Forms.Label lblStatus;
|
||||
private System.Windows.Forms.ComboBox cmbStores;
|
||||
private System.Windows.Forms.Button btnManageStores;
|
||||
private System.Windows.Forms.Label labelStore;
|
||||
private System.Windows.Forms.Button btnPageSetup; // Добавлено
|
||||
private System.Windows.Forms.PageSetupDialog pageSetupDialog1; // Добавлено
|
||||
}
|
||||
}
|
500
Form1.cs
Normal file
500
Form1.cs
Normal file
@ -0,0 +1,500 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Printing;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Security.Cryptography; // Для шифрования/дешифрования
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using SKLADm.Properties; // Для доступа к Settings.Default
|
||||
using SKLADm;
|
||||
using ZXing;
|
||||
using ZXing.Common;
|
||||
using ZXing.Windows.Compatibility;
|
||||
|
||||
namespace OzonInternalLabelPrinter // Убедитесь, что это ваше пространство имен
|
||||
{
|
||||
public partial class Form1 : Form
|
||||
{
|
||||
private HttpClient _httpClient;
|
||||
// Bitmap больше не нужен как поле класса
|
||||
// private Bitmap _labelBitmap;
|
||||
private string _currentProductName;
|
||||
private string _currentSku;
|
||||
private string _currentBarcode;
|
||||
private List<OzonStore> _availableStores;
|
||||
// Поле для хранения экземпляра документа между настройкой и печатью
|
||||
private PrintDocument _printDocForSetup; // Используем для PageSetup и Print
|
||||
|
||||
// Конструктор формы
|
||||
public Form1()
|
||||
{
|
||||
InitializeComponent(); // Инициализирует компоненты из ДИЗАЙНЕРА
|
||||
InitializeHttpClient();
|
||||
// Инициализируем PrintDocument один раз
|
||||
_printDocForSetup = new PrintDocument();
|
||||
// Устанавливаем обработчик печати один раз
|
||||
_printDocForSetup.PrintPage += new PrintPageEventHandler(pd_PrintPage);
|
||||
// Загружаем магазины при запуске ПОСЛЕ инициализации _printDocForSetup
|
||||
LoadStoresToComboBox();
|
||||
}
|
||||
|
||||
// Инициализация HTTP клиента
|
||||
private void InitializeHttpClient()
|
||||
{
|
||||
_httpClient = new HttpClient
|
||||
{
|
||||
BaseAddress = new Uri("https://api-seller.ozon.ru/")
|
||||
};
|
||||
_httpClient.DefaultRequestHeaders.Accept.Clear();
|
||||
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||
}
|
||||
|
||||
// --- Логика работы с магазинами и ключами ---
|
||||
|
||||
private static readonly byte[] s_entropy = null; // Энтропия для шифрования
|
||||
|
||||
// Дешифрование Api-Key
|
||||
private string DecryptApiKey(string encryptedKeyBase64)
|
||||
{
|
||||
if (string.IsNullOrEmpty(encryptedKeyBase64)) return string.Empty;
|
||||
try
|
||||
{
|
||||
byte[] encryptedBytes = Convert.FromBase64String(encryptedKeyBase64);
|
||||
byte[] decryptedBytes = ProtectedData.Unprotect(encryptedBytes, s_entropy, DataProtectionScope.CurrentUser);
|
||||
return Encoding.UTF8.GetString(decryptedBytes);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"Ошибка дешифрования ключа: {ex.Message}");
|
||||
MessageBox.Show($"Не удалось дешифровать Api-Key для магазина '{cmbStores.Text}'. Возможно, настройки повреждены или созданы под другим пользователем.\n\nОшибка: {ex.Message}",
|
||||
"Ошибка ключа", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Загрузка магазинов из настроек в ComboBox
|
||||
private void LoadStoresToComboBox()
|
||||
{
|
||||
string json = Settings.Default.SavedStoresJson;
|
||||
_availableStores = new List<OzonStore>();
|
||||
if (!string.IsNullOrEmpty(json))
|
||||
{
|
||||
try
|
||||
{
|
||||
_availableStores = JsonConvert.DeserializeObject<List<OzonStore>>(json) ?? new List<OzonStore>();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"Ошибка загрузки списка магазинов: {ex.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
_availableStores = new List<OzonStore>();
|
||||
}
|
||||
}
|
||||
|
||||
cmbStores.DataSource = null;
|
||||
cmbStores.DataSource = _availableStores;
|
||||
cmbStores.DisplayMember = "StoreName";
|
||||
|
||||
bool storesExist = _availableStores.Any();
|
||||
cmbStores.Enabled = storesExist;
|
||||
txtOfferId.Enabled = storesExist;
|
||||
btnPageSetup.Enabled = storesExist; // Включаем настройку, если есть магазины
|
||||
// Кнопка GetData включится при вводе артикула
|
||||
|
||||
if (storesExist)
|
||||
{
|
||||
cmbStores.SelectedIndex = 0;
|
||||
// Установим принтер по умолчанию для _printDocForSetup, если возможно
|
||||
TrySetDefaultPrinterForDocument();
|
||||
}
|
||||
else
|
||||
{
|
||||
cmbStores.SelectedIndex = -1;
|
||||
// Показываем сообщение, если нужно
|
||||
// MessageBox.Show("Нет сохраненных магазинов...", "Внимание", MessageBoxButtons.OK, Information);
|
||||
}
|
||||
ResetProductData();
|
||||
// Обновляем состояние кнопки GetData после загрузки
|
||||
txtOfferId_TextChanged(txtOfferId, EventArgs.Empty);
|
||||
}
|
||||
|
||||
// Попытка установить принтер по умолчанию для PrintDocument
|
||||
private void TrySetDefaultPrinterForDocument()
|
||||
{
|
||||
string thermalPrinterName = "Xprinter XP-365B"; // Или другое имя по умолчанию
|
||||
foreach (string printerName in PrinterSettings.InstalledPrinters)
|
||||
{
|
||||
if (printerName.Equals(thermalPrinterName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
try
|
||||
{
|
||||
_printDocForSetup.PrinterSettings.PrinterName = printerName;
|
||||
System.Diagnostics.Debug.WriteLine($"Принтер по умолчанию '{printerName}' установлен для PrintDocument.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"Ошибка установки принтера по умолчанию '{printerName}': {ex.Message}");
|
||||
}
|
||||
return; // Выходим после нахождения
|
||||
}
|
||||
}
|
||||
System.Diagnostics.Debug.WriteLine($"Принтер по умолчанию '{thermalPrinterName}' не найден.");
|
||||
}
|
||||
|
||||
// --- Обработчики событий UI ---
|
||||
|
||||
private void btnManageStores_Click(object sender, EventArgs e)
|
||||
{
|
||||
using (FormManageStores manageForm = new FormManageStores())
|
||||
{
|
||||
manageForm.ShowDialog(this);
|
||||
LoadStoresToComboBox(); // Перезагружаем список
|
||||
}
|
||||
}
|
||||
|
||||
private void cmbStores_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
ResetProductData();
|
||||
txtOfferId_TextChanged(txtOfferId, EventArgs.Empty); // Обновляем состояние кнопки GetData
|
||||
// Можно попробовать обновить принтер по умолчанию для _printDocForSetup,
|
||||
// если у разных магазинов могут быть разные принтеры (но это усложнит логику)
|
||||
}
|
||||
|
||||
private void txtOfferId_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
btnGetData.Enabled = cmbStores.SelectedItem != null && !string.IsNullOrEmpty(txtOfferId.Text.Trim());
|
||||
if (string.IsNullOrEmpty(txtOfferId.Text.Trim()))
|
||||
{
|
||||
ResetProductData();
|
||||
}
|
||||
}
|
||||
|
||||
// --- Кнопка "Настройка принтера" ---
|
||||
private void btnPageSetup_Click(object sender, EventArgs e)
|
||||
{
|
||||
// Убедимся, что принтер в _printDocForSetup актуален (если не нашли Xprinter при запуске,
|
||||
// или если у пользователя несколько принтеров)
|
||||
if (!PrinterSettings.InstalledPrinters.Cast<string>().Contains(_printDocForSetup.PrinterSettings.PrinterName))
|
||||
{
|
||||
// Если текущий принтер недоступен, сбрасываем на принтер по умолчанию Windows
|
||||
try
|
||||
{
|
||||
_printDocForSetup.PrinterSettings = new PrinterSettings(); // Сброс на настройки по умолчанию
|
||||
System.Diagnostics.Debug.WriteLine("Текущий принтер в PrintDocument был недоступен, сброшен на принтер по умолчанию Windows.");
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
pageSetupDialog1.Document = _printDocForSetup; // Связываем диалог с нашим PrintDocument
|
||||
pageSetupDialog1.MinMargins = new Margins(0, 0, 0, 0); // Минимальные поля
|
||||
pageSetupDialog1.AllowMargins = true; // Разрешаем менять поля
|
||||
pageSetupDialog1.AllowOrientation = false; // Запрещаем менять ориентацию
|
||||
pageSetupDialog1.AllowPaper = true; // Разрешаем менять размер бумаги
|
||||
pageSetupDialog1.AllowPrinter = true; // Разрешаем выбирать другой принтер
|
||||
|
||||
if (pageSetupDialog1.ShowDialog(this) == DialogResult.OK)
|
||||
{
|
||||
// Настройки применились к _printDocForSetup
|
||||
lblStatus.Text = "Настройки принтера применены.";
|
||||
System.Diagnostics.Debug.WriteLine($"PageSetupDialog OK: New PaperSize={_printDocForSetup.DefaultPageSettings.PaperSize.PaperName}, Printer={_printDocForSetup.PrinterSettings.PrinterName}");
|
||||
}
|
||||
else
|
||||
{
|
||||
lblStatus.Text = "Настройка принтера отменена.";
|
||||
}
|
||||
}
|
||||
|
||||
// --- Получение данных из API ---
|
||||
private async void btnGetData_Click(object sender, EventArgs e)
|
||||
{
|
||||
OzonStore selectedStore = cmbStores.SelectedItem as OzonStore;
|
||||
if (selectedStore == null) { MessageBox.Show("Выберите магазин.", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; }
|
||||
|
||||
string clientId = selectedStore.ClientId;
|
||||
string apiKey = DecryptApiKey(selectedStore.EncryptedApiKey);
|
||||
if (apiKey == null) { lblStatus.Text = "Ошибка ключа API."; return; }
|
||||
|
||||
string rawOfferId = txtOfferId.Text.Trim();
|
||||
if (string.IsNullOrEmpty(rawOfferId)) { MessageBox.Show("Введите Артикул.", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; }
|
||||
|
||||
string offerId = Regex.Replace(rawOfferId, @"[^a-zA-Zа-яА-Я0-9_-]", "");
|
||||
if (string.IsNullOrEmpty(offerId)) { MessageBox.Show("Артикул некорректен.", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; }
|
||||
if (offerId != rawOfferId) { txtOfferId.Text = offerId; }
|
||||
|
||||
ResetProductData();
|
||||
lblStatus.Text = "Запрос данных...";
|
||||
Application.DoEvents();
|
||||
|
||||
_httpClient.DefaultRequestHeaders.Remove("Client-Id");
|
||||
_httpClient.DefaultRequestHeaders.Remove("Api-Key");
|
||||
_httpClient.DefaultRequestHeaders.Add("Client-Id", clientId);
|
||||
_httpClient.DefaultRequestHeaders.Add("Api-Key", apiKey);
|
||||
|
||||
string responseBody = string.Empty;
|
||||
try
|
||||
{
|
||||
var requestData = new { offer_id = new[] { offerId } };
|
||||
var jsonRequest = JsonConvert.SerializeObject(requestData);
|
||||
var content = new StringContent(jsonRequest, Encoding.UTF8, "application/json");
|
||||
|
||||
HttpResponseMessage response = await _httpClient.PostAsync("/v3/product/info/list", content);
|
||||
responseBody = await response.Content.ReadAsStringAsync();
|
||||
System.Diagnostics.Debug.WriteLine($"API Response ({response.StatusCode}): {responseBody}");
|
||||
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
JObject jsonResponse = JObject.Parse(responseBody);
|
||||
JToken itemsArray = jsonResponse["items"];
|
||||
|
||||
if (itemsArray != null && itemsArray.Type == JTokenType.Array && itemsArray.HasValues)
|
||||
{
|
||||
JToken firstItem = itemsArray[0];
|
||||
if (firstItem != null)
|
||||
{
|
||||
_currentProductName = firstItem["name"]?.ToString() ?? "N/A";
|
||||
_currentSku = firstItem["offer_id"]?.ToString() ?? offerId;
|
||||
_currentBarcode = firstItem["barcode"]?.ToString();
|
||||
if (string.IsNullOrEmpty(_currentBarcode))
|
||||
{
|
||||
JToken barcodesToken = firstItem["barcodes"];
|
||||
if (barcodesToken != null && barcodesToken.Type == JTokenType.Array && barcodesToken.HasValues)
|
||||
{ _currentBarcode = barcodesToken.First?.ToString(); }
|
||||
}
|
||||
_currentBarcode = _currentBarcode ?? "N/A";
|
||||
|
||||
GenerateLabelPreview(); // Обновляем UI и включаем кнопку печати
|
||||
}
|
||||
else { HandleApiError("Нет данных о товаре в ответе.", responseBody); }
|
||||
}
|
||||
else { HandleApiError("Ответ API не содержит списка товаров.", responseBody); }
|
||||
}
|
||||
else { HandleApiError($"Ошибка API: {response.StatusCode}", responseBody); }
|
||||
}
|
||||
catch (JsonReaderException jsonEx) { MessageBox.Show($"Ошибка JSON: {jsonEx.Message}\n{responseBody}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); ResetProductData(); }
|
||||
catch (HttpRequestException httpEx) { MessageBox.Show($"Ошибка сети: {httpEx.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); ResetProductData(); }
|
||||
catch (Exception ex) { MessageBox.Show($"Ошибка: {ex.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); ResetProductData(); }
|
||||
finally { apiKey = null; }
|
||||
}
|
||||
|
||||
// Обработка ошибок API
|
||||
private void HandleApiError(string messagePrefix, string responseBody)
|
||||
{
|
||||
string errorMessage = $"{messagePrefix}";
|
||||
try
|
||||
{
|
||||
JObject errorJson = JObject.Parse(responseBody);
|
||||
string ozonError = errorJson["message"]?.ToString() ?? errorJson["error"]?["message"]?.ToString();
|
||||
errorMessage = string.IsNullOrEmpty(ozonError) ? $"{messagePrefix}\n{responseBody}" : $"{messagePrefix}\n{ozonError}";
|
||||
}
|
||||
catch { errorMessage = $"{messagePrefix}\n{responseBody}"; }
|
||||
|
||||
MessageBox.Show(errorMessage, "Ошибка API Ozon", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
lblStatus.Text = "Ошибка API.";
|
||||
ResetProductData();
|
||||
}
|
||||
|
||||
// Сброс данных о товаре и состояния UI
|
||||
private void ResetProductData()
|
||||
{
|
||||
_currentProductName = null;
|
||||
_currentSku = null;
|
||||
_currentBarcode = null;
|
||||
lblProductName.Text = "Название:";
|
||||
lblProductSku.Text = "Артикул:";
|
||||
lblProductBarcode.Text = "Штрихкод:";
|
||||
// Очищаем превью, если оно есть
|
||||
if (this.Controls.ContainsKey("picLabelPreview"))
|
||||
(this.Controls["picLabelPreview"] as PictureBox).Image = null;
|
||||
btnPrintLabel.Enabled = false;
|
||||
// lblStatus.Text = "Статус:";
|
||||
}
|
||||
|
||||
// Генерация (только обновление UI)
|
||||
private void GenerateLabelPreview()
|
||||
{
|
||||
bool dataAvailable = !string.IsNullOrEmpty(_currentSku) &&
|
||||
!string.IsNullOrEmpty(_currentProductName) &&
|
||||
!string.IsNullOrEmpty(_currentBarcode) &&
|
||||
_currentBarcode != "N/A";
|
||||
if (!dataAvailable) { ResetProductData(); return; }
|
||||
|
||||
lblProductName.Text = $"Название: {_currentProductName}";
|
||||
lblProductSku.Text = $"Артикул: {_currentSku}";
|
||||
lblProductBarcode.Text = $"Штрихкод: {_currentBarcode}";
|
||||
|
||||
// Очистка превью, если оно есть
|
||||
if (this.Controls.ContainsKey("picLabelPreview"))
|
||||
(this.Controls["picLabelPreview"] as PictureBox).Image = null;
|
||||
|
||||
btnPrintLabel.Enabled = true;
|
||||
lblStatus.Text = "Данные получены, готово к печати.";
|
||||
}
|
||||
|
||||
|
||||
// --- Печать ---
|
||||
|
||||
// Кнопка "Печать этикетки"
|
||||
private void btnPrintLabel_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (string.IsNullOrEmpty(_currentSku) || string.IsNullOrEmpty(_currentProductName) || string.IsNullOrEmpty(_currentBarcode) || _currentBarcode == "N/A")
|
||||
{
|
||||
MessageBox.Show("Нет данных для печати.", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
PrintDialog printDialog = new PrintDialog();
|
||||
printDialog.Document = _printDocForSetup; // Используем настроенный документ
|
||||
printDialog.AllowSomePages = false;
|
||||
printDialog.AllowSelection = false;
|
||||
printDialog.UseEXDialog = true;
|
||||
|
||||
if (printDialog.ShowDialog(this) == DialogResult.OK)
|
||||
{
|
||||
// _printDocForSetup уже содержит принтер и настройки страницы, выбранные в PrintDialog или PageSetupDialog
|
||||
// Переустанавливаем поля на случай, если PrintDialog их сбросил
|
||||
_printDocForSetup.DefaultPageSettings.Margins = new Margins(0, 0, 0, 0);
|
||||
_printDocForSetup.OriginAtMargins = false;
|
||||
|
||||
try
|
||||
{
|
||||
lblStatus.Text = $"Печать на {_printDocForSetup.PrinterSettings.PrinterName}...";
|
||||
_printDocForSetup.Print(); // Печатаем с текущими настройками
|
||||
lblStatus.Text = "Отправлено на печать.";
|
||||
}
|
||||
catch (InvalidPrinterException)
|
||||
{
|
||||
MessageBox.Show($"Ошибка: Принтер '{_printDocForSetup.PrinterSettings.PrinterName}' недоступен или не найден.\nПроверьте подключение или выберите другой принтер в настройках.", "Ошибка принтера", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
lblStatus.Text = "Ошибка принтера.";
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"Ошибка печати: {ex.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
lblStatus.Text = "Ошибка печати.";
|
||||
}
|
||||
}
|
||||
else { lblStatus.Text = "Печать отменена."; }
|
||||
|
||||
printDialog.Dispose();
|
||||
}
|
||||
|
||||
// Метод отрисовки страницы для печати (динамический)
|
||||
private void pd_PrintPage(object sender, PrintPageEventArgs e)
|
||||
{
|
||||
// Проверка данных
|
||||
if (string.IsNullOrEmpty(_currentSku) || string.IsNullOrEmpty(_currentProductName) || string.IsNullOrEmpty(_currentBarcode) || _currentBarcode == "N/A")
|
||||
{ System.Diagnostics.Debug.WriteLine("PrintPage ABORTED - Missing data!"); e.Cancel = true; return; }
|
||||
|
||||
Graphics g = e.Graphics;
|
||||
// Получаем РЕАЛЬНЫЕ границы печатаемой области в единицах Graphics (обычно сотые дюйма)
|
||||
// Не PageBounds, а PrintableArea! PageBounds - это физический размер листа.
|
||||
RectangleF printArea = e.PageSettings.PrintableArea;
|
||||
|
||||
// Отступы от КРАЕВ ПЕЧАТАЕМОЙ ОБЛАСТИ (в единицах Graphics)
|
||||
// Подбирайте эти значения, чтобы получить рамку внутри печатаемой зоны
|
||||
float marginX = 5 * g.DpiX / 100f; // Пример: 5/100 дюйма -> в единицах Graphics
|
||||
float marginY = 3 * g.DpiY / 100f; // Пример: 3/100 дюйма -> в единицах Graphics
|
||||
|
||||
// Область для рисования контента внутри отступов
|
||||
float drawableX = printArea.Left + marginX;
|
||||
float drawableY = printArea.Top + marginY;
|
||||
float drawableWidth = printArea.Width - (marginX * 2);
|
||||
float drawableHeight = printArea.Height - (marginY * 2);
|
||||
float currentY = drawableY; // Текущая позиция по Y
|
||||
|
||||
// Проверка на валидность области
|
||||
if (drawableWidth <= 0 || drawableHeight <= 0) { System.Diagnostics.Debug.WriteLine("PrintPage ABORTED - Invalid drawable area!"); e.Cancel = true; return; }
|
||||
|
||||
System.Diagnostics.Debug.WriteLine("--- Printing Page (Dynamic) ---");
|
||||
System.Diagnostics.Debug.WriteLine($"Paper: {e.PageSettings.PaperSize.PaperName} ({e.PageSettings.PaperSize.Width}x{e.PageSettings.PaperSize.Height}) hund.inch");
|
||||
System.Diagnostics.Debug.WriteLine($"PrintableArea ({g.PageUnit}): X={printArea.X:F2}, Y={printArea.Y:F2}, W={printArea.Width:F2}, H={printArea.Height:F2}");
|
||||
System.Diagnostics.Debug.WriteLine($"Drawable Area ({g.PageUnit}): X={drawableX:F2}, Y={drawableY:F2}, W={drawableWidth:F2}, H={drawableHeight:F2}");
|
||||
|
||||
// Шрифты (размер в пунктах)
|
||||
float baseFontSizePoints = 6f; // Базовый размер, можно менять
|
||||
Font titleFont = new Font("Arial", baseFontSizePoints + 1, FontStyle.Bold);
|
||||
Font regularFont = new Font("Arial", baseFontSizePoints);
|
||||
Font barcodeTextFont = new Font("Arial", baseFontSizePoints - 1);
|
||||
|
||||
try
|
||||
{
|
||||
// --- Рисуем Название ---
|
||||
string productName = _currentProductName ?? "N/A";
|
||||
SizeF titleSize = g.MeasureString(productName, titleFont, (int)drawableWidth);
|
||||
// Ограничиваем высоту, чтобы поместилось остальное
|
||||
float maxTitleHeight = drawableHeight * 0.3f;
|
||||
float actualTitleHeight = Math.Min(titleSize.Height, maxTitleHeight);
|
||||
g.DrawString(productName, titleFont, Brushes.Black, new RectangleF(drawableX, currentY, drawableWidth, actualTitleHeight));
|
||||
currentY += actualTitleHeight + (2 * g.DpiY / 72f); // Отступ 2 пункта
|
||||
|
||||
// --- Рисуем Артикул ---
|
||||
string skuText = $"Артикул: {_currentSku ?? "N/A"}";
|
||||
SizeF skuSize = g.MeasureString(skuText, regularFont, (int)drawableWidth);
|
||||
if (currentY + skuSize.Height < printArea.Bottom - marginY - 15 * 100f / g.DpiY) // Оставляем ~15px под ШК + текст
|
||||
{
|
||||
g.DrawString(skuText, regularFont, Brushes.Black, drawableX, currentY);
|
||||
currentY += skuSize.Height + (3 * g.DpiY / 72f); // Отступ 3 пункта
|
||||
}
|
||||
|
||||
// --- Рисуем Штрихкод ---
|
||||
float remainingHeight = (printArea.Bottom - marginY) - currentY; // Оставшаяся высота
|
||||
if (remainingHeight > 15 * 100f / g.DpiY) // Если осталось хотя бы ~15px
|
||||
{
|
||||
try
|
||||
{
|
||||
// --- Расчет размеров ШК ---
|
||||
float barcodeTextHeight = g.MeasureString(_currentBarcode, barcodeTextFont).Height;
|
||||
float barcodePrintHeight = Math.Max(10 * 100f / g.DpiY, remainingHeight - barcodeTextHeight - (2 * g.DpiY / 72f)); // Вычитаем текст и отступ
|
||||
float barcodePrintWidth = drawableWidth * 0.98f;
|
||||
|
||||
int barcodePixelHeight = (int)(barcodePrintHeight * g.DpiY / 100f);
|
||||
int barcodePixelWidth = (int)(barcodePrintWidth * g.DpiX / 100f);
|
||||
if (barcodePixelHeight < 10 || barcodePixelWidth < 40) throw new Exception("Слишком мало места для ШК.");
|
||||
|
||||
BarcodeFormat barcodeFormat = BarcodeFormat.CODE_128;
|
||||
// ... (определение barcodeFormat) ...
|
||||
if (_currentBarcode.Length == 13 && long.TryParse(_currentBarcode, out _)) barcodeFormat = BarcodeFormat.EAN_13;
|
||||
else if (_currentBarcode.Length == 8 && long.TryParse(_currentBarcode, out _)) barcodeFormat = BarcodeFormat.EAN_8;
|
||||
|
||||
var barcodeWriter = new ZXing.Windows.Compatibility.BarcodeWriter { Format = barcodeFormat, Options = new EncodingOptions { Height = barcodePixelHeight, Width = barcodePixelWidth, PureBarcode = true, Margin = 1 } };
|
||||
|
||||
using (var barcodeBitmap = barcodeWriter.Write(_currentBarcode))
|
||||
{
|
||||
float barcodeX = drawableX + (drawableWidth - barcodePrintWidth) / 2.0f; // Центрируем
|
||||
g.DrawImage(barcodeBitmap, barcodeX, currentY, barcodePrintWidth, barcodePrintHeight);
|
||||
currentY += barcodePrintHeight + (1 * g.DpiY / 72f); // Отступ 1 пункт
|
||||
}
|
||||
|
||||
// --- Рисуем текст ШК ---
|
||||
SizeF barcodeTextSize = g.MeasureString(_currentBarcode, barcodeTextFont);
|
||||
if (currentY + barcodeTextSize.Height <= printArea.Bottom - marginY)
|
||||
{
|
||||
float textX = drawableX + (drawableWidth - barcodeTextSize.Width) / 2.0f; // Центрируем
|
||||
g.DrawString(_currentBarcode, barcodeTextFont, Brushes.Black, textX, currentY);
|
||||
}
|
||||
else { System.Diagnostics.Debug.WriteLine("SKIPPING Barcode text - no space"); }
|
||||
|
||||
}
|
||||
catch (Exception exBarcode)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"Error drawing barcode: {exBarcode.Message}");
|
||||
g.DrawString("Ошибка ШК", regularFont, Brushes.Red, drawableX, currentY); // Рисуем ошибку вместо ШК
|
||||
}
|
||||
}
|
||||
else { System.Diagnostics.Debug.WriteLine("SKIPPING Barcode - not enough vertical space"); }
|
||||
|
||||
}
|
||||
catch (Exception exDraw) { System.Diagnostics.Debug.WriteLine($"Error drawing page: {exDraw}"); }
|
||||
finally { titleFont.Dispose(); regularFont.Dispose(); barcodeTextFont.Dispose(); }
|
||||
|
||||
e.HasMorePages = false;
|
||||
}
|
||||
|
||||
} // Конец класса Form1
|
||||
} // Конец namespace
|
120
Form1.resx
Normal file
120
Form1.resx
Normal file
@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
201
FormManageStores.Designer.cs
generated
Normal file
201
FormManageStores.Designer.cs
generated
Normal file
@ -0,0 +1,201 @@
|
||||
namespace SKLADm
|
||||
{
|
||||
partial class FormManageStores
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.lstStores = new System.Windows.Forms.ListBox();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.groupBox1 = new System.Windows.Forms.GroupBox();
|
||||
this.btnAddStore = new System.Windows.Forms.Button();
|
||||
this.txtEditApiKey = new System.Windows.Forms.TextBox();
|
||||
this.label4 = new System.Windows.Forms.Label();
|
||||
this.txtEditClientId = new System.Windows.Forms.TextBox();
|
||||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.txtStoreName = new System.Windows.Forms.TextBox();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.btnDeleteStore = new System.Windows.Forms.Button();
|
||||
this.btnClose = new System.Windows.Forms.Button();
|
||||
this.groupBox1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// lstStores
|
||||
//
|
||||
this.lstStores.FormattingEnabled = true;
|
||||
this.lstStores.Location = new System.Drawing.Point(12, 25);
|
||||
this.lstStores.Name = "lstStores";
|
||||
this.lstStores.Size = new System.Drawing.Size(188, 199); // Adjust height as needed
|
||||
this.lstStores.TabIndex = 0;
|
||||
// Add event handler if you want to display details on selection:
|
||||
// this.lstStores.SelectedIndexChanged += new System.EventHandler(this.lstStores_SelectedIndexChanged);
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(12, 9);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(121, 13);
|
||||
this.label1.TabIndex = 1;
|
||||
this.label1.Text = "Сохраненные магазины:";
|
||||
//
|
||||
// groupBox1
|
||||
//
|
||||
this.groupBox1.Controls.Add(this.btnAddStore);
|
||||
this.groupBox1.Controls.Add(this.txtEditApiKey);
|
||||
this.groupBox1.Controls.Add(this.label4);
|
||||
this.groupBox1.Controls.Add(this.txtEditClientId);
|
||||
this.groupBox1.Controls.Add(this.label3);
|
||||
this.groupBox1.Controls.Add(this.txtStoreName);
|
||||
this.groupBox1.Controls.Add(this.label2);
|
||||
this.groupBox1.Location = new System.Drawing.Point(219, 25);
|
||||
this.groupBox1.Name = "groupBox1";
|
||||
this.groupBox1.Size = new System.Drawing.Size(303, 155); // Adjust size as needed
|
||||
this.groupBox1.TabIndex = 2;
|
||||
this.groupBox1.TabStop = false;
|
||||
this.groupBox1.Text = "Добавить новый магазин";
|
||||
//
|
||||
// btnAddStore
|
||||
//
|
||||
this.btnAddStore.Location = new System.Drawing.Point(196, 118);
|
||||
this.btnAddStore.Name = "btnAddStore";
|
||||
this.btnAddStore.Size = new System.Drawing.Size(97, 23);
|
||||
this.btnAddStore.TabIndex = 6;
|
||||
this.btnAddStore.Text = "Добавить";
|
||||
this.btnAddStore.UseVisualStyleBackColor = true;
|
||||
this.btnAddStore.Click += new System.EventHandler(this.btnAddStore_Click);
|
||||
//
|
||||
// txtEditApiKey
|
||||
//
|
||||
this.txtEditApiKey.Location = new System.Drawing.Point(74, 86);
|
||||
this.txtEditApiKey.Name = "txtEditApiKey";
|
||||
this.txtEditApiKey.PasswordChar = '*';
|
||||
this.txtEditApiKey.Size = new System.Drawing.Size(219, 20);
|
||||
this.txtEditApiKey.TabIndex = 5;
|
||||
//
|
||||
// label4
|
||||
//
|
||||
this.label4.AutoSize = true;
|
||||
this.label4.Location = new System.Drawing.Point(16, 89);
|
||||
this.label4.Name = "label4";
|
||||
this.label4.Size = new System.Drawing.Size(48, 13);
|
||||
this.label4.TabIndex = 4;
|
||||
this.label4.Text = "Api-Key:";
|
||||
//
|
||||
// txtEditClientId
|
||||
//
|
||||
this.txtEditClientId.Location = new System.Drawing.Point(74, 57);
|
||||
this.txtEditClientId.Name = "txtEditClientId";
|
||||
this.txtEditClientId.Size = new System.Drawing.Size(219, 20);
|
||||
this.txtEditClientId.TabIndex = 3;
|
||||
//
|
||||
// label3
|
||||
//
|
||||
this.label3.AutoSize = true;
|
||||
this.label3.Location = new System.Drawing.Point(16, 60);
|
||||
this.label3.Name = "label3";
|
||||
this.label3.Size = new System.Drawing.Size(50, 13);
|
||||
this.label3.TabIndex = 2;
|
||||
this.label3.Text = "Client ID:";
|
||||
//
|
||||
// txtStoreName
|
||||
//
|
||||
this.txtStoreName.Location = new System.Drawing.Point(74, 28);
|
||||
this.txtStoreName.Name = "txtStoreName";
|
||||
this.txtStoreName.Size = new System.Drawing.Size(219, 20);
|
||||
this.txtStoreName.TabIndex = 1;
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(16, 31);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(60, 13);
|
||||
this.label2.TabIndex = 0;
|
||||
this.label2.Text = "Название:";
|
||||
//
|
||||
// btnDeleteStore
|
||||
//
|
||||
this.btnDeleteStore.Location = new System.Drawing.Point(12, 230); // Position below listbox
|
||||
this.btnDeleteStore.Name = "btnDeleteStore";
|
||||
this.btnDeleteStore.Size = new System.Drawing.Size(188, 23);
|
||||
this.btnDeleteStore.TabIndex = 3;
|
||||
this.btnDeleteStore.Text = "Удалить выбранный";
|
||||
this.btnDeleteStore.UseVisualStyleBackColor = true;
|
||||
this.btnDeleteStore.Click += new System.EventHandler(this.btnDeleteStore_Click);
|
||||
//
|
||||
// btnClose
|
||||
//
|
||||
this.btnClose.DialogResult = System.Windows.Forms.DialogResult.Cancel; // Makes Esc close the form
|
||||
this.btnClose.Location = new System.Drawing.Point(447, 230); // Position bottom right
|
||||
this.btnClose.Name = "btnClose";
|
||||
this.btnClose.Size = new System.Drawing.Size(75, 23);
|
||||
this.btnClose.TabIndex = 4;
|
||||
this.btnClose.Text = "Закрыть";
|
||||
this.btnClose.UseVisualStyleBackColor = true;
|
||||
this.btnClose.Click += new System.EventHandler(this.btnClose_Click);
|
||||
//
|
||||
// FormManageStores
|
||||
//
|
||||
this.AcceptButton = this.btnAddStore; // Enter in groupbox adds store
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.CancelButton = this.btnClose; // Esc closes form
|
||||
this.ClientSize = new System.Drawing.Size(534, 267); // Adjust size as needed
|
||||
this.Controls.Add(this.btnClose);
|
||||
this.Controls.Add(this.btnDeleteStore);
|
||||
this.Controls.Add(this.groupBox1);
|
||||
this.Controls.Add(this.label1);
|
||||
this.Controls.Add(this.lstStores);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; // Prevent resizing
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "FormManageStores";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; // Center over Form1
|
||||
this.Text = "Управление магазинами Ozon";
|
||||
this.groupBox1.ResumeLayout(false);
|
||||
this.groupBox1.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.ListBox lstStores;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.GroupBox groupBox1;
|
||||
private System.Windows.Forms.Button btnAddStore;
|
||||
private System.Windows.Forms.TextBox txtEditApiKey;
|
||||
private System.Windows.Forms.Label label4;
|
||||
private System.Windows.Forms.TextBox txtEditClientId;
|
||||
private System.Windows.Forms.Label label3;
|
||||
private System.Windows.Forms.TextBox txtStoreName;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.Button btnDeleteStore;
|
||||
private System.Windows.Forms.Button btnClose;
|
||||
}
|
||||
}
|
150
FormManageStores.cs
Normal file
150
FormManageStores.cs
Normal file
@ -0,0 +1,150 @@
|
||||
using Newtonsoft.Json;
|
||||
using OzonInternalLabelPrinter; // Добавляем пространство имен для OzonStore
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography; // Для ProtectedData
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace SKLADm
|
||||
{
|
||||
public partial class FormManageStores : Form
|
||||
{
|
||||
private List<OzonStore> _stores;
|
||||
// Энтропия для шифрования (можно оставить null или использовать свой секрет)
|
||||
private static readonly byte[] s_entropy = null; // Или Encoding.UTF8.GetBytes("MyOptionalEntropy");
|
||||
|
||||
public FormManageStores()
|
||||
{
|
||||
InitializeComponent();
|
||||
LoadStoresToListBox();
|
||||
}
|
||||
|
||||
// --- Шифрование Api-Key ---
|
||||
private string EncryptApiKey(string apiKey)
|
||||
{
|
||||
if (string.IsNullOrEmpty(apiKey)) return string.Empty;
|
||||
try
|
||||
{
|
||||
byte[] apiKeyBytes = Encoding.UTF8.GetBytes(apiKey);
|
||||
byte[] encryptedBytes = ProtectedData.Protect(apiKeyBytes, s_entropy, DataProtectionScope.CurrentUser);
|
||||
return Convert.ToBase64String(encryptedBytes);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"Ошибка шифрования ключа: {ex.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return null; // Возвращаем null при ошибке
|
||||
}
|
||||
}
|
||||
|
||||
// --- Загрузка магазинов из настроек ---
|
||||
private void LoadStoresToListBox()
|
||||
{
|
||||
string json = Properties.Settings.Default.SavedStoresJson;
|
||||
_stores = new List<OzonStore>();
|
||||
if (!string.IsNullOrEmpty(json))
|
||||
{
|
||||
try
|
||||
{
|
||||
_stores = JsonConvert.DeserializeObject<List<OzonStore>>(json) ?? new List<OzonStore>();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"Ошибка загрузки списка магазинов: {ex.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
_stores = new List<OzonStore>(); // Создаем пустой список при ошибке
|
||||
}
|
||||
}
|
||||
UpdateListBox();
|
||||
}
|
||||
|
||||
// --- Сохранение магазинов в настройки ---
|
||||
private void SaveStores()
|
||||
{
|
||||
try
|
||||
{
|
||||
string json = JsonConvert.SerializeObject(_stores, Formatting.Indented);
|
||||
Properties.Settings.Default.SavedStoresJson = json;
|
||||
Properties.Settings.Default.Save();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"Ошибка сохранения списка магазинов: {ex.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Обновление ListBox ---
|
||||
private void UpdateListBox()
|
||||
{
|
||||
lstStores.DataSource = null; // Сначала отвязываем источник
|
||||
lstStores.DataSource = _stores; // Привязываем обновленный список
|
||||
lstStores.DisplayMember = "StoreName"; // Отображаем имя
|
||||
}
|
||||
|
||||
// --- Кнопка "Добавить магазин" ---
|
||||
private void btnAddStore_Click(object sender, EventArgs e)
|
||||
{
|
||||
string storeName = txtStoreName.Text.Trim();
|
||||
string clientId = txtEditClientId.Text.Trim();
|
||||
string apiKey = txtEditApiKey.Text.Trim(); // Берем ключ как есть
|
||||
|
||||
if (string.IsNullOrEmpty(storeName) || string.IsNullOrEmpty(clientId) || string.IsNullOrEmpty(apiKey))
|
||||
{
|
||||
MessageBox.Show("Пожалуйста, заполните все поля: Название, Client ID, Api-Key.", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
// Проверяем, нет ли уже магазина с таким именем
|
||||
if (_stores.Any(s => s.StoreName.Equals(storeName, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
MessageBox.Show("Магазин с таким названием уже существует.", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
// Шифруем ключ
|
||||
string encryptedKey = EncryptApiKey(apiKey);
|
||||
if (encryptedKey == null) // Если шифрование не удалось
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Создаем и добавляем магазин
|
||||
OzonStore newStore = new OzonStore(storeName, clientId, encryptedKey);
|
||||
_stores.Add(newStore);
|
||||
|
||||
// Сохраняем и обновляем список
|
||||
SaveStores();
|
||||
UpdateListBox();
|
||||
|
||||
// Очищаем поля ввода
|
||||
txtStoreName.Clear();
|
||||
txtEditClientId.Clear();
|
||||
txtEditApiKey.Clear();
|
||||
}
|
||||
|
||||
// --- Кнопка "Удалить выбранный" (Опционально) ---
|
||||
private void btnDeleteStore_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (lstStores.SelectedItem is OzonStore selectedStore)
|
||||
{
|
||||
if (MessageBox.Show($"Вы уверены, что хотите удалить магазин '{selectedStore.StoreName}'?", "Подтверждение", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
|
||||
{
|
||||
_stores.Remove(selectedStore);
|
||||
SaveStores();
|
||||
UpdateListBox();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Выберите магазин для удаления.", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Кнопка "Закрыть" ---
|
||||
private void btnClose_Click(object sender, EventArgs e)
|
||||
{
|
||||
this.DialogResult = DialogResult.OK; // Указываем, что форма закрыта штатно
|
||||
this.Close();
|
||||
}
|
||||
}
|
||||
}
|
120
FormManageStores.resx
Normal file
120
FormManageStores.resx
Normal file
@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
28
OzonStore.cs
Normal file
28
OzonStore.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using System;
|
||||
|
||||
namespace OzonInternalLabelPrinter
|
||||
{
|
||||
[Serializable] // Важно для возможной сериализации в будущем, хотя с JSON необязательно
|
||||
public class OzonStore
|
||||
{
|
||||
public string StoreName { get; set; } // Имя, которое видит пользователь
|
||||
public string ClientId { get; set; }
|
||||
public string EncryptedApiKey { get; set; } // Храним ЗАШИФРОВАННЫЙ ключ
|
||||
|
||||
// Конструктор для удобства
|
||||
public OzonStore(string name, string clientId, string encryptedKey)
|
||||
{
|
||||
StoreName = name;
|
||||
ClientId = clientId;
|
||||
EncryptedApiKey = encryptedKey;
|
||||
}
|
||||
|
||||
public OzonStore() { } // Пустой конструктор для сериализации
|
||||
|
||||
// Переопределяем ToString, чтобы в ComboBox отображалось имя
|
||||
public override string ToString()
|
||||
{
|
||||
return StoreName ?? "Без имени";
|
||||
}
|
||||
}
|
||||
}
|
23
Program.cs
Normal file
23
Program.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using OzonInternalLabelPrinter; // Добавляем директиву using для пространства имен с Form1
|
||||
|
||||
namespace SKLADm
|
||||
{
|
||||
internal static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// Главная точка входа для приложения.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new Form1());
|
||||
}
|
||||
}
|
||||
}
|
33
Properties/AssemblyInfo.cs
Normal file
33
Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,33 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// Общие сведения об этой сборке предоставляются следующим набором
|
||||
// набора атрибутов. Измените значения этих атрибутов для изменения сведений,
|
||||
// связанных со сборкой.
|
||||
[assembly: AssemblyTitle("SKLADm")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("SKLADm")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2025")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Установка значения False для параметра ComVisible делает типы в этой сборке невидимыми
|
||||
// для компонентов COM. Если необходимо обратиться к типу в этой сборке через
|
||||
// COM, следует установить атрибут ComVisible в TRUE для этого типа.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM
|
||||
[assembly: Guid("17f6818e-f645-43c4-a25a-eab41e5e1be6")]
|
||||
|
||||
// Сведения о версии сборки состоят из указанных ниже четырех значений:
|
||||
//
|
||||
// Основной номер версии
|
||||
// Дополнительный номер версии
|
||||
// Номер сборки
|
||||
// Редакция
|
||||
//
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
71
Properties/Resources.Designer.cs
generated
Normal file
71
Properties/Resources.Designer.cs
generated
Normal file
@ -0,0 +1,71 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// Этот код создан программным средством.
|
||||
// Версия среды выполнения: 4.0.30319.42000
|
||||
//
|
||||
// Изменения в этом файле могут привести к неправильному поведению и будут утрачены, если
|
||||
// код создан повторно.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace SKLADm.Properties
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Класс ресурсов со строгим типом для поиска локализованных строк и пр.
|
||||
/// </summary>
|
||||
// Этот класс был автоматически создан при помощи StronglyTypedResourceBuilder
|
||||
// класс с помощью таких средств, как ResGen или Visual Studio.
|
||||
// Для добавления или удаления члена измените файл .ResX, а затем перезапустите ResGen
|
||||
// с параметром /str или заново постройте свой VS-проект.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources
|
||||
{
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Возврат кэшированного экземпляра ResourceManager, используемого этим классом.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((resourceMan == null))
|
||||
{
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SKLADm.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Переопределяет свойство CurrentUICulture текущего потока для всех
|
||||
/// подстановки ресурсов с помощью этого класса ресурсов со строгим типом.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture
|
||||
{
|
||||
get
|
||||
{
|
||||
return resourceCulture;
|
||||
}
|
||||
set
|
||||
{
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
117
Properties/Resources.resx
Normal file
117
Properties/Resources.resx
Normal file
@ -0,0 +1,117 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
38
Properties/Settings.Designer.cs
generated
Normal file
38
Properties/Settings.Designer.cs
generated
Normal file
@ -0,0 +1,38 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// Этот код создан программой.
|
||||
// Исполняемая версия:4.0.30319.42000
|
||||
//
|
||||
// Изменения в этом файле могут привести к неправильной работе и будут потеряны в случае
|
||||
// повторной генерации кода.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace SKLADm.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.13.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
||||
public string SavedStoresJson {
|
||||
get {
|
||||
return ((string)(this["SavedStoresJson"]));
|
||||
}
|
||||
set {
|
||||
this["SavedStoresJson"] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
9
Properties/Settings.settings
Normal file
9
Properties/Settings.settings
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="SKLADm.Properties" GeneratedClassName="Settings">
|
||||
<Profiles />
|
||||
<Settings>
|
||||
<Setting Name="SavedStoresJson" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)" />
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
122
SKLADm.csproj
Normal file
122
SKLADm.csproj
Normal file
@ -0,0 +1,122 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{17F6818E-F645-43C4-A25A-EAB41E5E1BE6}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<RootNamespace>SKLADm</RootNamespace>
|
||||
<AssemblyName>SKLADm</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<Deterministic>true</Deterministic>
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Drawing.Common, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Drawing.Common.8.0.12\lib\net462\System.Drawing.Common.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security" />
|
||||
<Reference Include="System.Security.Cryptography.ProtectedData, Version=9.0.0.4, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Security.Cryptography.ProtectedData.9.0.4\lib\net462\System.Security.Cryptography.ProtectedData.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Deployment" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="zxing, Version=0.16.10.0, Culture=neutral, PublicKeyToken=4e88037ac681fe60, processorArchitecture=MSIL">
|
||||
<HintPath>packages\ZXing.Net.0.16.10\lib\net461\zxing.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="zxing.presentation, Version=0.16.10.0, Culture=neutral, PublicKeyToken=4e88037ac681fe60, processorArchitecture=MSIL">
|
||||
<HintPath>packages\ZXing.Net.0.16.10\lib\net461\zxing.presentation.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ZXing.Windows.Compatibility, Version=0.16.13.0, Culture=neutral, PublicKeyToken=4e88037ac681fe60, processorArchitecture=MSIL">
|
||||
<HintPath>packages\ZXing.Net.Bindings.Windows.Compatibility.0.16.13\lib\netstandard2.0\ZXing.Windows.Compatibility.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Form1.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Form1.Designer.cs">
|
||||
<DependentUpon>Form1.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="FormManageStores.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="FormManageStores.Designer.cs">
|
||||
<DependentUpon>FormManageStores.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="OzonStore.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<EmbeddedResource Include="Form1.resx">
|
||||
<DependentUpon>Form1.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="FormManageStores.resx">
|
||||
<DependentUpon>FormManageStores.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<None Include="packages.config" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<Compile Include="Properties\Settings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="packages\NETStandard.Library.2.0.3\build\netstandard2.0\NETStandard.Library.targets" Condition="Exists('packages\NETStandard.Library.2.0.3\build\netstandard2.0\NETStandard.Library.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>Данный проект ссылается на пакеты NuGet, отсутствующие на этом компьютере. Используйте восстановление пакетов NuGet, чтобы скачать их. Дополнительную информацию см. по адресу: http://go.microsoft.com/fwlink/?LinkID=322105. Отсутствует следующий файл: {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('packages\NETStandard.Library.2.0.3\build\netstandard2.0\NETStandard.Library.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\NETStandard.Library.2.0.3\build\netstandard2.0\NETStandard.Library.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
25
SKLADm.sln
Normal file
25
SKLADm.sln
Normal file
@ -0,0 +1,25 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.13.35913.81 d17.13
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SKLADm", "SKLADm.csproj", "{17F6818E-F645-43C4-A25A-EAB41E5E1BE6}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{17F6818E-F645-43C4-A25A-EAB41E5E1BE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{17F6818E-F645-43C4-A25A-EAB41E5E1BE6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{17F6818E-F645-43C4-A25A-EAB41E5E1BE6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{17F6818E-F645-43C4-A25A-EAB41E5E1BE6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {58FC063D-E3B8-421B-BCB0-0349A0C4DCDB}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
10
packages.config
Normal file
10
packages.config
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.NETCore.Platforms" version="1.1.0" targetFramework="net462" />
|
||||
<package id="NETStandard.Library" version="2.0.3" targetFramework="net462" />
|
||||
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net462" />
|
||||
<package id="System.Drawing.Common" version="8.0.12" targetFramework="net462" />
|
||||
<package id="System.Security.Cryptography.ProtectedData" version="9.0.4" targetFramework="net462" />
|
||||
<package id="ZXing.Net" version="0.16.10" targetFramework="net462" />
|
||||
<package id="ZXing.Net.Bindings.Windows.Compatibility" version="0.16.13" targetFramework="net462" />
|
||||
</packages>
|
Loading…
x
Reference in New Issue
Block a user