UAC is not needed in an Embedded/IoT system. Does disabling UAC resolve the problem.
How to set IP, Subnet Mask and GW on Windows 10 IoT Enterprise 2019 LTSC from Windows Forms C# EXE (.NET Framework 4.7) or Win32 C++ DLL?
I'm porting an Industrial Control application to Windows 10 IoT Enterprise 2019 LTSC. The application is a Windows Forms C# EXE (.NET Framework 4.7+) invoking a multi-threaded Win32 C++ DLL. Since UI OS access is purposely restricted, I need to be able to set the IP address, subnet mask and gateway from our application UI. We have no preference for whether it's located in either C# or C++, but we greatly prefer that the UAC prompt does NOT appear. After extensive searching and testing, I'm not sure what to try next. The following has been tried so far:
try
{
ProcessStartInfo ProcStartInfo = new ProcessStartInfo();
ProcStartInfo.FileName = "netsh";
ProcStartInfo.Arguments = "interface ip set address \"Ethernet\" static " + IpAddrAryToStr(IpAddrAry) + " " +
IpAddrAryToStr(SubnetMaskAry); // IpAddrAryToStr() string output is in the format of 10.0.0.1
string DefaultGatewayStr = IpAddrAryToStr(DefaultGatewayAry); // For us, 255.255.255.255 represents no gateway
if (DefaultGatewayStr != "255.255.255.255")
ProcStartInfo.Arguments += " " + DefaultGatewayStr;
else
ProcStartInfo.Arguments += " " + IpAddrAryToStr(IpAddrAry); // clears the gateway if the same as the IP address
ProcStartInfo.Verb = "runas";
Process Proc = Process.Start(ProcStartInfo);
while (!Proc.WaitForExit(100)); //+++ Seems to cause a lockup if the UAC prompt is okayed too quickly
Console.WriteLine("netsh exit code = " + Proc.ExitCode);
}
catch
{
Console.WriteLine("netsh command failed or UAC prompt not Okayed");
}
The above generally works, but it causes the UAC prompt to appear, which is not desired and the Wait for Exit while loop locks up sometimes if the UAC prompt is okayed too quickly.
Second method:
MacAddrStr = "00E04C6821FE";
// Get the network interface
RetCode = -4;
NetworkInterface NetIf = null;
foreach (NetworkInterface Ni in NetworkInterface.GetAllNetworkInterfaces())
if (Ni.GetPhysicalAddress().ToString() == MacAddrStr)
{
NetIf = Ni;
break;
}
if (NetIf == null)
return RetCode;
Console.WriteLine("Ni found, MAC=" + MacAddrStr);
// Set the IP settings
RetCode = -5;
ManagementClass MgmtClass = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection MgmtObjCollection = MgmtClass.GetInstances();
foreach (ManagementObject MgmtObj in MgmtObjCollection)
{
if (MgmtObj["settingID"].ToString() == NetIf.Id)
{
Console.WriteLine("MgmtObj found, ID=" + MgmtObj["settingID"].ToString());
try
{
ManagementBaseObject RetMgmtObj;
// Set the IP address and subnet mask
ManagementBaseObject MgmtObjIp = MgmtObj.GetMethodParameters("EnableStatic");
MgmtObjIp["IPAddress"] = new string[] { IpAddrAryToStr(IpAddrAry) }; // IpAddrAryToStr() string output is in the format of 10.0.0.1
MgmtObjIp["SubnetMask"] = new string[] { IpAddrAryToStr(SubnetMaskAry) };
RetMgmtObj = MgmtObj.InvokeMethod("EnableStatic", MgmtObjIp, null);
Console.WriteLine("Set IP Result=" + IpAddrAryToStr(IpAddrAry) + " " +
IpAddrAryToStr(SubnetMaskAry) + " 0x" +
Convert.ToUInt32(RetMgmtObj.Properties["ReturnValue"].Value).ToString("X")); ;// Prints an error value of 0x80070005, which is access denied
// Set the Default Gateway - set to the same as IP address to clear
string DefaultGatewayStr = IpAddrAryToStr(DefaultGatewayAry);
if (DefaultGatewayStr == "255.255.255.255") // For us, 255.255.255.255 represents no gateway
DefaultGatewayStr = IpAddrAryToStr(IpAddrAry); // clears the gateway if the same as the IP address
ManagementBaseObject MgmtObjGw = MgmtObj.GetMethodParameters("SetGateways");
MgmtObjGw["DefaultIPGateway"] = new string[] { DefaultGatewayStr };
MgmtObjGw["GatewayCostMetric"] = new int[] { 1 };
RetMgmtObj = MgmtObj.InvokeMethod("SetGateways", MgmtObjGw, null);
Console.WriteLine("Set GW Result=" + DefaultGatewayStr + " 0x" +
Convert.ToUInt32(RetMgmtObj.Properties["ReturnValue"].Value).ToString("X")); // Prints an error value also, 67 as I remember
RetCode = 0;
break;
}
catch (Exception Ex)
{
Console.WriteLine("Ex=" + Ex.ToString());
break;
}
}
}
Developer technologies | C++
Developer technologies | C#
2 answers
Sort by: Most helpful
-
Sean Liming 4,766 Reputation points Volunteer Moderator
2022-05-27T22:30:15.14+00:00 -
Limitless Technology 44,766 Reputation points
2022-05-31T07:30:56.587+00:00 Hello KrisKazmar,
By default UAC is intended as a protection and notification measure for the security of the system and health of the OS, as well company/user content and assets. It is expected that may have some behavioral settings (such as the "accepted too quick") to prevent fooling the user, or unwantedly passing the notification or acceptance.
In this case scenario, it is understandable what you are trying to achieve and why, but it is still not expected as UAC behavior, therefor any workarounds or bypassed are expected to be problematic or unstable. In other words, that would be considered a "not recommended" implementation.
The best way in this case, would be to disable the UAC for these specific devices, as they are not expected to be interacted with unless Administrator. For this you can use a registry GPO setting, for the next path/key:
Path:HKEY_LOCAL_MACHINE > Software > Microsoft > Windows > Current Version > Policies > System
Key: EnableLUA
Value: 0 (disabled)
--If the reply is helpful, please Upvote and Accept as answer--