Сохранить строку внутри программы - C#
Формулировка задачи:
Задача такая: консольная программа предлагает ввести строку и сохраняет ее внутри программы. При следующем запуске программы, она вначале выводит сохраненную строку, а потом предлагает сохранить новую строку и т.д.
Проблема в том, что сохранить строку надо внутри екзешника как ресурс. Вот только как этот ресурс изменять каждый раз при запуске программы?
Решение задачи: «Сохранить строку внутри программы»
textual
Листинг программы
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.IO;
using System.Threading;
using System.Diagnostics;
namespace ConsoleApplication1
{
class Program
{
[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Ansi)]
static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)]string lpFileName);
[DllImport("kernel32.dll")]
static extern IntPtr FindResource(IntPtr hModule, IntPtr lpName, IntPtr lpType);
[DllImport("kernel32.dll")]
static extern IntPtr FindResource(IntPtr hModule, int lpName, int lpType);
[DllImport("kernel32.dll")]
static extern IntPtr FindResource(IntPtr hModule, int lpName, string lpType);
[DllImport("kernel32.dll")]
static extern IntPtr FindResource(IntPtr hModule, string lpName, int lpType);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr FindResource(IntPtr hModule, string lpName, string lpType);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr LoadResource(IntPtr hModule, IntPtr hResInfo);
[DllImport("kernel32.dll")]
static extern IntPtr LockResource(IntPtr hResData);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr BeginUpdateResource(string pFileName,
[MarshalAs(UnmanagedType.Bool)]bool bDeleteExistingResources);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool UpdateResource(IntPtr hUpdate, string lpType, string lpName, ushort wLanguage, IntPtr lpData, uint cbData);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool EndUpdateResource(IntPtr hUpdate, bool fDiscard);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool FreeLibrary(IntPtr hModule);
[DllImport("kernel32.dll", SetLastError = true)]
static extern uint SizeofResource(IntPtr hModule, IntPtr hResInfo);
static void Main(string[] args)
{
string filename = args[0];
string oldpassword = args[1];
string newpassword = args[2];
bool sucess = false;
int timeoutcounter = 0;
while (!sucess && timeoutcounter < 30)
{
try
{
using (var fs = File.Open(filename, FileMode.Open, FileAccess.ReadWrite))
{
sucess = true;
break;
}
}
catch { Thread.Sleep(200); timeoutcounter++; }
}
if (timeoutcounter == 30) { Process.Start(filename, "fucked_up"); return; }
try {
if (ChechIsPasswordCorrect(filename, oldpassword))
{
ChangePassword(newpassword, filename);
Process.Start(filename, "all_ok");
}
}
catch { Process.Start(filename, "fucked_up"); }
}
static bool ChechIsPasswordCorrect(string filename, string oldpassword)//тут проверяем правильность пароля в ресурсах
{
SHA512Cng crypt = new SHA512Cng();
var hExe = LoadLibrary(filename);
var hRes = FindResource(hExe, "BRED_ZAKAZCHIKA", "BRED_ZAKAZCHIKA");
var hResLoad = LoadResource(hExe, hRes);
var lpResLock = LockResource(hResLoad);
if (lpResLock == IntPtr.Zero) { throw new Exception(); }
uint size = SizeofResource(hExe, hRes);
byte[] managedArray = new byte[size];
Marshal.Copy(lpResLock, managedArray, 0, (int)size);
FreeLibrary(hExe);
byte[] oldpasswordbytes = crypt.ComputeHash(Encoding.UTF8.GetBytes(oldpassword));
return oldpasswordbytes.SequenceEqual(managedArray);
}
static void ChangePassword(string newpassword,string filename)//тут меняем его
{
SHA512Cng crypt = new SHA512Cng();
var encodedpassword = crypt.ComputeHash(Encoding.UTF8.GetBytes(newpassword));
IntPtr unmanagedPointer = Marshal.AllocHGlobal(encodedpassword.Length);
Marshal.Copy(encodedpassword, 0, unmanagedPointer, encodedpassword.Length);
var hUpdateResource = BeginUpdateResource(filename, false);
var result = UpdateResource(hUpdateResource, "BRED_ZAKAZCHIKA", "BRED_ZAKAZCHIKA", MAKELANGID(0x00, 0x03), unmanagedPointer, (uint)encodedpassword.Length);
var end = EndUpdateResource(hUpdateResource, false);
Marshal.FreeHGlobal(unmanagedPointer);
}
static public ushort MAKELANGID(byte primaryLanguage, byte subLanguage)
{
return (ushort)((((ushort)subLanguage) << 10) |
(ushort)primaryLanguage);
}
static public byte PRIMARYLANGID(ushort languageId)
{
return (byte)(languageId & 0x3ff);
}
static public byte SUBLANGID(ushort languageId)
{
return (byte)(languageId >> 10);
}
}
}