I need to find out the idle time of remote pc from server pc using c# application. I have a list of IP addresses and host names connected in Local Area Network. I want to find out idle time more then 30 min for each computer connected in LAN. I done it for local pc, but it not works for remote pc. here is my code for local pc.
[DllImport("user32.dll")]
private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
private int GetIdleTime()
{
LASTINPUTINFO lastone = new LASTINPUTINFO();
lastone.cbSize = (uint)Marshal.SizeOf(lastone);
lastone.dwTime = 0;
int idleTime = 0;
int tickCount = Environment.TickCount;
if (GetLastInputInfo(ref lastone))
{
idleTime = tickCount - (int)lastone.dwTime;
return idleTime;
}
else
return 0;
}
Acording to MSDN, this is not possible entirely for the local machine let alone a remote one.
This function is useful for input idle detection. However,
GetLastInputInfo does not provide system-wide user input information
across all running sessions. Rather, GetLastInputInfo provides
session-specific user input information for only the session that
invoked the function.
You could however try one of the following:
Have a process on each PC which you can query.
Have a process on each
PC reporting to your central process.
Monitor remote PC processes to
determine if the screen saver is active.
If you do not have terminal services deactivated, and the clients are xp or higher, you can also use
ITerminalServicesSession.LastInputTime
For this you either use the Cassia libraries or p/invoke
WTSQuerySessionInformation
I use this remote WMI query:
object idleResult = Functions.remoteWMIQuery(machinename, "", "", "Select CreationDate From Win32_Process WHERE Name = \"logonUI.exe\"", "CreationDate", ref wmiOK);
Logonui.exe is the lockscreen. In business environments most systems lock when a user is idle.
You can translate the result like this in DateTime format
DateTime idleTime = Functions.ParseCIM_DATETIME((string)idleResult);
Where ParseCIM_DATETIME is this fucntion:
public static DateTime ParseCIM_DATETIME(string date)
{
//datetime object to store the return value
DateTime parsed = DateTime.MinValue;
//check date integrity
if (date != null && date.IndexOf('.') != -1)
{
//obtain the date with miliseconds
string newDate = date.Substring(0, date.IndexOf('.') + 4);
//check the lenght
if (newDate.Length == 18)
{
//extract each date component
int y = Convert.ToInt32(newDate.Substring(0, 4));
int m = Convert.ToInt32(newDate.Substring(4, 2));
int d = Convert.ToInt32(newDate.Substring(6, 2));
int h = Convert.ToInt32(newDate.Substring(8, 2));
int mm = Convert.ToInt32(newDate.Substring(10, 2));
int s = Convert.ToInt32(newDate.Substring(12, 2));
int ms = Convert.ToInt32(newDate.Substring(15, 3));
//compose the new datetime object
parsed = new DateTime(y, m, d, h, mm, s, ms);
}
}
//return datetime
return parsed;
}
The remote WMI Query function is as follows:
public static object remoteWMIQuery(string machine, string username, string password, string WMIQuery, string property, ref bool jobOK)
{
jobOK = true;
if (username == "")
{
username = null;
password = null;
}
// Configure the connection settings.
ConnectionOptions options = new ConnectionOptions();
options.Username = username; //could be in domain\user format
options.Password = password;
ManagementPath path = new ManagementPath(String.Format("\\\\{0}\\root\\cimv2", machine));
ManagementScope scope = new ManagementScope(path, options);
// Try and connect to the remote (or local) machine.
try
{
scope.Connect();
}
catch (ManagementException ex)
{
// Failed to authenticate properly.
jobOK = false;
return "Failed to authenticate: " + ex.Message;
//p_extendederror = (int)ex.ErrorCode;
//return Status.AuthenticateFailure;
}
catch (System.Runtime.InteropServices.COMException)
{
// Unable to connect to the RPC service on the remote machine.
jobOK = false;
return "Unable to connect to RPC service";
//p_extendederror = ex.ErrorCode;
//return Status.RPCServicesUnavailable;
}
catch (System.UnauthorizedAccessException)
{
// User not authorized.
jobOK = false;
return "Error: Unauthorized access";
//p_extendederror = 0;
//return Status.UnauthorizedAccess;
}
try
{
ObjectQuery oq = new ObjectQuery(WMIQuery);
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, oq);
foreach (ManagementObject queryObj in searcher.Get())
{
if (property != null)
{
return queryObj[property];
}
else return queryObj;
}
}
catch (Exception e)
{
jobOK = false;
return "Error: " + e.Message;
}
return "";
}
If you have the screensaver enabled I would suggest you check the CreateDate on the screensaver process and do a difference from the remote the createdate time and you get the idle time + the screensaver timeout
you might want to use WMI for this kind of thing
its a hack but it works
Related
In my Xamarin Forms application, I am trying to discover all devices on the local network that I am connected to. My approach is to first get the device IP address, and use to first 3 numbers to know what the gateway is (first number is always 192). And then, ping every address on that gateway. Here is my code:
public partial class MainPage : ContentPage
{
private List<Device> discoveredDevices = new List<Device>();
public MainPage()
{
InitializeComponent();
Ping_all();
}
private string GetCurrentIp()
{
IPAddress[] addresses = Dns.GetHostAddresses(Dns.GetHostName());
string ipAddress = string.Empty;
if (addresses != null && addresses[0] != null)
{
ipAddress = addresses[0].ToString();
}
else
{
ipAddress = null;
}
return ipAddress;
}
public void Ping_all()
{
string ip = GetCurrentIp();
if (ip != null)
{
//Extracting and pinging all other ip's.
string[] array = ip.Split('.');
string gateway = array[0] + "." + array[1] + "." + array[2];
for (int i = 2; i <= 255; i++)
{
string ping_var = $"{gateway}.{i}";
//time in milliseconds
Ping(ping_var, 4, 4000);
}
}
}
public void Ping(string host, int attempts, int timeout)
{
for (int i = 0; i < attempts; i++)
{
new Thread(delegate ()
{
try
{
System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping();
ping.PingCompleted += new PingCompletedEventHandler(PingCompleted);
ping.SendAsync(host, timeout, host);
// PingCompleted never gets called
}
catch(Exception e)
{
// Do nothing and let it try again until the attempts are exausted.
// Exceptions are thrown for normal ping failurs like address lookup
// failed. For this reason we are supressing errors.
}
}).Start();
}
}
private void PingCompleted(object sender, PingCompletedEventArgs e)
{
string ip = (string)e.UserState;
if (e.Reply != null && e.Reply.Status == IPStatus.Success)
{
string hostname = GetHostName(ip);
string macaddres = GetMacAddress(ip);
var device = new Device()
{
Hostname = hostname,
IpAddress = ip,
MacAddress = macaddres
};
discoveredDevices.Add(device);
}
}
public string GetHostName(string ipAddress)
{
try
{
IPHostEntry entry = Dns.GetHostEntry(ipAddress);
if (entry != null)
{
return entry.HostName;
}
}
catch (SocketException)
{
}
return null;
}
public string GetMacAddress(string ipAddress)
{
string macAddress = string.Empty;
System.Diagnostics.Process Process = new System.Diagnostics.Process();
Process.StartInfo.FileName = "arp";
Process.StartInfo.Arguments = "-a " + ipAddress;
Process.StartInfo.UseShellExecute = false;
Process.StartInfo.RedirectStandardOutput = true;
Process.StartInfo.CreateNoWindow = true;
Process.Start();
string strOutput = Process.StandardOutput.ReadToEnd();
string[] substrings = strOutput.Split('-');
if (substrings.Length >= 8)
{
macAddress = substrings[3].Substring(Math.Max(0, substrings[3].Length - 2))
+ "-" + substrings[4] + "-" + substrings[5] + "-" + substrings[6]
+ "-" + substrings[7] + "-"
+ substrings[8].Substring(0, 2);
return macAddress;
}
else
{
return "OWN Machine";
}
}
}
I get to the part where I try to ping:
System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping();
ping.PingCompleted += new PingCompletedEventHandler(PingCompleted);
ping.SendAsync(host, timeout, host);
But PingCompleted never gets called. No exception is thrown either. Any idea why? I'm running this on a physical Android device.
EDIT
PingCompleted started getting called for me now, not sure why it wasn't working before. But it now crashes in my GetMacAddress function on the line Process.Start(); because it can not find the resource.
I ended up using this really robust and easy to use library:
https://github.com/Yortw/RSSDP
It doesn't actually find all devices on the network, instead it uses SSDP (Simple Search Discovery Protocol) to quickly find all devices that are broadcasting a service with this protocol on the network. I filtered it to only scan devices running my app, which is what I actually needed. It takes only a second to discover my devices, which is much faster than pinging 255 addresses.
In the documentation you will see:
var deviceDefinition = new SsdpRootDevice()
{
CacheLifetime = TimeSpan.FromMinutes(30), //How long SSDP clients can cache this info.
Location = new Uri("http://mydevice/descriptiondocument.xml"), // Must point to the URL that serves your devices UPnP description document.
DeviceTypeNamespace = "my-namespace",
DeviceType = "MyCustomDevice",
FriendlyName = "Custom Device 1",
Manufacturer = "Me",
ModelName = "MyCustomDevice",
Uuid = GetPersistentUuid() // This must be a globally unique value that survives reboots etc. Get from storage or embedded hardware etc.
};
For the Location I set it as my device's IP. So that another device that discovers it can have the IP too. I don't think it's meant to be used this way, but it worked for me and I don't see why not.
I tested it on 2 physical Android devices.
I am making a Bloomberg web service GetData call for the "DEBT_TO_EQUITY_FUNDAMENTALS_TKR" field. I am setting secmaster = true and asking for a single instrument with a CUSIP identifier (with yellowkey = MarketSector.Corp).
This strikes me as a fairly lightweight call having seen people asking for thousands of instruments and dozens of fields at once.
I have played around with setting lots of different settings but I just can't get this request to return in a few seconds. It gives me the correct return value but it takes longer than 60 seconds.
Any idea if it is possible to get such a request to execute and return in a few seconds?
Thanks
EDIT - Here is the code I am running:
public string GetFundamentalTicker(string identifier, InstrumentType identifierType = InstrumentType.CUSIP)
{
PerSecurityWS ps = new PerSecurityWS();
try
{
log.DebugFormat("Cert path is: {0}", CertPath);
X509Certificate2 clientCert = new X509Certificate2(CertPath, "<password_redacted>");
ps.ClientCertificates.Add(clientCert);
}
catch (Exception e)
{
log.ErrorFormat("Error in cert setup - {0} - {1}", e.Message, e.InnerException == null ? "" : e.InnerException.Message);
return null;
}
//Set request header
GetDataHeaders getDataHeaders = new GetDataHeaders();
getDataHeaders.secmaster = true;
getDataHeaders.secmasterSpecified = true;
//getDataHeaders.fundamentals = true;
//getDataHeaders.fundamentalsSpecified = true;
//getDataHeaders.programflag = ProgramFlag.oneshot;//unnecessary - defaults to this anyway
//getDataHeaders.programflagSpecified = true;
//getDataHeaders.pricing = true;
getDataHeaders.secid = identifierType;
getDataHeaders.secidSpecified = true;
SubmitGetDataRequest sbmtGtDtreq = new SubmitGetDataRequest();
sbmtGtDtreq.headers = getDataHeaders;
sbmtGtDtreq.fields = new string[] {
"DEBT_TO_EQUITY_FUNDAMENTALS_TKR"
};
int currentFundYear = DateTime.Now.Year;
//var fundYears = new List<int>();
List<Instrument> fundYearInstruments = new List<Instrument>();
Instrument fundYearInstrument = null;
fundYearInstrument = new Instrument();
fundYearInstrument.id = identifier;
fundYearInstrument.typeSpecified = true;
fundYearInstrument.type = identifierType;
fundYearInstrument.yellowkey = MarketSector.Corp;
fundYearInstrument.yellowkeySpecified = true;
//fundYearInstrument.overrides = new Override[] {};//{ new Override() { field = "EQY_FUND_YEAR", value = currentFundYear.ToString() } };
fundYearInstruments.Add(fundYearInstrument);
//fundYears.Add(-1);
Instrument[] instr = fundYearInstruments.ToArray();
Instruments instrs = new Instruments();
instrs.instrument = instr;
sbmtGtDtreq.instruments = instrs;
try
{
SubmitGetDataResponse sbmtGtDtResp = ps.submitGetDataRequest(sbmtGtDtreq);
RetrieveGetDataRequest rtrvGtDrReq = new RetrieveGetDataRequest();
rtrvGtDrReq.responseId = sbmtGtDtResp.responseId;
RetrieveGetDataResponse rtrvGtDrResp;
do
{
System.Threading.Thread.Sleep(POLL_INTERVAL);
rtrvGtDrResp = ps.retrieveGetDataResponse(rtrvGtDrReq);
}
while (rtrvGtDrResp.statusCode.code == DATA_NOT_AVAILABLE);
if (rtrvGtDrResp.statusCode.code == SUCCESS)
{
for (int i = 0; i < rtrvGtDrResp.instrumentDatas.Length; i++)
{
for (int j = 0; j < rtrvGtDrResp.instrumentDatas[i].data.Length; j++)
{
if (rtrvGtDrResp.instrumentDatas[i].data[j].value == "N.A." || rtrvGtDrResp.instrumentDatas[i].data[j].value == "N.S." || rtrvGtDrResp.instrumentDatas[i].data[j].value == "N.D.")
rtrvGtDrResp.instrumentDatas[i].data[j].value = null;
return rtrvGtDrResp.instrumentDatas[i].data[j].value;
}
}
return null;
}
else if (rtrvGtDrResp.statusCode.code == REQUEST_ERROR)
{
log.ErrorFormat("Error in the submitted request: {0}", rtrvGtDrResp.statusCode.description);
return null;
}
}
catch (Exception e)
{
log.ErrorFormat("Error in GetData - {0} - {1}", e.Message, e.InnerException == null ? "" : e.InnerException.Message);
return null;
}
return null;
}
Poll interval is 5 seconds and the SOAP web service url is:
https://software.bloomberg.com/datalicensewp/dlws.wsdl
I am having the same issue. I found out that there is a difference between making the same call to Bloomberg API from, for example, console app (works very fast) and web service (takes a lot of time to start session). And the difference is that console app runs under the same user as bbcomm process, whereas web service (or actually iis process) runs under System account. You can try to log out all users on the PC where web service is hosted and then try to make the call. In this case, I guess, bbcomm goes under System account as no one else is logged in and works fast. It worked for me and the call was answered instantly.
I'm trying to write a small command line application with C# that will prompt for a username and a password that will be used to login to several remote computers that are sitting on the same network/domain and start a local session.
I've tried connecting to a remote computer and to query the remote PC's operating system info with the following code:
ConnectionOptions options = new ConnectionOptions();
ManagementScope scope = new ManagementScope(#"\\REMOTE_COMPUTER_NAME");
scope.Connect();
ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_OperatingSystem");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
ManagementObjectCollection queryCollection = searcher.Get();
foreach (ManagementObject m in queryCollection)
{
// Display the remote computer information
Console.WriteLine("Computer Name : {0}", m["csname"]);
Console.WriteLine("Windows Directory : {0}", m["WindowsDirectory"]);
Console.WriteLine("Operating System: {0}", m["Caption"]);
Console.WriteLine("Version: {0}", m["Version"]);
Console.WriteLine("Manufacturer : {0}", m["Manufacturer"]);
}
However, this only returns information on the local PC that I'm working on and not on the remote PC.
Am I overlooking something with this code? And is there an appropriate approach to accomplish what I am trying to do?
I don't have remote machine right now to give you the working example, but you can try this. advapi32.logonuser
Example:
[DllImport("advapi32.dll")]
public static extern bool LogonUser(string name, string domain, string pass,
int logType, int logpv, out IntPtr pht);
IntPtr ptr;
// LogonUser("username", "remotemachine", "password", 2, 0, out ptr);
LogonUser("username", "remotemachine", "password", 9, 0, out ptr);
WindowsIdentity windowsIdentity = new WindowsIdentity(ptr);
var impersonationContext = windowsIdentity.Impersonate();
// your code goes here...
impersonationContext.Undo();
This logon type allows the caller to clone its current token and
specify new credentials for outbound connections. The new logon
session has the same local identifier but uses different credentials
for other network connections. NOTE: This logon type is supported
only by the LOGON32_PROVIDER_WINNT50 logon provider. NOTE: Windows NT:
This value is not supported.
http://www.pinvoke.net/default.aspx/advapi32.logonuser
Edit
Give it a try cassia
ITerminalServicesManager manager = new TerminalServicesManager();
using (ITerminalServer server = manager.GetRemoteServer("servername"))
{
server.Open();
foreach (ITerminalServicesSession session in server.GetSessions())
{
Console.WriteLine("Hi there, " + session.UserAccount + " on session " + session.SessionId);
Console.WriteLine("It looks like you logged on at " + session.LoginTime +
" and are now " + session.ConnectionState);
}
}
You have to use ConnectionOptions and pass it to the ManagementScope
public void GetSystemInformation(string _yourDomain, string _hostName, string _userName, SecureString _password)
{
ManagementScope Scope = null;
string computerName = _hostName;
string userName = _userName;
SecureString password = _password;
ManagementObjectCollection collection = null;
try
{
SelectQuery query = new SelectQuery("SELECT * FROM Win32_OperatingSystem");
//string query = "SELECT * FROM Win32_NetworkAdapterConfiguration" + " WHERE IPEnabled = 'TRUE'";
var options = new ConnectionOptions
{
EnablePrivileges = false,
Impersonation = ImpersonationLevel.Impersonate,
Username = _userName,
SecurePassword = _password,
Authority = "ntlmdomain:" + _yourDomain
};
Scope.Options = options;
Scope.Connect();
ManagementObjectSearcher searcher = new ManagementObjectSearcher(Scope, query);
collection = searcher.Get();
//Do something with the collection
}
catch (ManagementException ex)
{
Console.WriteLine(ex.Message);
}
catch (UnauthorizedAccessException ex)
{
throw new ArgumentException(ex.Message);
}
}
private static SecureString CreateSecuredString(string pw)
{
var secureString = new SecureString();
foreach (var c in pw)
{
secureString.AppendChar(c);
}
return secureString;
}
You might have to try some different stats with the variables EnablePrivileges and Impersonation
edit:
If you want to get your information from your pc (local) than you dont have to pass the options to the scope.
I have a C#.net Windows form Application with SQL Server. My application use in Multiple user by local Network. Now I need to find Hard disk Serial Number which hard disk installed sql server (Note: By Using C#.net Application Data source ).
How can i find Hard disk Serial number throw by application data source?
This might be useful
using System;
using System.Management;
using System.Collections;
namespace WmiControl
{
public class WMI
{
public bool GetDiskSerial(string Computername)
{
try
{
ManagementScope scope = new ManagementScope(#"\\" + Computername + #"\root\cimv2");
scope.Connect();
ArrayList hdCollection;
ManagementObjectSearcher searcher;
if (GetDiskDrive(scope, out hdCollection, out searcher) || GetDiskSerial(scope, hdCollection, ref searcher))
return true;
else
return false;
}
catch (ManagementException)
{
return false;
}
}
private bool GetDiskSerial(ManagementScope scope, ArrayList hdCollection, ref ManagementObjectSearcher searcher)
{
try
{
ObjectQuery query1 = new ObjectQuery("SELECT * FROM Win32_PhysicalMedia");
searcher = new ManagementObjectSearcher(scope, query1);
int i = 0;
string sDiskSerial = "";
foreach (ManagementObject wmi_HD in searcher.Get())
{
// get the hard drive from collection
// using index
if (i < hdCollection.Count)
{
HardDrive hd = (HardDrive)hdCollection[i];
if (wmi_HD["SerialNumber"] == null)
hd.SerialNo = "";
else
hd.SerialNo = wmi_HD["SerialNumber"].ToString();
}
++i;
}
foreach (HardDrive hd in hdCollection)
{
if (!String.IsNullOrEmpty(hd.SerialNo))
{
sDiskSerial = hd.SerialNo;
break;
}
}
return true;
}
catch (Exception)
{
return false;
}
}
private bool GetDiskDrive(ManagementScope scope, out ArrayList hdCollection, out ManagementObjectSearcher searcher)
{
try
{
ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_DiskDrive");
hdCollection = new ArrayList();
searcher = new ManagementObjectSearcher(scope, query);
foreach (ManagementObject wmi_HD in searcher.Get())
{
HardDrive hd = new HardDrive();
hd.Model = wmi_HD["Model"].ToString();
hd.Type = wmi_HD["InterfaceType"].ToString();
hdCollection.Add(hd);
return true;
}
return true;
}
catch (Exception)
{
hdCollection = null;
searcher = null;
return false;
}
}
}
class HardDrive
{
private string model = null;
private string type = null;
private string serialNo = null;
public string Model
{
get { return model; }
set { model = value; }
}
public string Type
{
get { return type; }
set { type = value; }
}
public string SerialNo
{
get { return serialNo; }
set { serialNo = value; }
}
}
}
See here for more info
You might want also to study CLR
You'll need to resort to WMI. With the proper privileges on the SQL Server machine, you can get the serial number of the hard-drives on it. See here for an example on retrieving the hard-disk's serial number using WMI.
You'll need to figure out which disk holds SQL Server and how to access the SQL Server machine on your own.
You have to do it in 3 stages:
The connection string of the data source gives you the name of the machine on which SQL Server is installed
You must then query the machine to find out the drive which drive SQL Server is installed on
You can then use the code supplied by others here to get the serial number
I'm trying to create a virtual directory on a remote server using DirectoryServices by cloning the settings of another virtual directory, but I get a COMException: Unknown name. (Exception from HRESULT: 0x80020006 (DISP_E_UNKNOWNNAME)) when invoking AppCreate.
This is the code I've written (simplified with most of tests removed):
public bool CreateVirtualDirectory(string serverName, string primaryVirtualDirectoryName, string virtualDirectoryName, MyUser user)
{
try
{
DirectoryEntry directoryEntry = null;
if (user != null)
directoryEntry = new DirectoryEntry("IIS://" + serverName + "/W3SVC/1/Root", user.UserName, user.Password, AuthenticationTypes.Secure | AuthenticationTypes.Sealing);
else
directoryEntry = new DirectoryEntry("IIS://" + serverName + "/W3SVC/1/Root");
DirectoryEntry primaryVirtualDirectory = directoryEntry.Children.Find(primaryVirtualDirectoryName, directoryEntry.SchemaClassName);
DirectoryEntry virtualDirectory = directoryEntry.Children.Add(virtualDirectoryName, directoryEntry.SchemaClassName);
virtualDirectory.CommitChanges();
virtualDirectory.Properties["Path"].Value = primaryVirtualDirectory.Properties["Path"].Value;
virtualDirectory.Properties["AppFriendlyName"][0] = virtualDirectoryName;
if (primaryVirtualDirectory.Properties["UNCUserName"] != null && primaryVirtualDirectory.Properties["UNCUserName"].Value != null && primaryVirtualDirectory.Properties["UNCUserName"].Value.ToString().Length > 0)
{
// IIS6 of IIS7
virtualDirectory.Properties["AuthNTLM"][0] = true;
virtualDirectory.Properties["UNCUserName"].Value = primaryVirtualDirectory.Properties["UNCUserName"].Value;
virtualDirectory.Properties["UNCPassword"].Value = primaryVirtualDirectory.Properties["UNCPassword"].Value;
}
else
{
// Older versions
virtualDirectory.Properties["AuthFlags"][0] = 5; // MD_AUTH_ANONYMOUS | MD_AUTH_NT
virtualDirectory.Properties["AnonymousUserName"].Value = primaryVirtualDirectory.Properties["AnonymousUserName"].Value;
virtualDirectory.Properties["AnonymousUserPass"].Value = primaryVirtualDirectory.Properties["AnonymousUserPass"].Value;
}
virtualDirectory.Properties["AccessRead"][0] = true;
virtualDirectory.Properties["AccessExecute"][0] = true;
virtualDirectory.Properties["AccessWrite"][0] = false;
virtualDirectory.Properties["AccessScript"][0] = true;
virtualDirectory.Properties["EnableDefaultDoc"][0] = true;
virtualDirectory.Properties["EnableDirBrowsing"][0] = false;
if (primaryVirtualDirectory.Properties["AppPoolId"] != null && primaryVirtualDirectory.Properties["AppPoolId"].Value != null && primaryVirtualDirectory.Properties["AppPoolId"].Value.ToString().Length > 0)
virtualDirectory.Properties["AppPoolId"].Value = primaryVirtualDirectory.Properties["AppPoolId"].Value;
virtualDirectory.Properties["ScriptMaps"].Value = primaryVirtualDirectory.Properties["ScriptMaps"].Value;
// I Tried adding these 3 lines but I keeo getting the same exception
// virtualDirectory.CommitChanges();
// virtualDirectory.Invoke("SetInfo");
// virtualDirectory.CommitChanges();
virtualDirectory.Invoke("AppCreate", true);
// I tried this instead but I still get the same exception
// virtualDirectory.Invoke("AppCreate2", 0);
virtualDirectory.CommitChanges();
return true;
}
catch (Exception exception)
{
return false;
}
}
I tried some variations (see comments in the code) using AppCreate2 instead of AppCreate or calling a CommitChanges and/or invoking SetInfo before the AppCreate, but all lead to the same exception.
The user credentials I'm using has adminstrator rights on the remote server. In fact if I copy the program to the remote server and run it there with the same credentials (I logged in with the same user on the remote server), using 'localhost' as servername and the user variable = null, it works without throwing the exception, so it must have something to do with the remote execution.
The remote server is a Windows Server 2003 R2 SP2 (32bit), the machine running this program is a Windows 7 Professional (64 bit).
Does anyone have any ideas ?