Microsoft.Web.Administration and Removing IIS Apps Iteratively - c#

I am using C# with Microsoft.Web.Administration to remove all of the apps inside of a site. I do not want to remove the site app itself (path = "/").
Here's the code:
ServerManager manager = new ServerManager();
for (int i = 0; i < manager.Sites[siteName].Applications.Count; i++)
{
if (manager.Sites[siteName].Applications[i].Path != "/")
{
manager.Sites[siteName].Applications.RemoveAt(i);
}
}
manager.CommitChanges();
What happens with this code is that some apps get removed and others don't, and which apps get removed and which don't are different each run.
manager.Sites[sitename].Applications.Clear();
will work, but it will also remove the application with path = "/", which I don't want.
I tried doing something like this, too:
Application baseApp = null;
for (int i = 0; i < manager.Sites[siteName].Applications.Count; i++)
{
if (manager.Sites[siteName].Applications[i].Path == "/")
{
baseApp = manager.Sites[siteName].Applications[i];
}
}
manager.Sites[siteName].Applications.Clear();
if (baseApp != null)
{
manager.Sites[siteName].Applications.Add(baseApp);
}
manager.CommitChanges();
But that didn't work either. The app with path = "/" was never re-added, or wasn't added properly.
Is there anyone with more experience with Microsoft.Web.Automation who has some insights on removing more than one app at a time that can help me out with this?

As it turns out, I was making the classic stupid mistake of altering the collection while enumerating through it. The first app would be removed and the count would go down. Some apps were never getting looked at. The randomness of the removal was simply due to the unordered nature of the collection. Silly me!
This works:
List<Application> appsToRemove = new List<Application>();
for (int i = 0; i < manager.Sites[siteName].Applications.Count; i++)
{
if (manager.Sites[siteName].Applications[i].Path != "/")
{
Console.WriteLine("Removing {0}", manager.Sites[siteName].Applications[i].Path);
appsToRemove.Add(manager.Sites[siteName].Applications[i]);
}
}
foreach (Application a in appsToRemove)
{
manager.Sites[siteName].Applications.Remove(a);
}
manager.CommitChanges();

Related

How to test akka.net persistent actors

I'am using [Akka.Net 1.3.1] a mix of ReceiveActors and ReceivePersistentActors and now I want to write tests for my actorsystem.
MyPersistentActor inherits from ReceivePersistentActor and MyActor inherits from ReceiveActor.
I also installed Akka.TestKit using version 1.3.1 .
But it seems that only ReceiveActors can be tested by Akka.TestKit.
IActorRef myActorRef = this.Sys.ActorOf<MyActor>(); // is fine
IActorRef myPersistentActorRef = this.Sys.ActorOf<MyPersistentActor>(); // is a problem
I also found the nuget package Akka.Persistence.TestKit version 1.2.3.43-beta . The beta wasn't changed since three month and only support akka 1.2.2 . Is it still in development or is it dead. I can not find any kind of information regarding that.
How do you test your persistent actors?
Thanks for your help!
Richi
Akka.Persistence.TestKit has been renamed to Akka.Persistence.TCK and it is used only for testing custom event journal and snapshot store implementations for compatibility with Akka.Persistence protocol. It doesn't bring any utilities for testing user actors.
There are no built-in methods to cooperate with journals/snapshot stores for testing purposes beside having implementations of them working in-memory. With that being said, you can actually work with journal/snapshot store just like with any other actor. If you look into implementations of persistence TCK specs like JournalSpec, you may get some insights into how that protocol works.
For example, if you want to initialize your journal with some events before firing the test case, you can do it like following:
void InitWithEvents(string persistenceId, params object[] events)
{
var probe = CreateTestProbe();
var writerGuid = Guid.NewGuid().ToString();
var writes = new AtomicWrite[events.Length];
for (int i = 0; i < events.Length; i++)
{
var e = events[i];
writes[i] = new AtomicWrite(new Persistent(e, i+1, persistenceId, "", false, ActorRefs.NoSender, writerGuid));
}
var journal = Persistence.Instance.Apply(Sys).JournalFor(null);
journal.Tell(new WriteMessages(writes, probe.Ref, 1));
probe.ExpectMsg<WriteMessagesSuccessful>();
for (int i = 0; i < events.Length; i++)
probe.ExpectMsg<WriteMessageSuccess>();
}
PS: There is clearly a missing part in the persistence TestKit API, any contributions on that field are more than welcome.
I know this is an ols answer, but I couldn't find any better resource. In my tests I am actually only interested if the correct event(s) is (are) persisted after I give my command. Multiple events could be raised by starting a saga. Most of the time I am only interested in the last persisted event.
If somebody is hitting the same issue as me, this is how I fixed getting the last message, based on Bartosz initWithEvents.
private void InitWithEvents(string persistenceId, IList<object> events)
{
var probe = CreateTestProbe();
var writerGuid = Guid.NewGuid().ToString();
var writes = new AtomicWrite[events.Count];
for (int i = 0; i < events.Count; i++)
{
var e = events[i];
writes[i] = new AtomicWrite(new Persistent(e, i+1, persistenceId, "", false, ActorRefs.NoSender, writerGuid));
}
journal = Persistence.Instance.Apply(Sys).JournalFor(null);
journal.Tell(new WriteMessages(writes, probe.Ref, 1));
probe.ExpectMsg<WriteMessagesSuccessful>();
for (int i = 0; i < events.Count; i++)
probe.ExpectMsg<WriteMessageSuccess>();
}
private object GetLastPersistedMessageFromJournal(string persistenceId)
{
var repointable = journal as RepointableActorRef;
var underlying = repointable.Underlying as ActorCell;
PropertyInfo prop = typeof(ActorCell).GetProperty("Actor", BindingFlags.NonPublic | BindingFlags.Instance);
MethodInfo getter = prop.GetGetMethod(nonPublic: true);
MemoryJournal jrnl = getter.Invoke(underlying, null) as MemoryJournal;
var read = jrnl?.Read(persistenceId, 0, Int64.MaxValue, Int64.MaxValue);
return read?.Last().Payload;
}

Could not load type 'SAS.LanguageServiceCarriageControl' from assembly

In addition to using the integration components of SAS Enterprise Edition, I am using parts of the following project I found on Github to connect with a SAS server. The goal here is to command the server to run programs on a schedule. However, the programs need to be modified each time, which is why I am attempting to trigger them to run in this manner. However, it keeps throwing an error at lang.FlushLogLines.
https://github.com/cjdinger/SasHarness
SAS.Workspace ws = server.Workspace;
List<string> results = new List<string>();
Array CCs;
Array lineTypes;
Array logLines;
int maxLines = 100;
SAS.LanguageService lang = (SAS.LanguageService)ws.LanguageService;
Array linesVar = (Array)new string[] { PROGRAM_TEXT };
lang.SubmitLines(ref linesVar);
//THROWS AN ERROR HERE
lang.FlushLogLines(maxLines, out CCs, out lineTypes, out logLines);
for (int i = 0; i < logLines.Length; i++)
{
results.Add((string)logLines.GetValue(i));
}
After a bit of research I found the following thread where it is recommended to make sure that all the required dlls are referenced in my project. The mystery here is that I do have them referenced, but the error still occurs.
http://blogs.sas.com/content/sasdummy/2013/06/09/sas-client-with-microsoft-dot-net/
Moreover, starting after the very first line, the code is no longer using SASHarness, but is using native SAS integration libraries only. The code above is also based on examples listed in the following documentation from SAS.
https://support.sas.com/documentation/cdl/en/itechwcdg/61500/PDF/default/itechwcdg.pdf (page 27-28)
Has anybody encountered an error similar to this, and if so, how did you correct it?
Strangely, fixing this error required declaring an instance for each of the assemblies that could not be loaded. I have no idea why this fixes the problem, but it works now.
SAS.Workspace ws = server.Workspace;
string wsId = ws.UniqueIdentifier;
List<string> results = new List<string>();
Array CCs;
Array lineTypes;
Array logLines;
int maxLines = 100;
SAS.LanguageService lang = (SAS.LanguageService) server.Workspace.LanguageService;
Array linesVar = (Array) new string[] { PROGRAM_TEXT };
lang.SubmitLines(ref linesVar);
//For some reason, these two declarations need to be here
SAS.LanguageServiceCarriageControl CarriageControl = new SAS.LanguageServiceCarriageControl();
SAS.LanguageServiceLineType LineType = new SAS.LanguageServiceLineType();
lang.FlushLogLines(maxLines, out CCs, out lineTypes, out logLines);
for (int i = 0; i < logLines.Length; i++)
{
results.Add((string) logLines.GetValue(i));
}

Trying to Add itemSubtotalAddRq, but getting error for it

I have been making an app for a friend, but recently got stuck. For some reason, when I try to test "itemSubtotalAddRq" I get the following error:
Request[3]: ItemSubtotalAddRq ItemSubtotalAdd
Name: required fiels is missing
End of ItemSubtotalAdd
Im not sure what it is, but I know its one of the ItemSubtotalAddRq lines, or im using iItemSubtotalAdd wrong.
public void SalesInfoAdd(IMsgSetRequest requestMsgSet)
{
ISalesReceiptAdd salesReceiptAddRq = requestMsgSet.AppendSalesReceiptAddRq();
//IItemSubtotalAdd itemSubtotalAddRq = requestMsgSet.AppendItemSubtotalAddRq();
salesReceiptAddNew = new List<ISalesReceiptLineAdd>();
salesReceiptAddRq.CustomerRef.FullName.SetValue(Form.phoneNumber.Text);
salesReceiptAddRq.IsPending.SetValue(true);
salesReceiptAddRq.IsTaxIncluded.SetValue(false);
salesReceiptAddRq.FOB.SetValue(Form.orderID.Text);
salesReceiptAddNew.Clear();
int cnt = 0;
//while (i < Form.productID.Count)
for (int j = 0; j < Form.productID.Count; j++)
{
salesReceiptAddNew.Add(salesReceiptAddRq.ORSalesReceiptLineAddList.Append().SalesReceiptLineAdd);
salesReceiptAddNew[j].ItemRef.FullName.SetValue(Form.productID[j].ToString());
salesReceiptAddNew[j].ORRatePriceLevel.Rate.SetValue(Convert.ToDouble(Form.pricesList.Items[j]));
salesReceiptAddNew[j].Quantity.SetValue(Form.QBqt[j]);
salesReceiptAddNew[j].Desc.SetValue(Form.productsList.Items[j].ToString().ToUpper() + " -" + " " +
Form.QBsku[j].ToString().ToUpper());
cnt = j;
}
if (Form.DiscountType.Text != "None" || Form.DiscountType.Text != " ")
{
if (Form.productID.Count >= 2)
{
cnt++;
salesReceiptAddNew.Add(salesReceiptAddRq.ORSalesReceiptLineAddList.Append().SalesReceiptLineAdd);
salesReceiptAddNew[cnt].ItemRef.FullName.SetValue("SUBTOTAL");
salesReceiptAddNew[cnt].ORRatePriceLevel.Rate.SetValue(Form.totalOfAllItems);
//itemSubtotalAddRq.Name.SetValue("SUBTOTAL");
//itemSubtotalAddRq.IsActive.SetValue(true);
}
else
itemSubtotalAddRq.IsActive.SetValue(false);
cnt++;
salesReceiptAddNew.Add(salesReceiptAddRq.ORSalesReceiptLineAddList.Append().SalesReceiptLineAdd);
salesReceiptAddNew[cnt].ItemRef.FullName.SetValue(Form.DiscountType.Text);
}
if(Form.freeShipping.Checked == false)
{
cnt++;
salesReceiptAddNew.Add(salesReceiptAddRq.ORSalesReceiptLineAddList.Append().SalesReceiptLineAdd);
salesReceiptAddNew[cnt].ItemRef.FullName.SetValue("SHIPPING");
salesReceiptAddNew[cnt].ORRatePriceLevel.Rate.SetValue(Convert.ToDouble(Form.shipping.Text));
}
IMsgSetResponse responseMsgSet = sessionManager.DoRequests(requestMsgSet);
}
this is the only solution i could think of, and it still doesn't work. any thoughts?
I think you are referring to 'ItemType' which is under 'Line' tag
Ref - https://developer.intuit.com/docs/0025_quickbooksapi/0050_data_services/v2/0500_quickbooks_windows/0600_object_reference/salesreceipt
XML
<Add RequestId="ca435123492c41b891f7841cf4d0e81d" xmlns="http://www.intuit.com/sb/cdm/v2">
<OfferingId>ipp</OfferingId>
<ExternalRealmId>65123456</ExternalRealmId>
<SalesReceipt>
<Header>
---
</Header>
<Line>
<Id idDomain="QB">66</Id>
<Desc>Description</Desc>
<ItemId idDomain="QB">4</ItemId>
<ItemName>Dusting</ItemName>
<ItemType>Subtotal</ItemType>
<UnitPrice>1231</UnitPrice>
</Line>
</SalesReceipt>
</Add>
Using Java, I had coded like this. I think, there should be some similar enums/classes in .Net too. Can you take a look at the .Net docs
Link - http://developer-static.intuit.com/SDKDocs/QBV2Doc/IntuitDataServicesSDK/
Instead of 'SUBTOTAL', you should use 'Subtotal'. In the service background, allowed values are [Assembly, Fixed Asset, Group, Inventory, Other Charge, Payment, Product, Service, Subtotal].
You can try this use case in the ApiExplorer.
Link - https://developer.intuit.com/apiexplorer?apiname=V2QBD#SalesReceipt
Java Code
QBSalesReceipt entityPojo = QBObjectFactory.getQBObject(context, QBSalesReceipt.class);
SalesReceiptLine receiptLine = QBObjectFactory.getQBObject(context, SalesReceiptLine.class);
receiptLine.setItemType(ItemTypeEnum.SUBTOTAL);
ArrayList receiptLines = new ArrayList();
receiptLines.add(receiptLine);
entityPojo.setLine(receiptLines);
QBSalesReceiptService service = QBServiceFactory.getService(context, QBSalesReceiptService.class);
service.addSalesReceipt(context, entityPojo);
Plz let me know how it goes.
Thanks

Is There a Settings Viewer/Manager for Windows 8 apps?

For testing my roaming and/or local settings, I'd like to be able to clear all the settings.
I could do it like so, I guess:
App.roamingSettings.Value["SomeVal"] = string.Empty;
App.roamingSettings.Value["SomeOtherVal"] = string.Empty;
App.roamingSettings.Value["YetAnotherVal"] = string.Empty;
...
etc.
...but I'd rather have some quicker, cleaner (no pun intended) way. Is there one?
Also, relatedly, it would be nice to have a "Settings Manager" utility for quickly verifying they are what you think they are, too. Does anybody know of one?
UPDATE
This is my attempt to "roll my own" based on the answer; so far, no go:
string roamingSettingPairs = string.Empty;
for (int i = 0; i < App.roamingSettings.Values.Count; i++)
{
// Print out whatever you want to verify that everything is as it should be
//string roamingSettingName = App.roamingSettings.Name[i].ToString();
//string roamingSettingValue = App.roamingSettings.Values[i].ToString();
Dictionary<string, object> roamingSettingVals = App.roamingSettings.Values;
string roamingSettingName = roamingSettingVals.Keys[i];
object roamingSettingObj = roamingSettingVals.Values[i];
//roamingSettingPairs = string.Format("{0}{1}={2}{3}", roamingSettingPairs, roamingSettingName,
// roamingSettingValue, Environment.NewLine);
}
You can delete all of your roaming settings using this code:
ApplicationData.Current.RoamingSettings.Values.Clear();
For a Settings Manager, I would probably just use a for loop like so:
for (int i = 0; i < ApplicationData.Current.RoamingSettings.Values.Count; i++)
{
// Print out whatever you want to verify that everything is as it should be
}

WMPLib: player.mediaCollection.getAll().count is always 0

I am attempting to write code that reads each item from the user's Windows Media Player library. This code works for the majority of users, but for some users, getAll() will return an empty list when they clearly have hundreds or thousands of items in their Windows Media Player library.
var player = new WindowsMediaPlayer();
var collection = player.mediaCollection;
var list = collection.getAll();
int total = list.count;
I am referencing the WMPLib namespace by adding a COM reference to wmp.dll. My application ships with Interop.WMPLib.dll. How would some users' machines be configured in such a way that they run Windows Media Player with many songs in their library, but WMPLib fails to function correctly? Furthermore, what workarounds exist to reliably read the user's Windows Media Player library in all cases?
Try this snippet and see if it works for you.
public List<MusicEntry> GetMusicLibrary()
{
List<MusicEntry> entries;
IWMPPlaylist mediaList = null;
IWMPMedia mediaItem;
try
{
// get the full audio media list
mediaList = media.getByAttribute("MediaType", "Audio");
entries = new List<MusicEntry>(mediaList.count);
for (int i = 0; i < mediaList.count; i++)
{
mediaItem = mediaList.get_Item(i);
// create the new entry and populate its properties
entry = new MusicEntry()
{
Title = GetTitle(mediaItem),
Album = GetAlbum(mediaItem),
Artist = GetArtist(mediaItem),
TrackNumber = GetTrackNumber(mediaItem),
Rating = GetRating(mediaItem),
FileType = GetFileType(mediaItem)
};
entries.Add(entry);
}
}
finally
{
// make sure we clean up as this is COM
if (mediaList != null)
{
mediaList.clear();
}
}
return entries;
}
For more information refer to this excellent article on Code Project.
http://www.codeproject.com/Articles/36338/Export-Windows-Media-Player-Music-Metadata-to-XML

Categories