0

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

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
Dean
  • 17
  • 8
  • What happens if you just run the program *from* the console, just passing the filename in as an argument? That way you should get the full stack trace which you can copy and paste it into the question. Note that your code is flawed anyway, as you shouldn't be reading it as a string in the first place - just call `ComputeHash` passing in a stream instead. – Jon Skeet Oct 25 '13 at 21:20
  • @ Jon Skeet - Sure, can you answer how? – Dean Oct 25 '13 at 21:27
  • Well which bit are you stuck on? – Jon Skeet Oct 26 '13 at 08:01

1 Answers1

0

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
CodesInChaos
  • 106,488
  • 23
  • 218
  • 262