Jump to content
Strawberry Orange Banana Lime Leaf Slate Sky Blueberry Grape Watermelon Chocolate Marble
Strawberry Orange Banana Lime Leaf Slate Sky Blueberry Grape Watermelon Chocolate Marble

MSFN is made available via donations, subscriptions and advertising revenue. The use of ad-blocking software hurts the site. Please disable ad-blocking software or set an exception for MSFN. Alternatively, register and become a site sponsor/subscriber and ads will be disabled automatically. 


Recommended Posts

Hi MSFN! Long time lurker, first time poster.

I'm looking for some help writing a simple GUI to drive command line scripts.

Here's a bit of preamble:

I work in a PC repair shop. I am in the process of converting all of our OEM install discs to slipstreamed, unattended installs.

I would like to make a simple program to run at first boot that will automate Windows Activation in Windows Vista/7.

Note: This program is NOT intended to bypass, crack or otherwise circumvent Genuine Windows activation!

We will be using our own OEM product keys for the unattended install, then we MUST change them to the customers' genuine product key. We're not a sleazy "warez" shop that distributes pirated software.

Now, I don't need help with any of the unattend setup, just writing the program. I have no programming experience, and I figured it would make more sense to ask for help with the code because this is such a simple program.

I will compile this is Visual C++ or VB 2010 Express, or whichever software you recommend.

I've been told the easiest way to do this kind of activation is to call a batch program.

“slmgr.vbs -ipk <insert your new product key here>”

To change the key

and

“slmgr.vbs -ato”

To activate Windows

I'd like some help or tips writing this program. It will have 3 buttons:

One to change the key, which will create an input field with text like "Enter new key", and insert that input into the batch with the "slmgr.vbs -ipk"

One to run Keyfinder, to verify the newly installed Key (just assume Keyfinder is named 'Keyfinder.exe')

One to run the “slmgr.vbs -ato” to activate GENUINE Windows with the new key.

I might need help using variables in the batch as well; I haven't even done batch programming in a long time!

Your help is greatly appreciated and if you live anywhere in MI I'll buy you a drink sometime!

Share this post


Link to post
Share on other sites

Upon doing some googling, it seems that creating an HTA and having it call VBscripts is another option.

Whichever way someone can help me with, I'm forever in your debt!

Share this post


Link to post
Share on other sites

If you say you have no programming experience, I'd say pick something easy, either C# or VB 2010 (mainly depending if you prefer C-like or VB-like syntax better). C++ is more complicated to learn, and it requires the VC++ runtime to be installed, whereas C# and VB apps will work out of the box on Win 7.

You can use slmgr to do this (activating & such), or you can use a number of underlying APIs to do this.

Personally I make WMI calls to take care of it (very much like slmgr.vbs does itself) which should be fairly easy in either language, or even in VBScript/JScript. That's a LOT of fun in C++ though -- you have to call CoInitializeEx, then CoInitializeSecurity, then CoCreateInstance to get a IWbemLocator object, then its ConnectServer method, then CoSetProxyBlanket, then exec a query using its ExecQuery method so you can use an actual instance of the SoftwareLicensingService class (iterating through the collection), to then call GetObject on it, so you can get a pointer to its InstallProductKey method, for which you have to add a parameter (using a VARIANT type), to finally call its ExecMethod method -- plus all the necessary memory allocation/freeing (SysAllocString/malloc/...), error handing on every API call (checking the returned HRESULT, etc) and other fun stuff like that. Obviously, using WMI is a lot easier in C# or VB. Or you could make calls to the underlying APIs (that would me more "proper" in a way), but those basically are not documented, and not exactly what I'd call "easy to use" either (reverse engineer it to figure out the arguments, etc). Then again, you can just call slmgr too. Making a GUI app in C++ (i.e. a MFC app, although you could go C++/CLI instead) has a much steeper learning curve (i.e. working with the message loop vs WinForms or even WPF with C# or VB)

As for using a batch program, it's really not a whole lot easier to do than VB or C# IMO, and you don't get a very fancy GUI there either, and you're quite limited in many ways. You can also integrate your very own "Keyfinder" in the app itself with C# or VB (no need for an external app for that). HTA is another option indeed. It's better if your HTML + CSS + either VBScript or JScript knowledge is already up to par (or you intend to run this on older OS'es w/o the .NET framework already built-in such as XP), otherwise there's not much reason to pick that over C# or VB. There's always AutoIt too...

You'll have to make the language choice by yourself. I'm purposely not including a 100% pre-made app to do this (yes, you can call me a bast****) just so you can learn some stuff along the way. This is very much beginner's stuff (especially if you just call slmgr & an external key decoder) and you can definitely handle it.

If you choose C# or VB you can grab Visual C# or VB Express which is more than adequate for the job. Then have a look at this page, which is the official documentation on how to start another process. Pick the method with the signature that suits you better -- probably "Start(String)" -- and check the sample code provided. That's 90% of the job right there (starting the 3 apps). All of this can be done in 3 lines of code total if you use slmgr.vbs and an external keyfinder app (it would have been FAR quicker to write it for you than writing this post). At least give it a shot :) You can do it!

Share this post


Link to post
Share on other sites

Thank you very much for the tips.

There is a bit more to it than just calling 3 external programs though.

I need a text/input field and the ability to manipulate the input of that field and insert it into the slmgr.vbs -ipk command.

It's this particular step that's troublesome.

I think I will do this with an HTA, as I already have some html knowledge.

So the next question is, how do I take the input from the HTA text box and pass it as an argument to a command?

Share this post


Link to post
Share on other sites

I can already see that this is going to need to be in the Programming section - moved.

Share this post


Link to post
Share on other sites

There is a bit more to it than just calling 3 external programs though.

I need a text/input field and the ability to manipulate the input of that field and insert it into the slmgr.vbs -ipk command

That's pretty much part of the leftover 10% (that, and building a simple GUI).

I think I will do this with an HTA, as I already have some html knowledge.

So the next question is, how do I take the input from the HTA text box and pass it as an argument to a command?

The HTML knowledge will help a little bit creating the GUI (you also need some CSS knowledge for that too if you want it to look any good), but that's about it (it's not just straight HTML, there's also the HTA "header" part). The code that will execute commands will be either VBScript or JScript. There is no way around knowing the basics either language, to either run the external apps or using DOM (yes, you also have to understand the basics of that) to get the content of a specific textbox using getElementById or a similar method. Actually, making a HTA version of this is a lot more complex than a C# or VB version ;) (No need to know HTML markup and the HTA bits + CSS for styling + VBScript or JSCript to make it do something + also DOM to interact with the form -- you just need basic understanding of one simple language)

Share this post


Link to post
Share on other sites

Ok, so I've decided to go the easiest route possible, which is probably VB 2010 Express :)

I have the basic form and I've added the 3 buttons.

For some reason, most likely my inexperience, it's not letting me copy the entire code for the entire project to paste here..?

Anyway here's the basic form, with 1 of the buttons..

Public Class Form1

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button0.Click

End Sub
End Class

The buttons are all labeled, sized and positioned. Now I need to add functionality to them!

I've done a mental flowchart and improved the basic layout for the little program.

The first button is "Change Product Key"

The second button is "Verify Key" (launches Keyfinder.exe)

The third button is "Activate Windows"

"Change Product Key" will clear the form, have an input field and the text "Change Product Key" above it. Two new buttons will appear below the input field, "Change Key" which will enter the command "slmgr.vbs -ipk *****-*****-*****-*****-*****", where asterisks are obviously the product key, and a "Cancel" key, which brings the main window back up.

"Verify Key" launches Keyfinder.exe

"Activate Windows" Will enter "slmgr.vbs -ato"

How do I tie all of that functionality to the "Change Product Key" button? IE Clear the window of all buttons, add input field, add two new buttons, take input from the input field and add it as a variable to the end of "slmgr.vbs -ipk" and execute that command with the "Change Key" button? And have the "Cancel" button return to the main window?

Once I clear this hurdle, I'm pretty much done.

I've googled code for the input field, and came up with this:

Public Function InputBox( _
ByVal Prompt As String, _
Optional ByVal Title As String = "", _
Optional ByVal DefaultResponse As String = "", _
Optional ByVal Xpos As Integer = -1, _
Optional ByVal YPos As Integer = -1 _
) As String

with the following example included:

Dim message, title, defaultValue As String
Dim myValue As Object
' Set prompt.
message = "Enter a value between 1 and 3"
' Set title.
title = "InputBox Demo"
defaultValue = "1" ' Set default value.

' Display message, title, and default value.
myValue = InputBox(message, title, defaultValue)
' If user has clicked Cancel, set myValue to defaultValue
If myValue Is "" Then myValue = defaultValue

' Display dialog box at position 100, 100.
myValue = InputBox(message, title, defaultValue, 100, 100)
' If user has clicked Cancel, set myValue to defaultValue
If myValue Is "" Then myValue = defaultValue

More google returns the basic syntax for explicitly declaring a variable:

Dim VariableName As DataType
Static VariableName As DataType
Private VariableName As DataType
Public VariableName As DataType

So I'm very close to tying this all together but more confused than ever :-s

Since I've put in the effort to get this all started, can you point me in the right direction with an example?

Share this post


Link to post
Share on other sites

Ok, so I've decided to go the easiest route possible, which is probably VB 2010 Express :)

That's about as easy as it gets, yeah.

I have the basic form and I've added the 3 buttons.

That's 3/4 of the simple GUI done, now I would add a textbox where you can type in the serial number too, without having extra forms or hiding stuff just yet. One thing at a time, then once that works start doing small changes one by one after.

The code you pasted uses an InputBox though, not textboxes. Have a look again at this link. It shows you how it runs an executable (Internet Explorer) with and without arguments to it (an URL). Basically, you add "Imports System.Diagnostics" at the top then use "Process.Start" to do it. To use the text typed in a textbox, just use it's ".Text" property i.e. if it's called TextBox1 then use TextBox1.Text

Now try to use that to pass it as an argument (perhaps to pass as an URL to IE), or you can try to run something else like the windows calculator (calc.exe) and such. Play with it until you got it figured out, then after that you can make it execute slmgr instead.

You're getting there.

Share this post


Link to post
Share on other sites

Ahh ok, this really is much simpler than I thought it would be, thanks for the tips.

I'm about to try and add the "Imports System.Diagnostics", which naturally won't work and I'll be back in a few mins excited to troubleshoot the next step! Thanks again :)

Share this post


Link to post
Share on other sites

Ok! It didn't work! :)

It probably would help if I knew where I was adding the snippet or what I was doing lol.

Public Class Form1

Private Sub Button0_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button0.Click
Imports System.Diagnostics
'Declaration

Public Shared Function Start( _
ByVal fileName As String _
) As Process

End Function
End Class

imdoinitrong :)

Without even specifying the process I want to start (or because..?), I have a syntax error, a Statement cannot appear with a method body error, and a Function 'Start' doesn't return a value on all code paths warning!

Share this post


Link to post
Share on other sites

"Imports System.Diagnostics" goes at the top most part (the absolute very first line) of the code. Then it'll work.

Share this post


Link to post
Share on other sites

Imports System.Diagnostics
Public Class Form1

Private Sub Button0_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button0.Click

'Declaration

Public Shared Function Start( _
ByVal fileName As String _
) As Process

End Function
End Class

Thanks for clearing that up. That cleared the Syntax error; the other two errors remain.

I naturally assumed I wanted this to be placed right under the Button0 line, because that's what the button would be doing correct?

So, where do I add Process.Start, and what is the syntax? Like Process.Start ie.exe -argument?

Share this post


Link to post
Share on other sites

You don't have to use any kind of declaration, just use the Process.Start method

Try this:


Imports System.Diagnostics

Public Class Form1

Private Sub Button0_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button0.Click
Process.Start("calc.exe")
End Sub
End Class

Then perhaps:


Imports System.Diagnostics

Public Class Form1

Private Sub Button0_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button0.Click
Process.Start("explorer.exe", "C:\Windows\System32")
End Sub
End Class

See where this is heading?

Share this post


Link to post
Share on other sites

Indeed! And not to miss out on where this is heading:

Process.Start("cmd.exe")

Would I be using CMD to eventually enter the command?

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...