Link to home
Start Free TrialLog in
Avatar of mjelec
mjelec

asked on

Function as process

I am trying to get a program to work that starts robocopy.exe as a process, the problem I am running into is with the username used in the operation.  it seems that I cannot use this program on more then one computer.

With trial and error, I have gotten the process to work in a command line runas command with the /netonly flag.  but I am unsure how to do something similar with the function i have in my code.

Here is my code:

Imports System.Security

Module Module1

    Sub Main()

        Dim conConnection As New ADODB.Connection
        Dim cmdCommand As New ADODB.Command
        Dim rstRecordSet As New ADODB.Recordset

        conConnection.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
                "Data Source=\\SERVER\DATABASE.mdb;Mode=Read|Write"
        conConnection.CursorLocation = ADODB.CursorLocationEnum.adUseClient
        conConnection.Open()

        With cmdCommand
            .ActiveConnection = conConnection
            .CommandText = "SELECT * FROM TABLE;"
            .CommandType = ADODB.CommandTypeEnum.adCmdText
        End With

        With rstRecordSet
            .CursorType = ADODB.CursorTypeEnum.adOpenStatic
            .CursorLocation = ADODB.CursorLocationEnum.adUseClient
            .LockType = ADODB.LockTypeEnum.adLockOptimistic
            .Open(cmdCommand)
        End With

        If rstRecordSet.RecordCount <> 0 Then
            rstRecordSet.MoveFirst()

            Dim file As String
            file = "C:\robocopy.exe"

            Dim args As String
            args = "\\mje-imtmifile02\500div\Job_Files\5XXXXXXX-Template-New-Folders " & rstRecordSet.Fields(0).Value & " *.* /copyall /mir"
            Stop
            Dim username As String
            username = "USER"

            Dim pass As SecureString
            pass = Secure()

            Dim Dom As String
            Dom = "DOMAIN"

            Process.Start(file, args, username, pass, Dom)

        Else
            Exit Sub
        End If

    End Sub

    Public Function Start(fileName As String, arguments As String, userName As String, password As SecureString, domain As String) As Process
    End Function

    Public Function Secure() As SecureString
        Dim pass As String
        pass = "PASSWORD"
        Dim str As New SecureString
        For x As Integer = 0 To pass.Length - 1
            str.AppendChar(pass.Substring(x, 1))
        Next

        Return str
    End Function

End Module

Open in new window


The issue seems to be with my Start() function.  It seems to have to do with running a user across multiple computers.

any help would be appreciated.  or an alternative solution.
Avatar of Bob Learned
Bob Learned
Flag of United States of America image

If this is a Console application, then you should be able to pass in user name and password on the command line.
Avatar of mjelec
mjelec

ASKER

I have tried that with:

fileReader = My.Computer.FileSystem.ReadAllText("\\SERVER\test.txt")

testx = "runas /user:DOMAIN\USER " & Chr(34) & "\\SERVER\Template_New_Folders " & fileReader & " *.* /copyall /E" & Chr(34)
Dim objShell As Object
        objShell = CreateObject("Wscript.Shell")
        objShell.Run("cmd.exe")
        Thread.Sleep(1000)
        objShell.sendkeys(testx)
        Thread.Sleep(100)
        objShell.sendkeys("{enter}")
        Thread.Sleep(100)
        Dim pw As String = "Password"
        Dim i, n As Integer
        i = pw.Length
        n = 0
        Do While i > n
            Thread.Sleep(100)
            objShell.sendkeys(Mid(pw, n + 1, 1))
            n = n + 1
        Loop
        Thread.Sleep(100)
        objShell.sendkeys("{enter}")
        Thread.Sleep(100)

Open in new window


the issue with this is that if the command window loses focus then it types into whatever has focus.
May I ask what you are trying to achieve with this application?
Avatar of mjelec

ASKER

I am trying to copy a folder structure that has preexisting permissions, in order to keep the permissions in place I need to run the robocopy command as an administrative account.  I am trying to create an application that allows for anyone to run the application while keeping the account details secure.

Now I dont know if robocopy is the best method, but its the only one I have found that will copy the folder permissions.
The Process StartInfo properties let you specify a user name and password when executing an external application, as shown in this example:

How to Launch an external process from a .NET program
http://galratner.com/blogs/net/archive/2009/04/26/how-to-launch-an-external-process-from-a-net-program.aspx

if (!string.IsNullOrEmpty(userName))
   processStartInfo.UserName = userName;

if (!string.IsNullOrEmpty(password))
{
      processStartInfo.Password = new System.Security.SecureString();
      char[] passwordChars = password.ToCharArray();
 
      foreach (char c in passwordChars)
          processStartInfo.Password.AppendChar(c);
}

Open in new window

Avatar of mjelec

ASKER

alright, before i start down another path again, do you know if this will let multiple users use the same credentials?  In my original code it would not allow this.
I need to make sure that I understand what you mean by "same credentials".  I was thinking that you pass in the user name and password to the calling application as command line arguments, but it sounds like that is not exactly what you are looking for.
Avatar of mjelec

ASKER

I have an account setup with the proper administrative rights, the point is that i need to use that account for the process.

so far it seems like when I start the process it locks up that administrative account to my profile or something.  if i try to run the same process on another person's account it gives me errors.
Can you describe some typical use cases for this application?  If you are trying to hide credentials, then including them in an ASCII text file is not secure.  Passing them in as command line arguments is not secure, since someone would need to know the password.  

Do you really need to hide the credentials, as this is pretty difficult to achieve?
Avatar of mjelec

ASKER

The process should be like this:

1. User wants to create a job folder structure and enters the folder name and other relevant information.
2. User runs this executable that already contains the credentials of the administrative account.
3. executable runs robocopy as the administrative account to preserve the permissions of the template folders.  reading a database for the information provided by the user.

I am open to changing any of the steps, I just need the administrative account information to be out of the hands of the user.
I am confused.  

If you include the administrative account information in the application, and pass it to the Process.StartInfo.UserName and Process.StartInfo.Password, it should open the process with those credentials.

You would need to use the non-shared (or non-static) form, as in this example:

Dim process As New Process()
process.StartInfo.FileName = fileName
process.StartInfo.UserName = userName
process.Password = New SecureString()

For Each (ch As Char in password.ToCharArray())
    process.StartInfo.Password.AppendChar(ch)
Next

process.Start()
Avatar of mjelec

ASKER

that works, the whole thing works, but when i try to run it on another computer, it crashes.


An unhandled exception of type 'System.InvalidCastException' occurred in ConsoleApplication3.exe

Additional information: Unable to cast COM object of type 'ADODB.ConnectionClass' to interface type 'ADODB.Connection'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{00001550-0000-0010-8000-00AA006D2EA4}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).


I assumed it had to do with a user credential thing because when i was using the runas command in command prompt i needed to use the /netonly flag to get it to work on another computer.
That is a completely different problem.  That sounds like a mismatch between the ADODB versions installed on each computer.

Look at the file version for msado15.dll.  That file is in the C:\Program Files\Common Files\System\ado folder for me.

I have Windows 7, and the file version is 6.1.7601.17514.
Avatar of mjelec

ASKER

Alright that has been resolved, but another error is happening:


An unhandled exception of type 'System.ComponentModel.Win32Exception' occurred in System.dll

Additional information: The directory name is invalid


When I break it is on the Process.Start(file, args, username, pass, Dom).

When I have that user put his own credentials in the executable it works.  but when he tries using the credentials of the administrative account it errors out.
The administrative account should have access rights to that folder, but you need to validate that assumption.
Avatar of mjelec

ASKER

yes, it does.  the problem is that i can run this program with the admin account on my computer, but when it runs on another computer it then errors out, the identical code.  but if we change the credentials in the code for the actual users credentials it works.  but it does not copy the permissions.

So the issue seems to be that the administrative credentials are locked to my credentials or something.

We fixed this issue using the runas command in command prompt with the /netonly flag.  but with this process.start function i cant seem to find a solution.
Where is this application running from on the other computer?  Is it running from a network share, or the local machine?

What is the operating system for the target machine?
Avatar of mjelec

ASKER

We are both running win 7 64x SP1.  the application is to be run from the users C:.
ASKER CERTIFIED SOLUTION
Avatar of Bob Learned
Bob Learned
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial