So I have an IIS10 webserver, running a quite a few applications, like:
+ Default Web Site
-First Application
-Second Application
-Third Application
We are using nLog to log stuff to a database, one of which is the current appdomain
${appdomain:format=Format}
as documented at https://github.com/NLog/NLog/wiki/AppDomain-Layout-Renderer.
This is great, except when I look at our consolidated logs, I see that the appdomain is logged as:
0002:/LM/W3SVC/2/ROOT-1-132036049222959352
I want to translate that into "Third Application" (So when I create a report, it will show up as "Third Application" instead of 0002:/LM/W3SVC/2/ROOT-1-132036049222959352.)
Conditions are:
I can't change the layoutrenderer.
I can't change the code of the applications.
I have to do this AFTER the data is logged. I assume that /LM/W3SVC/2/ROOT is what I need to transform, and I can't do it in the app, only in reporting.
I've tried Microsoft.Web.Administration, something like:
using (ServerManager sm = new ServerManager()){
var thisVal = (from s in sm.Sites
from app in s.Applications
from vDir in app.VirtualDirectories
where vDir.Path.Equals(currVal,StringComparison.InvariantCultureIgnoreCase)
select new KeyValuePair<string, string>(currVal, vDir.Path));
}
But I can't find the app root in there anywhere. I believe it's the same thing as https://learn.microsoft.com/en-us/previous-versions/iis/6.0-sdk/ms524308(v=vs.90), but that's the IIS metabase, which is apparently old and busted.
(the code above will be running on the same machine as the applications, so I don't have to worry about finding the correct server, just translating the name)
You can enumerate (and thus filter for) the AppDomain's id as such:
using (ServerManager s = new ServerManager())
{
var processList = from m in Process.GetProcessesByName("w3wp") select m.Id;
IEnumerable<WorkerProcess> workerP = (from p in s.ApplicationPools
from w in p.WorkerProcesses
where processList.Any(vn => vn == w.ProcessId)
select w);
foreach (var workProcess in workerP)
{
Console.WriteLine(
$"{workProcess.AppPoolName} Id:{workProcess.ProcessId} AppDomains Count: {workProcess.ApplicationDomains?.Count}");
var ad = workProcess.ApplicationDomains;
if (!ad.Any()) continue;
foreach (var curDomain in ad)
{
Console.WriteLine($"AppDomain: {curDomain.Id} {curDomain.VirtualPath}");
}
}
}
This will give you output that shows the AppDomain's ids, that you can get the vdir from:
DefaultAppPool Id:33180 AppDomains Count: 1
AppDomain: /LM/W3SVC/1/ROOT/
Related
I am trying to test some methods in my library using Google API. More specifically the Cloud Vision API. When I reference the library in LINQPad I get an error
FileNotFoundException: Error loading native library. Not found in any of the possible locations: C:\Users\\AppData\Local\Temp\LINQPad5_dgzgzeqb\shadow_fxuunf\grpc_csharp_ext.x86.dll,C:\Users\\AppData\Local\Temp\LINQPad5_dgzgzeqb\shadow_fxuunf\runtimes/win/native\grpc_csharp_ext.x86.dll,C:\Users\\AppData\Local\Temp\LINQPad5_dgzgzeqb\shadow_fxuunf../..\runtimes/win/native\grpc_csharp_ext.x86.dll
I have tried copying the dll into all of these locations as well as my LINQPad Plugins and the LINQPad folder. I have tried clearing Cancel and Clear query thinking I needed to reset it. I have also closed and reopened LINQPad thinking maybe it re-scans the directory on load. None of this has worked. Has LINQPad changed where to put dlls or am I missing something?
I am using Google.Cloud.Vision.V1
`
var file = new byte[128];
var _settingsCon = new SettingConnector();
var apiKey = Task.Run(() => _settingsCon.Get("Google:Key")).Result.Value;
var credential = Google.Apis.Auth.OAuth2.GoogleCredential.FromJson(apiKey);
var channel = new Grpc.Core.Channel(
ImageAnnotatorClient.DefaultEndpoint.ToString(),
credential.ToChannelCredentials());
var builder = new StringBuilder();
var image = Image.FromBytes(file);
var client = ImageAnnotatorClient.Create(channel);
var response = client.DetectDocumentText(image);
foreach (var page in response.Pages)
{
foreach (var block in page.Blocks)
{
foreach (var paragraph in block.Paragraphs)
{
builder.Append(paragraph);
}
}
}
builder.ToString().Dump();`
This is essentially the function. The file is a dummy file that would be passed in. It shouldn't matter cause it can't make the request any way. The Dump is used instead of return.
I want to get all a list of all installed drivers on my machine. For this purpose I use WMI. But for unknown reason all properties returned have empty values (except for deviceID, DriverVersion and Signer) .
What I tried and considered so far:
running with and without admin rights makes no difference
no methods found like fetch, load, reload on any of involved objects found
no option found like lazyload
pnputil.exe and driversearch.exe do return data of all drivers, but the outputs of those a very hard to interpret
This is the C#-code:
using (var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PnPSignedDriver"))
{
foreach (ManagementBaseObject u in searcher.Get())
{
foreach(PropertyData prop in u.Properties)
{
System.Console.WriteLine($"{prop.Name}={prop.Value}");
}
System.Console.WriteLine("===");
}
}
Output for first driver found:
Caption=
ClassGuid=
CompatID=
CreationClassName=
Description=
DeviceClass=
DeviceID=\\SVWPSW46\P3115 X WC 7120-D C S U A3
DeviceName=
DevLoader=
DriverDate=
DriverName=
DriverProviderName=
DriverVersion=2:6.0,2:5.2,2:5.1,2:5.0
FriendlyName=
HardWareID=
InfName=
InstallDate=
IsSigned=True
Location=
Manufacturer=
Name=
PDO=
Signer=Microsoft Windows
Started=
StartMode=
Status=
SystemCreationClassName=
SystemName=
===
...
I am trying to create a term in a SP 2013 term set. I am able to read the terms from the term set with the given credentials.
Settings:
The ServiceAccountLogonName user is one of the Term Store Admins
Code:
var siteUrl = ConfigHelper.GetValue("SharepointSiteUrl");
var clientContext = new ClientContext(siteUrl);
clientContext.Credentials = new NetworkCredential(ConfigHelper.GetValue("ServiceAccountLogonName"), ConfigHelper.GetValue("ServiceAccountPassword"));
var taxonomySession = TaxonomySession.GetTaxonomySession(clientContext);
var termStore = taxonomySession.TermStores.GetById(new Guid("dae0745c07ae40d6bf4b6c52e3172d6a"));
var termSet = termStore.GetTermSet(new Guid("f40eeb54-7c87-409d-96c7-75ceed6bff60"));
foreach (var tagName in tagNames)
{
var newTerm = termSet.CreateTerm(tagName, Thread.CurrentThread.CurrentUICulture.LCID, Guid.NewGuid());
newTerm.CreateLabel(tagName, Thread.CurrentThread.CurrentUICulture.LCID, true);
termStore.CommitAll();
clientContext.Load(newTerm);
clientContext.ExecuteQuery();
}
Error message when ExecuteQuery is run:
Failed to read from or write to database. Refresh and try again. If the problem
persists, please contact the administrator.
Does the credential need any specific rights on the term store or term set?
Is there anything else I am missing here?
Useful tutorial:
https://github.com/OfficeDev/TrainingContent/blob/master/O3656/O3656-8%20Developing%20advanced%20Taxonomy%20Scenarios%20in%20Office%20365/Lab.md
Make sure that your user has permissions to term store.
Go to central administration ==> manage service application ==> click on line (not link) of your service application ==> choose "Permissions" ribbon button and add your account.
Also make sure that your term set ist open for term creation. You can check the "IsOpenForTermCreation" of you termSet variable.
Third. Use Guid.NewGuid() instead of new Guid() in CreateTerm line.
Had time for some tests:
foreach (var tagName in tagNames)
{
var newTerm = termSet.CreateTerm(tagName, Thread.CurrentThread.CurrentUICulture.LCID, Guid.NewGuid());
}
termStore.CommitAll();
clientContext.Load(termStore);
clientContext.ExecuteQuery();
This worked for me after I've added my user to service application permissions.
I have a SharePoint 2010 site hosted on a remote server and I want to add users to one of the SharePoint groups automatically from another machine using C#. I've tried using web services as mentioned all over the internet as under:
class Program
{
static void Main(string[] args)
{
SPUserGroupRef.UserGroup usrGrpService = new SPUserGroupRef.UserGroup();
System.Net.NetworkCredential netCred = new System.Net.NetworkCredential(<my username>, <my password>, <my domain name>);
usrGrpService.Credentials = netCred;
usrGrpService.AddUserToGroup(<group name>, <new user full name>, <domain\new user name>, <new user email address>, <notes>);
}
}
Note:
1. SPUserGroupRef is the web service reference to http:///_vti_bin/usergroup.asmx
2. All the angle-bracketed entities mentioned above in the code are strings.
1st 3 lines of code inside Main execute fine but the 4th line fails with "Exception of type Microsoft.SharePoint.SoapServer.SoapServerException was thrown". I am pretty new to SharePoint so may be I am missing something here. Can someone help me figure out how to get over this issue or may be suggest another approach that might work (but remember my SharePoint site is hosted on a remote server, not on my local machine.
why dont you use Sharepoint 2010 client object model,I have not tested below code, but it should work.
namespace ClientObjectModel
{
class Program
{
static void Main(string[] args)
{
// Add a new user to a particular group
string siteURL = "http://serverName:1111/sites/SPSiteDataQuery/";
ClientContext context = new ClientContext(siteURL);
GroupCollection groupColl = context.Web.SiteGroups;
Group group = groupColl.GetById(7);
UserCreationInformation userCreationInfo = new UserCreationInformation();
userCreationInfo.Email = "";
userCreationInfo.LoginName = #"DomainName\UserName";
userCreationInfo.Title = "SharePoint Developer";
User user = group.Users.Add(userCreationInfo);
context.ExecuteQuery();
}
}
}
Microsoft.SharePoint and Microsoft.SharePoint.Client
let me know if it works?
I have an event receiver that is using the ItemUpdating event. I am trying to disinherit the item's permissions from parent and strip all permissions on the item upon being uploaded to the Drop Off Library. The reason for this is that the document contains sensitive information and should not be visible to anyone once it arrives in the Drop Off Library.
The code below is throwing the following error when executing the CurrentListItem.BreakRoleInheritence(true) line upon reaching the Drop Off Library: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite oSiteCollection = new SPSite(properties.ListItem.Web.Url))
{
using (SPWeb oWebsite = oSiteCollection.RootWeb)
{
SPListItem CurrentListItem = properties.ListItem;
SPRoleAssignmentCollection SPRoleAssColn = CurrentListItem.RoleAssignments;
oSiteCollection.AllowUnsafeUpdates = true;
oWebsite.AllowUnsafeUpdates = true;
CurrentListItem.BreakRoleInheritance(true);
oSiteCollection.AllowUnsafeUpdates = true;
oWebsite.AllowUnsafeUpdates = true;
for (int i = SPRoleAssColn.Count - 1; i >= 0; i--)
{
if (SPRoleAssColn[i].Member.Name != "System Account")
{
SPRoleAssColn.Remove(i);
}
}
}
}
});
I have also done the following things:
- made sure the Identity of the app pool is a site collection admin
- tried to get the list item again using GetItemById (but this throws an error that the item does not exist, since the item has still not been published yet - we need to remove permissions before the document is published - and we cannot force a check-in otherwise the drop off library might process and move the document to the its target library)
- tried getting the web and site options using guids
- tried many different combinations of placements with AllowUnsafeUpdates
- used the user token of a site collection admin to open the web objects
For some reason, the code above works fine when the document reaches the target library (as we are removing all the permissions AGAIN once the document arrives at the destination). This happens because the document is moved from the drop off library to the target library using the System Account.
Any thoughts on how to get around the "Access is Denied" error while utilizing a similar approach as above?
And how this item is being sent to Drop off library? Via workflow, or when using OfficialFile.asmx? Can you check if this eventreceiver works properly when you manually upload file (most probably you will have to click 'submit' to force update, but maybe you can set fields in such way, that none of your Rules would match? I files get there via workflow, make sure that also account on which SPTimer4 service is running is site administrator on this site collection.
Also be careful, - i think there are two things that may not work as you expect in your event receiver:
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (var oSiteCollection = new SPSite(properties.ListItem.Web.Url))
{
using (var oWebsite = oSiteCollection.RootWeb)
{
var currentListItem = properties.ListItem;
oSiteCollection.AllowUnsafeUpdates = true;
oWebsite.AllowUnsafeUpdates = true;
currentListItem.BreakRoleInheritance(true);
//You should take the RoleAssignments after breaking inheritance our you will be working on parents permissions.
var spRoleAssColn = currentListItem.RoleAssignments;
oSiteCollection.AllowUnsafeUpdates = true;
oWebsite.AllowUnsafeUpdates = true;
for (int i = spRoleAssColn.Count - 1; i >= 0; i--)
{
//I think it won't allow you to remove permissions for site administrator
if (spRoleAssColn[i].Member.Name != "System Account" && !oWebsite.EnsureUser(spRoleAssColn[i].Member.LoginName).IsSiteAdmin)
{
spRoleAssColn.Remove(i);
}
}
}
}
});