Максим Тимофеев, формат SVG многие поддерживают, а с интерфейсом, сами понимаете - на вкус все фломастеры разные.
Но, наверное, вам для этих целей не подойдёт... впрочем, в CAD системах почти везде есть расширенная поддержка автоматизации (скрипты), если необходимо просто выполнять трансформации, то их и заскриптовать можно.
И так, ещё раз, дырявыми бывают программы, а не языки
Немножко позанудничаю - разумеется дырявыми бывают только программы. Но что в наше время есть программа? Скажем, стандартная библиотека языка (C# или PHP - пофигу), это ведь тоже программа?
И много эксплойтов нацеливаются на стандартные реализации стандартных методов стандартных библиотек. Если пишешь на голом asm, разумеется, всё зависит от вас. Если ипользуешь чей-то код (пусть даже и код от создателя самого языка), уже есть нюансы.
В этой связи выбор между "голым" php и голым .Net Framework действительно одинаков, однако, читаем "php", имеем в виду php + какой-нибудь новомодный CMS. И если опасные zero-day дырки в стандартной библиотеке закроют в течение нескольких часов или дней, то для CMS это уже не факт.
Если уж рассматривать с точки зрения безопасности, то я бы предпочёл ASP.Net
Ну и ещё дополню - php позволяет программисту спокойно выстрелить себе или пользователю в ногу, и прощает многие ошибки, коих .NET Framework даже не скомпилирует. Отсюда в php качество кодовой базы (вообще целиком) несколько хуже, чем для .Net, потому что ниже порог вхождения и, соответственно, больше некачественного кода.
Это не значит, что php - плохо, это значит, что с php надо внимательнее следить, чей код ты используешь в проекте и какого он качества.
lam0x86, Каюсь, про сборку не посмотрел. Под Winforms она обычно сразу установлена, а кроме как в Winforms этот класс не использовал.
Ваше решение подходит, разве что ссылку на инициирующий объект добавить.
Вас отправляю туда же.
Не занимайтесь изобретением велосипедов.
Кроме того, чтобы предупреждение ушло, надо соблюдать сигнатуру event (object, EventArgs)
В первом параметре передаётся ссылка на объект, сгенерировавший событие, во втором - наследник от EventArgs, в котором передаются доп. параметры, если необходимо.
Smilleey, Я так понял, товарищу надо какое-то другое приложение прибить и перезапустить (не исполняемое в настоящий момент) - у него не написано, что надо это произвести со своим приложением.
Уж очень похоже, что тогда зловред какой-то создаётся. Но тогда обычно в паре работают два процесса, и один следит за другим (прибиваешь первый, второй его перезапускает, прибиваешь второй и т. д.), в общем надо suspend делать двум сразу, потом прибивать.
По хорошему, лучше сначала прибить, потом переместить (некоторые процессы лочат свои исполняемые модули).
Ещё некоторым нужны привилегии администратора, чтобы прибить.
Artem0071, Только имейте в виду, что при таком подходе, нужно удостовериться, что пользователь будет просматривать уведомления исключительно в порядке их поступления.
То есть, он не может прочитать более позднее, пока не прочитает более раннее - увы, это "плата" за меньший объём хранимых данных.
Artem0071, А, тогда подумайте над тем, стоит ли вообще хранить статус "прочтено/не прочтено", ибо это будет массив данных кол-во пользователей * кол-во уведомлений.
Чтобы его уменьшить, можно, например, с уведомлениями хранить дату/время. Тогда у пользователя можно хранить только 1 параметр (дату/время), на которую предполагается, что все уведомления прочитаны.
Например:
1.11 - "Уведомление 1"
2.12 - "Уведомление 2"
5.12 - "Уведомление 3"
У пользователя хранится дата 2.12, соответственно, мы знаем, что он прочитал уведомления 1 и 2, но не прочитал уведомление 3.
Вместо даты можно использовать идентификатор последнего прочитанного сообщения, подразумевая, что идентификаторы нумеруются по возрастанию
Ну а многоязычность - повторяю, уведомления сами отдельно храните с идентификаторами., например:
ID=4, DATE=2017-11-16, TYPE=2, PARAM=4
А текстовую часть отдельно:
TYPE=2 CULTURE="Ru-Ru" TEXT="Ваш платёж не выполнен в связи с {}" )
Вместо {} указываем (если PARAM=4 - "недостаточностью денег на счёте")
И то же самое по английски
TYPE=2 CULTURE="En-Us" TEXT="Your payment has not been processed due {})
PARAM=4 {"Insufficient account balance"}
Griboks, вполне возможно, что этого и достаточно. "Знайте своего врага", кто ваш злоумышленник, что он может, а что - нет, что ему нужно и пр. Понимание того, от кого именно вы защищаетесь - от спецслужб или от школьника, который хочет сжульничать в игре, сильно помогает в оптимизации затрат на защиту.
Griboks, в целом - никак (я серьёзно). Мне не известно ни одно десктопное приложение, которое бы не было рано или поздно взломано (кроме, конечно, "неуловимых Джо", которые не взламывают не потому, что там сложная защита, а потому что это нахрен никому не надо).
Ваш программный код всегда можно загрузить в дебаггер и подвергнуть реверс-инжинирингу. Частично в этом помогает обфускация, но это лишь усложняет атаку, а не предотвращает её.
В компьютерной безопасности есть понятие "модель угроз". Защиты на 100% добиться невозможно никакими способами, поэтому определяют ключевые угрозы, от которых неободимо защищаться.
Например, модель "случайный доступ" - защита в виде пароля
модель "случайное прочтение" - защита в виде "звёздочек" при вводе пароля.
и т. д. от простого к сложному (именно так, потому что злоумышленник не будет дизассемблировать ваше приложение, если имеются более простые способы).
Вы не можете никак защитить приложение на десктопе, ваша задача - сделать взлом экономически не выгодным, когда затраты времени/ресурсов/денег не окупают ценности получаемой информации.
Если у вас клиент-серверная архитектура, ключевые данные лучше всего хранить на контролируемой и более безопасной стороне.
Griboks, от чтения не защитите. Даже если кэш зашифрован, приложение должно располагать ключом для его расшифровки, следовательно, этот ключ будет так же доступен злоумышленнику. Получить его можно либо "подслушивая" трафик между клиентом и сервером, либо просканировав память компьютера, на котором выполняется приложение. Соответственно, расшифровав содержимое, злоумышленник так же может его изменить.
В целом, применяемая вами модель защиты, может и действенна на уровне домохозяек и "продвинутых пользователей", но не представляет абсолютно никакой защиты против целенаправленной атаки. Правило обычно простое - всё, что вы передаёте клиенту, доступно врагу. Секретные данные лучше хранить на сервере.
Griboks, Ну вам виднее, только если злоумышленник контролирует машину с какой-либо стороны, разумно в модель угроз вводить предположение, что ему доступны все ресурсы этой машины. В принципе исходите из того, что соединение скомпрометировано - вся передаваемая информация доступна злоумышленнику, т. .к от man-in-the-middle вы не убережетесь никак.
Отсюда вывод - трафик должен быть зашифрован. Обмен ключами по протоколу Диффи-Хеллмана. Но в целом, это тоже не даёт 100% гарантии.
Griboks, учитывая, что cef - опенсорсный на базе хромиум, даже если сейчас нет такого эмулятора (в чём я сомневаюсь), но мне очень надо, то я его напишу.
Да и вообще, вы как отличаете, подключился к вам cef или обычный браузер?
Дмитрий Королев, Думаю, там не текстбокс (хотя, я гта не видел). Думаю, там ловятся нажатия клавиш и потом нужный символ отображается (отрисовывается) в нужном месте.
nabokovsafran, Но любое "преступление" оставляет за собой финансовый след.
Тонкий момент - оплата. Анонимный безналичный платёж - это нонсенс, разве что за криптовалюту (биткойны), да и то... отследить, с какого кошелька пришла оплата, а потом посмотреть, откуда на этот кошелёк поступали деньги, в принципе, тоже можно. Рано или поздно цепочка выведет на биржу и перевод фиатных денег. Исходить надо из предположения, что биржа крипты продаст вас с потрохами (так и есть в большинстве случаев). В общем, финансовая анонимность - самая сложная часть.
В целом, для обеспечения полной анонимности надо ещё быть уверенным, что любые соединения с ресурсами хостинга осуществляются через VPN или прокси (а лучше - через цепочку). Если подключаться через браузер - обеспечить неидентифицируемость "отпечатка браузера" (лучше всего подойдёт дефолтный IE, развёрнутый на виртуальной машине).
Но, наверное, вам для этих целей не подойдёт... впрочем, в CAD системах почти везде есть расширенная поддержка автоматизации (скрипты), если необходимо просто выполнять трансформации, то их и заскриптовать можно.