سؤال

I am trying to create a console or form where you would drag a file onto their respective .exe The program would get that file and hash it, then set the clipboard text to the proviously generated hash.

This is my code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.Windows.Forms;
using System.IO;

namespace ConsoleApplication1
{
class Program
{
    static void Main(string[] args)
    {
        string path = args[0];          
        StreamReader wer = new StreamReader(path.ToString());
        wer.ReadToEnd();
        string qwe = wer.ToString();
        string ert = Hash(qwe);
        string password = "~" + ert + "~";
        Clipboard.SetText(password);
    }

    static public string Hash(string input)
    {
        MD5 md5 = MD5.Create();
        byte[] inputBytes = Encoding.ASCII.GetBytes(input);
        byte[] hash = md5.ComputeHash(inputBytes);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < hash.Length; i++)
        {
            sb.Append(hash[i].ToString("X2"));
        }
        return sb.ToString();
    }
}
}

When I get the single .exe from the release, and drag a file onto it, I get some sort of threading error- I can't provide it because it is in the console, not in vb2010. Thanks for any help

هل كانت مفيدة؟

المحلول

Clipboard API uses OLE internally and thus can only be called on a STA thread. Unlike WinForms applications, console applications aren't using STA by default.

Add the [STAThread] attribute to Main:

[STAThread]
static void Main(string[] args)
{
    ...

Just do what the exception message told you to:

Unhandled Exception: System.Threading.ThreadStateException: Current thread must be set to single thread apartment (STA) mode before OLE calls can be made. Ensure that your Main function has STAThreadAttribute marked on it.


Cleaning up your program a bit:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Windows.Forms;

namespace HashToClipboard
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            string hexHash = Hash(args[0]);
            string password = "~" + hexHash + "~";
            Clipboard.SetText(password);
        }

        static public string Hash(string path)
        {
            using (var stream = File.OpenRead(path))
            using (var hasher = MD5.Create())
            {
                byte[] hash = hasher.ComputeHash(stream);
                string hexHash = BitConverter.ToString(hash).Replace("-", "");
                return hexHash;
            }
        }
    }
}

This has several advantages over your program:

  • It doesn't need to load the whole file into RAM at the same time
  • It returns the correct result if the file contains non-ASCII characters/bytes
  • It'd shorter and cleaner
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top