 |
|
 |
I tried to run your nice demo. Unfortunately I get always error "The service cannot be started, either because it is disabled or because it has not enabled devices associated with it".
I am running demo with administrator user.
Is this a new "security" patch or someting...
Best Regards, Jake
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
It seems to start program in other PC that have logged power user account and I get to demo administrator rigths.
The program try to load ipfltdrv driver but it get still error in loading. Do you have any idea to fix it???
Jake
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Look in your Windows Services (start>run>services.msc) and you should see a Microsoft service (I think it's actually called Runas) that has to be enabled and started or else the WinAPI that my class uses is not available.
Dewey Vozel
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
 |
Just Another Info ,in Windows 2000 the service is "RunAs" , in Windows 2003 /XP the service is "Secondary Logon"
Thanks Naresh
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
meaning i have a machine with a local administrator login to it and not a domain user (MyMachineName\admin). can i runas it and use the domain? how can i do it? great app!
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I have an asp.net 1.1 app that I need to call an exe from across the network. I need to use something like this... will this work for me?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I have never tried it. I think that code access security will prevent it though. I'm not into ASP.NET though, so I could be mistaken.
-=( atchr )=-
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
This is a great class. I kept getting "...failed to init properly (0xc0000142)" error when using System.Diagnotics.Process directly. I found thru another source that I needed to set the StartInfo.lpDesktop = @"winsta0\default". This solution solved that major headache, however, I still need the stream redirection of the Process class. Anyone taken the trouble to do that or would know how? I don't see it.
Thanks, Dave
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
 |
Thanks for the feedback. I started working on a class but because of my schedule it has been sitting around 80% complete like many of my other solutions that I'd love to share.
Hopefully I'll get to finish some of them before they are made obsolete by some point-and-click features that will be added in future versions of VS.NET and the dotnetfrx to make it even easier for 10 year olds to write software without understanding any underlying concepts. (not pointed at you...just venting...the doctors say it's healthy)
-=( atchr )=-
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I don't see any mention of the license that you wish to release the source code under. I was wondering whether you were releaseing it into the public domain or under a bsd style license or some other more restrictive license?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
You can use it, I'd appreciate if you leave the author information in the files...but other than that I don't care for now.
-=( atchr )=-
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I am running a service with desktop interaction under an administrator account. I can't use CreateProcessWithLogonW under the System account because it's not allowed in SP2 and in W2003.
I get the following error when trying to run notepad:
The application failed to initialize properly (0xc0000142). Click on OK to terminate the application. The process lies in the task manager with the right username but exits as soon as I click ok.
I am only using username, domain, password and commandline. Do I have to specify anything more to create a window?
thanks,
Henrik
|
| Sign In·View Thread·PermaLink | 2.67/5 (3 votes) |
|
|
|
 |
|
 |
See my last post of a few minutes ago. I'm wanting to spawn processes from a Windows Service also. I found I needed to set the desktop member of StartInfo struct.
Dave
|
| Sign In·View Thread·PermaLink | 1.00/5 (2 votes) |
|
|
|
 |
|
 |
EyeHatePickingScreenNames wrote: I'm wanting to spawn processes from a Windows Service also. I found I needed to set the desktop member of StartInfo struct.
I've encountered another problem: my Windows Service starts a process which needs access to a network share. This process uses the correct username an domain but the networking rights got lost. If the process is started manually everything works fine. Any ideas?
Thanks, Martin
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
While very useful in leading me down the path, I didn't wind up using Dewey's code as is. I later found that CreateProcessWithLogon doesn't honor the lpDesktop member of the startup info which needs to be "" in this scenario. So, you have to use LogonUser, DuplicateTokenEx, LoadUserProfile (depending on app being started), and finally, CreateProcessAsUser.
If you do all that and your process still doesn't behave as if running from the command prompt, then something else is wrong. I routinely start processes that access the network. For example, copying files to shares and running rsh/ssh commands to Unix boxes. It was a long road getting there tho.
Dave
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
 |
davelogie wrote: I later found that CreateProcessWithLogon doesn't honor the lpDesktop member of the startup info which needs to be "" in this scenario. So, you have to use LogonUser, DuplicateTokenEx, LoadUserProfile (depending on app being started), and finally, CreateProcessAsUser.
Thanks a lot for that tip. Please could you post that piece of code?
Martin
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Here's logon stuff. You can add CreateProcessAsUser easy enough. Remember that the lpDesktop member of StartupInfo = "" (not NULL and not "WinSta0\Default") for this application. Good luck.
#region User Logon
/// /// The LogonUser function attempts to log a user on to the local computer. /// [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern bool LogonUser(String lpszUsername, String lpszDomain, IntPtr lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr hToken);
/// /// The DuplicateTokenEx function creates a new access token that duplicates an existing token. This function can create either a primary token or an impersonation token. /// [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern bool DuplicateTokenEx(IntPtr hExistingToken, int dwDesiredAccess, ref SecurityAttributes lpTokenAttributes, int impersonationLevel, int tokenType, out IntPtr phNewToken);
/// /// The LoadUserProfile function loads the specified user's profile /// [DllImport("userenv.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern bool LoadUserProfile(IntPtr hToken, ref ProfileInfo lpProfileInfo);
/// /// The UnloadUserProfile function unloads a user's profile that was loaded by the LoadUserProfile function /// [DllImport("userenv.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern bool UnloadUserProfile(IntPtr hToken, IntPtr hProfile);
/// /// Closes an open object handle. /// [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern bool CloseHandle(IntPtr handle);
/// /// The SECURITY_ATTRIBUTES structure contains the security descriptor for an object and specifies whether the handle retrieved by specifying this structure is inheritable /// [StructLayout(LayoutKind.Sequential)] public struct SecurityAttributes { public int dwLength; public IntPtr lpSecurityDescriptor; public bool bInheritHandle; }
/// /// Profile Info /// [StructLayout(LayoutKind.Sequential)] public struct ProfileInfo { /// /// Specifies the size of the structure, in bytes. /// public int dwSize;
/// /// This member can be one of the following flags: PI_NOUI or PI_APPLYPOLICY /// public int dwFlags;
/// /// Pointer to the name of the user. /// This member is used as the base name of the directory in which to store a new profile. /// public string lpUserName;
/// /// Pointer to the roaming user profile path. /// If the user does not have a roaming profile, this member can be NULL. /// public string lpProfilePath;
/// /// Pointer to the default user profile path. This member can be NULL. /// public string lpDefaultPath;
/// /// Pointer to the name of the validating domain controller, in NetBIOS format. /// If this member is NULL, the Windows NT 4.0-style policy will not be applied. /// public string lpServerName;
/// /// Pointer to the path of the Windows NT 4.0-style policy file. This member can be NULL. /// public string lpPolicyPath;
/// /// Handle to the HKEY_CURRENT_USER registry key. /// public IntPtr hProfile; }
/// /// Logon type option. /// [FlagsAttribute] public enum LogonType { /// /// This logon type is intended for users who will be interactively using the computer /// Interactive = 2, /// /// This logon type is intended for high performance servers to authenticate plaintext passwords. /// Network = 3, /// /// This logon type is intended for batch servers, where processes may be executing on behalf of a user without their direct intervention. /// Batch = 4, /// /// Indicates a service-type logon. The account provided must have the service privilege enabled. /// Service = 5, /// /// This logon type is for GINA DLLs that log on users who will be interactively using the computer. /// Unlock = 7 }
/// /// Specifies the logon provider. /// [FlagsAttribute] public enum LogonProvider { /// /// Use the standard logon provider for the system. /// Default = 0, /// /// Use the negotiate logon provider. (WINNT50) /// Negotiate = 3, /// /// Use the NTLM logon provider (WINNT40) /// NTLM = 2, /// /// Use the Windows NT 3.5 logon provider. /// WinNT35 = 1 }
/// /// Specifies the requested access rights for the new token. /// [FlagsAttribute] public enum DuplicateTokenDesiredAccess { /// /// To request the same access rights as the existing token, specify zero. /// SameAsExisting = 0, /// /// To request all access rights that are valid for the caller, specify MAXIMUM_ALLOWED. /// MaximumAllowed = 0x02000000 } /// /// Specifies a value from the SECURITY_IMPERSONATION_LEVEL enumeration that indicates the impersonation level of the new token /// [FlagsAttribute] public enum ImpersonationLevel { /// /// The server process cannot obtain identification information about the client, and it cannot impersonate the client. It is defined with no value given, and thus, by ANSI C rules, defaults to a value of zero. /// Anonymous = 0, /// /// The server process can obtain information about the client, such as security identifiers and privileges, but it cannot impersonate the client. This is useful for servers that export their own objects, for example, database products that export tables and views. Using the retrieved client-security information, the server can make access-validation decisions without being able to use other services that are using the client's security context., /// Identification = 1, /// /// The server process can impersonate the client's security context on its local system. The server cannot impersonate the client on remote systems., /// Impersonation = 2, /// /// The server process can impersonate the client's security context on remote systems. This impersonation level is not supported on WinNT /// Delegation = 3 } /// /// Specifies the requested access rights for the new token. /// [FlagsAttribute] public enum TokenType { /// /// The new token is a primary token that you can use in the CreateProcessAsUser function. /// Primary = 1, /// /// The new token is an impersonation token. /// Impersonation = 2 } private void LogonUser(String user, String domain, SecureString password, LogonType type, LogonProvider provider) { if (password.IsReadOnly() == false) throw new InvalidOperationException("SecureString not ReadOnly");
if (string.IsNullOrEmpty(user) == true || string.IsNullOrEmpty(domain) == true) throw new InvalidOperationException("No user account specified");
IntPtr handle; IntPtr bstr = Marshal.SecureStringToBSTR(password); bool result = LogonUser(user, domain, bstr, (int)type, (int)provider, out handle); Marshal.ZeroFreeBSTR(bstr);
if (result == false) throw new System.ComponentModel.Win32Exception();
SecurityAttributes sa = new SecurityAttributes(); sa.dwLength = Marshal.SizeOf(sa); sa.lpSecurityDescriptor = IntPtr.Zero; sa.bInheritHandle = true;
IntPtr newHandle; result = DuplicateTokenEx(handle, (int)DuplicateTokenDesiredAccess.MaximumAllowed, ref sa, (int)ImpersonationLevel.Impersonation, (int)TokenType.Primary, out newHandle); if (result == false) throw new System.ComponentModel.Win32Exception();
CloseHandle(handle); handle = newHandle;
hToken = handle; }
public void LoadUserProfile(string username) { if (hToken == IntPtr.Zero) throw new InvalidOperationException("User not logged in");
ProfileInfo info = new ProfileInfo(); info.dwSize = Marshal.SizeOf(info); info.lpUserName = username; info.dwFlags = 1; // PI_NOUI 0x00000001 // Prevents displaying of messages
bool result = LoadUserProfile(hToken, ref info); if (result == false) throw new System.ComponentModel.Win32Exception();
hProfile = info.hProfile; }
internal void LogOffUser() { #if false string identity = WindowsIdentity.GetCurrent().Name; string threadIdentity = Thread.CurrentPrincipal.Identity.Name; scriptTask.State.AddMessage(DateTime.Now, string.Format("Logging off user {0} ({1})", identity, threadIdentity)); #endif
WindowsIdentity.Impersonate(IntPtr.Zero);
#if false identity = WindowsIdentity.GetCurrent().Name; Thread.CurrentPrincipal = new WindowsPrincipal(WindowsIdentity.GetCurrent()); threadIdentity = Thread.CurrentPrincipal.Identity.Name; scriptTask.State.AddMessage(DateTime.Now, string.Format("Identity now {0} ({1})", identity, threadIdentity)); #endif
if (hToken != IntPtr.Zero && hProfile != IntPtr.Zero) { bool result = UnloadUserProfile(hToken, hProfile); hProfile = IntPtr.Zero;
if (result == false) throw new System.ComponentModel.Win32Exception(); }
if (hToken != IntPtr.Zero) { bool result = CloseHandle(hToken); hToken = IntPtr.Zero;
if (result == false) throw new System.ComponentModel.Win32Exception(); }
}
#endregion // User Logon
|
| Sign In·View Thread·PermaLink | 2.00/5 (2 votes) |
|
|
|
 |
|
 |
Hi davelogie, With your solution I got the same problems - still no network access.
Am I using wrong parameters?
public static System.Diagnostics.Process StartProcessDesktop(string userName, string domain, string password, string commandLine, short showWindow, string sCurrentDirectory) { bool retval; StringBuilder cl = new StringBuilder(commandLine.Length); cl.Append(commandLine);
retval = LogonUser(userName, domain, password, LogonType.Interactive, LogonProvider.Default); if (!retval) { throw new System.ComponentModel.Win32Exception(); } retval = LoadUserProfile(userName); if (!retval) { throw new System.ComponentModel.Win32Exception(); } SecurityAttributes saproc = new SecurityAttributes(); saproc.dwLength = Marshal.SizeOf(saproc); saproc.lpSecurityDescriptor = IntPtr.Zero; saproc.bInheritHandle = true;
SecurityAttributes sathread = new SecurityAttributes(); sathread.dwLength = Marshal.SizeOf(sathread); sathread.lpSecurityDescriptor = IntPtr.Zero; sathread.bInheritHandle = true;
ProcessInformation processInfo; StartUpInfo startupInfo = new StartUpInfo(); startupInfo.cb = Marshal.SizeOf(startupInfo); startupInfo.lpTitle = null; startupInfo.lpDesktop = ""; startupInfo.dwFlags = (int)StartUpInfoFlags.UseShowWindow; startupInfo.wShowWindow = showWindow;
retval = CreateProcessAsUser(_hToken, null, cl, ref saproc, ref sathread, false, (uint)(CreationFlags.NewProcessGroup | CreationFlags.NewConsole), IntPtr.Zero, sCurrentDirectory, ref startupInfo, out processInfo);
if (!retval) { throw new System.ComponentModel.Win32Exception(); } else { CloseHandle(processInfo.hProcess); CloseHandle(processInfo.hThread); return System.Diagnostics.Process.GetProcessById(processInfo.dwProcessId); } }
Thanks, Martin
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
So you want to show a GUI? In my application everything is GUI-less behind the scenes. Mostly console apps. the most important requirement for me was that the process was fully started as the user as if they were interactively logged in.
Are you seeing the GUI of your process? The only thing I set on the startup info is the lpDesktop = "". I mentioned the other options earlier. My creation flag is only "NoWindow".
Are you loading the Environment? This is useful but I don't see how it would effect network access.
IntPtr lpEnvironment; bool res = CreateEnvironmentBlock(out lpEnvironment, hToken, true); if (res == false) throw new System.ComponentModel.Win32Exception();
ProcessInformation processInfo;
bool result = CreateProcessAsUser(hToken, null, commandLine, ref sa, ref sa, true, // inheritHandles. (int)(creationFlags | ProcessCreationFlags.UnicodeEnvironment), lpEnvironment, workingDirectory, ref startupInfo, out processInfo);
if (lpEnvironment != IntPtr.Zero) DestroyEnvironmentBlock(lpEnvironment);
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Yes, I want to show a GUI and it works but there's still no network access. I also load the environment because the started application needs it (not for network access). Any ideas left?
Thanks, Martin
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Got me. Try running you Windows service under a domain account and see if that changes the behavior. Must be something different about your environment.
|
| Sign In·View Thread·PermaLink | 4.00/5 (1 vote) |
|
|
|
 |
|
 |
Thanks for posting that, it helped out alot. One slight change though, we needed to explicitly marshal the strings in the ProfileInfo struct as UnmanagedType.LPTStr
When loading a profile that already exists, it doesn't matter, as the lpUserName member is ignored. When loading a profile that doesn't already exist, LoadUserProfile() will create a new one using lpUserName. Without the marshalling, the passed in string gets junked, so you get a profile created with a junk path which can't be loaded correctly on subsequent user logins.
Cheers Steve
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
|
 |
|
 |
its all good... but whidbey is some time away and things need to be done usually "yesterday".
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |