/// <summary> /// Creates all the specified virtual resources. /// </summary> public override void Start() { // Install all print queues for the specified user. InstallRemotePrinters(); InstallLocalPrinters(); // Perform user specific setup, but don't actually start the Office Worker on the // Citrix server. Wait until the ExecuteResources is called for that. This will // better simulate a simultaneous load on the Citrix server. ChangeResourceState(_credential.ResourceInstanceId, RuntimeState.Starting); ChangeMachineStatusMessage("Configuring User"); ConfigureUserGroups(_credential); CitrixSessionManager.ConfigureLocalUserGroups(_credential, _citrixServer); ChangeMachineStatusMessage("Resetting Citrix"); CitrixSessionManager.ResetCitrixSession(_credential.UserName, _citrixServer); // If a value is provided for the published app, then start it first. if (!string.IsNullOrEmpty(_worker.PublishedApp)) { CitrixSessionManager.StartPublishedApp(_credential, _citrixServer, _worker.PublishedApp); } ChangeMachineStatusMessage("Starting Citrix User"); StartCitrixUserSession(); }
/// <summary> /// Calls the print UI utility. /// </summary> /// <param name="printerPath">The printer path.</param> /// <param name="credential">The credential.</param> private static void CallPrintUi(string printerPath, OfficeWorkerCredential credential = null) { string arg = Resources.PrintUICommand.FormatWith(printerPath); TraceFactory.Logger.Debug(arg); CitrixSessionManager.StartProcess(credential, "CMD.EXE", arg, TimeSpan.FromMinutes(10)); }
/// <summary> /// Starts the defined Virtual Resource process for the defined credential. /// </summary> /// <param name="credential">The user credential.</param> /// <param name="currentDirectory">The current directory.</param> protected override void StartUserProcess(OfficeWorkerCredential credential, string currentDirectory) { if (credential == null) { throw new ArgumentNullException("credential"); } Environment.SpecialFolder folder = (Environment.Is64BitOperatingSystem) ? Environment.SpecialFolder.ProgramFilesX86 : Environment.SpecialFolder.ProgramFiles; var exeFile = Path.Combine ( Environment.GetFolderPath(folder), Resources.WFICA32Path ); TraceFactory.Logger.Debug("ICA Client: {0}".FormatWith(exeFile)); int tries = 0; int numTries = 5; while (tries < numTries) { if (CheckSessionStarted(credential, exeFile)) { break; } tries++; TraceFactory.Logger.Debug("Failed to start session, sleeping and trying again"); if (!ProcessUtil.KillProcess(Resources.wfica32, currentUserOnly: false)) { TraceFactory.Logger.Debug("Failed to kill ICA process"); } else { TraceFactory.Logger.Debug("ICA process killed"); } // Kill any session on the Citrix server CitrixSessionManager.ResetCitrixSession(credential.UserName, _citrixServer); Thread.Sleep(TimeSpan.FromSeconds(5)); } if (tries >= numTries) { throw new ArgumentException("Unable to start Citrix process after {0} tries, for {1}".FormatWith(numTries, credential.UserName)); } else { TraceFactory.Logger.Debug("Citrix session started"); } }
void VirtualResourceEventBus_OnStartMainRun(object sender, VirtualResourceEventBusRunArgs e) { TraceFactory.Logger.Debug("Attempting to start the Citrix Published Application"); // Now the actual Citrix published app must be started. ChangeMachineStatusMessage("Starting Published App"); CitrixSessionManager.StartPublishedApp(_credential, _citrixServer, _worker.PublishedApp); ChangeResourceState(RuntimeState.Running); }
/// <summary> /// Creates all EventLogCollector virtual resources. /// </summary> public override void Start() { ChangeResourceState(RuntimeState.Starting); OpenManagementServiceEndpoint(_credential.UserName); ChangeMachineStatusMessage("Configuring User"); CitrixSessionManager.ConfigureLocalUserGroups(_credential, _citrixServer); ChangeMachineStatusMessage("Resetting Citrix"); CitrixSessionManager.ResetCitrixSession(_credential.UserName, _citrixServer); // Register and let the dispatcher know it's available to run. SessionProxyBackendConnection.RegisterResource(ServiceEndpoint); }
private void VirtualResourceEventBus_OnShutdownResource(object sender, EventArgs e) { TraceFactory.Logger.Info("Shutdown Session for {0}".FormatWith(_credential.UserName)); try { ChangeMachineStatusMessage("Logoff Citrix"); CitrixSessionManager.ResetCitrixSession(_credential.UserName, _citrixServer); CitrixSessionManager.RemoveFromAdminGroup(_credential, _citrixServer); } catch (Exception ex) { TraceFactory.Logger.Error("Error ending session for user {0}".FormatWith(_credential.UserName), ex); } ChangeResourceState(RuntimeState.Offline); }
public override void Cleanup() { TraceFactory.Logger.Info("Cleanup Session for {0}".FormatWith(_credential.UserName)); try { // Give the Citrix server a few seconds to gracefully log the user off the session before // sending the death signal through the KillCitrixSession(). Thread.Sleep(TimeSpan.FromSeconds(2)); ChangeMachineStatusMessage("Logoff Citrix"); CitrixSessionManager.ResetCitrixSession(_credential.UserName, _citrixServer); // CitrixSessionManager.RemoveFromAdminGroup(_credential, _citrixServer); // Send a delete request to the Citrix Monitor service and request a cleanup. This will // proceed to remove the user profile directory from the server to keep the disk space under // control. TraceFactory.Logger.Debug("Sending delete request for: {0}".FormatWith(_userProfile)); string citrixHost = _citrixServer; using (CitrixQueueMonitorConnection client = CitrixQueueMonitorConnection.Create(citrixHost)) { //client.Channel.Cleanup(_credential.UserName, _userProfile); client.Channel.Cleanup(_credential); } //the user configuration file deletion is moved here from startup program to allow for retries to work - Veda string remotePath = @"\\{0}\C$\VirtualResource\UserConfiguration".FormatWith(_citrixServer); string datFile = @"{0}\{1}.dat".FormatWith(remotePath, _credential.UserName); if (File.Exists(datFile)) { File.Delete(datFile); } // Now that the user is logged out, purge all print queues on the local machine. // This also occurs on the Citrix server, both have to be purged in order to++ // ensure that there are no print jobs left in a queue after a completed test. TraceFactory.Logger.Debug("Purging local print queues..."); PurgeLocalPrintQueues(); } catch (Exception ex) { TraceFactory.Logger.Error("Error cleaning up Citrix session", ex); } }
internal static void StartPublishedApp(OfficeWorkerCredential credential, string citrixServer, string publishedApp) { Environment.SpecialFolder folder = (Environment.Is64BitOperatingSystem) ? Environment.SpecialFolder.ProgramFilesX86 : Environment.SpecialFolder.ProgramFiles; string resourcePath = Path.Combine ( Environment.GetFolderPath(folder), Resources.WFICA32Path ); credential.WorkingDirectory = Directory.GetCurrentDirectory(); TraceFactory.Logger.Debug("Starting published app {0}".FormatWith(publishedApp)); string icaFile = CitrixSessionManager.CreateIcaFile(credential, citrixServer, publishedApp); CitrixSessionManager.StartProcess(credential, resourcePath, icaFile, TimeSpan.FromSeconds(10)); }
private bool CheckSessionStarted(OfficeWorkerCredential credential, string resourcePath) { bool sessionStarted = false; string appId = string.Empty; // The Citrix Office Worker can run on a Citrix server in two different ways, one as a published // app and the other under a desktop session. This block of code defines how the ICA file // should be constructed in order to run the session in one of the two options. It is based // on the value of the RunMode which is chosen by the user at runtime. switch (_worker.WorkerRunMode) { case CitrixWorkerRunMode.Desktop: string key = "{0}-CitrixWorkerDesktop".FormatWith(_citrixServer); appId = GlobalSettings.Items[key]; if (string.IsNullOrEmpty(appId)) { throw new InvalidOperationException("The CitrixWorkerDesktop System Setting value is missing."); } break; case CitrixWorkerRunMode.PublishedApp: appId = "{0}-OWC".FormatWith(_citrixServer); break; } // Start the worker process on the remote Citrix server by running the ICA client // as administrator, and the ICA config file contains the credentials for the the // actual Office Worker string icaFile = CitrixSessionManager.CreateIcaFile(credential, _citrixServer, appId); CitrixSessionManager.StartProcess(credential, resourcePath, icaFile, TimeSpan.FromSeconds(10)); // The Citrix server will display a Citrix license warning anytime a user is not admin // and is running a client process. So delay here about 10 seconds to let this dialog // display and eventually go away. TraceFactory.Logger.Info("Sleep 20 seconds to wait on Citrix to startup"); Thread.Sleep(TimeSpan.FromSeconds(20)); try { Retry.WhileThrowing ( () => sessionStarted = PingWorker(credential), 10, TimeSpan.FromSeconds(10), new List <Type>() { typeof(FaultException), typeof(EndpointNotFoundException), typeof(SocketException) } ); } catch (FaultException ex) { TraceFactory.Logger.Debug("Ping worker failed (1): {0}".FormatWith(ex.Message)); } catch (EndpointNotFoundException ex) { TraceFactory.Logger.Debug("Ping worker failed (2): {0}".FormatWith(ex.Message)); } catch (SocketException ex) { TraceFactory.Logger.Debug("Ping worker failed (3): {0}".FormatWith(ex.Message)); } catch (Exception ex) { TraceFactory.Logger.Debug("Ping worker failed (4): {0}".FormatWith(ex.Message)); } finally { TraceFactory.Logger.Debug("Session Started: {0}".FormatWith(sessionStarted)); } return(sessionStarted); }