Read output from Process in custiom action dont return symbols selected language Wix - wix

I use the same code in custom action wix and console app. In custom action it dont return polish symbol "ł" and "ą" in custom action. Replaces them with other symbols or spaces. In console app it works well.
Already in the "message" variable there isnt polish letters.
private static void RunTest(Session session)
{
try
{
Process p = CreateProcess();
p.StartInfo.FileName = "....exe"; ;
p.StartInfo.Arguments = "-t";
string message = "";
int errorCount = 0;
p.OutputDataReceived += (sender, args) =>
{
if (args.Data == null)
return;
message += args.Data;
message += "\n";
};
p.ErrorDataReceived += (sender, args) =>
{
if (args.Data == null)
return;
errorCount++;
message += args.Data;
message += "\n";
};
p.Start();
p.BeginOutputReadLine();
p.WaitForExit();
SaveNewRtf(session, message);
}
catch (Exception)
{
}
}
private static Process CreateProcess()
{
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.CreateNoWindow = true;
return p;
}
Edit:
This is happen because Massages from Process are in Unicode. But unfortunately I don't know how repair that. I changed encoding to utf-8 for messages in Program I run by Process and still the message are download in Unicode.

I solved it by
p.StartInfo.StandardOutputEncoding = OemEncoding.GetDefaultOemCodePageEncoding();
and
public static class OemEncoding
{
private const Int32 MAX_DEFAULTCHAR = 2;
private const Int32 MAX_LEADBYTES = 12;
private const Int32 MAX_PATH = 260;
private const UInt32 CP_OEMCP = 1;
public static Encoding GetDefaultOemCodePageEncoding()
{
CPINFOEX cpInfoEx;
if (GetCPInfoEx(CP_OEMCP, 0, out cpInfoEx) == 0)
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture,
"GetCPInfoEx() failed with error code {0}",
Marshal.GetLastWin32Error()));
return Encoding.GetEncoding((int)cpInfoEx.CodePage);
}
[DllImport("Kernel32.dll", EntryPoint = "GetCPInfoExW", SetLastError = true)]
private static extern Int32 GetCPInfoEx(UInt32 CodePage, UInt32 dwFlags, out CPINFOEX lpCPInfoEx);
[StructLayout(LayoutKind.Sequential)]
private unsafe struct CPINFOEX
{
internal UInt32 MaxCharSize;
internal fixed Byte DefaultChar[MAX_DEFAULTCHAR];
internal fixed Byte LeadByte[MAX_LEADBYTES];
internal Char UnicodeDefaultChar;
internal UInt32 CodePage;
internal fixed Char CodePageName[MAX_PATH];
}
}

Related

How to pass custom buffer to windows runtime methods

I am trying to pass my custom buffer to WinRT objects that take IBuffer as argument. Here is what I have so far;
static const uint32_t ARRAY_SIZE = 4096;
struct ArrayBuffer : implements<ArrayBuffer, IBuffer, winrt::impl::IBufferByteAccess>
{
uint32_t Capacity() const { return ARRAY_SIZE; }
uint32_t Length() const { return length; }
void Length(uint32_t value)
{
if (value > ARRAY_SIZE)
throw hresult_invalid_argument();
length = value;
}
int32_t __stdcall Buffer(uint8_t** value)
{
*value = &data[0];
return 0;
}
private:
uint32_t length = 0;
uint8_t data[ARRAY_SIZE];
};
I am trying to use it like this;
fire_and_forget WebSocketServer::readLoop(StreamSocket socket)
{
IBuffer buffer = make<ArrayBuffer>();
auto istream = socket.InputStream();
while (true)
{
try
{
co_await istream.ReadAsync(buffer, ARRAY_SIZE, InputStreamOptions::None);
}
catch (hresult_error const& ex)
{
hresult hr = ex.code();
hstring message = ex.message();
}
if (buffer.Length() == 0)
break;
buffer.Length(0);
}
}
However, I am getting hresult_no_interface exception when I call ReadAsync method.

FileStore.CreateFile returns ntStatus = 3221226071

I am using this SMBLibrary. Related to this closed issue, I sometimes get ntStatus = 3221226071 when I attempt to FileStore.CreateFile(). What does "DFS pathname not on local server" mean? If I keep trying, eventually it will work. Leads me to believe some resources are being held or not released/disconnected. Any ideas here?
"SMBLibrary" Version="1.4.8"
Here is my code:
[Fact]
public void Unit_Test_To_Test_SMBLibrary()
{
var server = "myRemoteServer";
var shareName = "shareddir";
var windowsPath = "Data\\Folder1\\unittest";
var random = new System.Random();
var filename = "createdBySmbclient" + random.Next(1, 10).ToString() + ".txt";
var domain = "my.domain";
var username = "myUser";
var password = "--put secret password here--";
var client = new SMB2Client();
bool isConnected = client.Connect(server, SMBTransportType.DirectTCPTransport);
if(isConnected)
{
try
{
NTStatus ntStatus = client.Login(domain, username, password);
if (ntStatus == NTStatus.STATUS_SUCCESS)
{
ISMBFileStore fileStore = client.TreeConnect(shareName, out ntStatus);
object fileHandle;
FileStatus fileStatus;
var windowsPathWithFile = Path.Combine(windowsPath, filename);
// 1st, create empty file.
ntStatus = fileStore.CreateFile(
out fileHandle,
out fileStatus,
windowsPathWithFile,
AccessMask.GENERIC_READ | AccessMask.GENERIC_WRITE,
0,
ShareAccess.None,
CreateDisposition.FILE_OPEN_IF,
CreateOptions.FILE_NON_DIRECTORY_FILE,
null
);
// create file contents and get the bytes
byte[] filebytes = Encoding.ASCII.GetBytes("hello world");
// 2nd, write data to the newly created file
if (ntStatus == NTStatus.STATUS_SUCCESS && fileStatus == FileStatus.FILE_CREATED)
{
int numberOfBytesWritten;
ntStatus = fileStore.WriteFile(out numberOfBytesWritten, fileHandle, 0, filebytes);
fileStore.FlushFileBuffers(fileHandle);
fileStore.CloseFile(fileHandle);
fileStore.Disconnect();
_logger.LogDebug(string.Format("Export successful: {0}", windowsPathWithFile));
}
else
{
throw new Exception(string.Format("ERROR: ntStatus = {0}, fileStatus = {1}", ntStatus, fileStatus));
}
}
}
finally
{
client.Logoff();
client.Disconnect();
}
}
}

error is occuring while creating custom tokenizer in lucene 7.3

I m trying to create new tokenizer by refering book tamingtext (which uses lucene 3.+ api) using new lucene api 7.3, but it is giving me error as mentioned below
java.lang.IllegalStateException: TokenStream contract violation: reset()/close() call missing, reset() called multiple times, or subclass does not call super.reset(). Please see Javadocs of TokenStream class for more information about the correct consuming workflow.
at org.apache.lucene.analysis.Tokenizer$1.read(Tokenizer.java:109)
at java.io.Reader.read(Reader.java:140)
at solr.SentenceTokenizer.fillSentences(SentenceTokenizer.java:43)
at solr.SentenceTokenizer.incrementToken(SentenceTokenizer.java:55)
at solr.NameFilter.fillSpans(NameFilter.java:56)
at solr.NameFilter.incrementToken(NameFilter.java:88)
at spec.solr.NameFilterTest.testNameFilter(NameFilterTest.java:81)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
Here is my SentenceTokenizer class
Initializing method, in older api there was super(Reader); but in current api there is no access to Reader class
public SentenceTokenizer(SentenceDetector detector) {
super();
setReader(reader);
this.sentenceDetector = detector;
}
Here is my reset method
#Override
public void reset() throws IOException {
super.reset();
sentenceDetector = null;
}
When i tried to access this method from custom TokenFilter, I m getting above error
public void fillSentences() throws IOException {
char[] c = new char[256];
int size = 0;
StringBuilder stringBuilder = new StringBuilder();
while ((size = input.read(c)) >= 0) {
stringBuilder.append(c, 0, size);
}
String temp = stringBuilder.toString();
inputSentence = temp.toCharArray();
sentenceSpans = sentenceDetector.sentPosDetect(temp);
tokenOffset = 0;
}
#Override
public final boolean incrementToken() throws IOException {
if (sentenceSpans == null) {
//invoking following method
fillSentences();
}
if (tokenOffset == sentenceSpans.length) {
return false;
}
Span sentenceSpan = sentenceSpans[tokenOffset];
clearAttributes();
int start = sentenceSpan.getStart();
int end = sentenceSpan.getEnd();
charTermAttribute.copyBuffer(inputSentence, start, end - start);
positionIncrementAttribute.setPositionIncrement(1);
offsetAttribute.setOffset(start, end);
tokenOffset++;
return true;
}
Here is my custom TokenFilter class
public final class NameFilter extends TokenFilter {
public static final String NE_PREFIX = "NE_";
private final Tokenizer tokenizer;
private final String[] tokenTypeNames;
private final NameFinderME[] nameFinderME;
private final KeywordAttribute keywordAttribute = addAttribute(KeywordAttribute.class);
private final PositionIncrementAttribute positionIncrementAttribute = addAttribute(PositionIncrementAttribute.class);
private final CharTermAttribute charTermAttribute = addAttribute(CharTermAttribute.class);
private final OffsetAttribute offsetAttribute = addAttribute(OffsetAttribute.class);
private String text;
private int baseOffset;
private Span[] spans;
private String[] tokens;
private Span[][] foundNames;
private boolean[][] tokenTypes;
private int spanOffsets = 0;
private final Queue<AttributeSource.State> tokenQueue =
new LinkedList<>();
public NameFilter(TokenStream in, String[] modelNames, NameFinderME[] nameFinderME) {
super(in);
this.tokenizer = SimpleTokenizer.INSTANCE;
this.nameFinderME = nameFinderME;
this.tokenTypeNames = new String[modelNames.length];
for (int i = 0; i < modelNames.length; i++) {
this.tokenTypeNames[i] = NE_PREFIX + modelNames[i];
}
}
//consumes tokens from the upstream tokenizer and buffer them in a
//StringBuilder whose contents will be passed to opennlp
protected boolean fillSpans() throws IOException {
if (!this.input.incrementToken()) return false;
//process the next sentence from the upstream tokenizer
this.text = input.getAttribute(CharTermAttribute.class).toString();
this.baseOffset = this.input.getAttribute(OffsetAttribute.class).startOffset();
this.spans = this.tokenizer.tokenizePos(text);
this.tokens = Span.spansToStrings(spans, text);
this.foundNames = new Span[this.nameFinderME.length][];
for (int i = 0; i < nameFinderME.length; i++) {
this.foundNames[i] = nameFinderME[i].find(tokens);
}
//insize
this.tokenTypes = new boolean[this.tokens.length][this.nameFinderME.length];
for (int i = 0; i < nameFinderME.length; i++) {
Span[] spans = foundNames[i];
for (int j = 0; j < spans.length; j++) {
int start = spans[j].getStart();
int end = spans[j].getEnd();
for (int k = start; k < end; k++) {
this.tokenTypes[k][i] = true;
}
}
}
spanOffsets = 0;
return true;
}
#Override
public boolean incrementToken() throws IOException {
//if there's nothing in the queue
if(tokenQueue.peek()==null){
//no span or spans consumed
if (spans==null||spanOffsets>=spans.length){
if (!fillSpans())return false;
}
if (spanOffsets>=spans.length)return false;
//copy the token and any types
clearAttributes();
keywordAttribute.setKeyword(false);
positionIncrementAttribute.setPositionIncrement(1);
int startOffset = baseOffset +spans[spanOffsets].getStart();
int endOffset = baseOffset+spans[spanOffsets].getEnd();
offsetAttribute.setOffset(startOffset,endOffset);
charTermAttribute.setEmpty()
.append(tokens[spanOffsets]);
//determine of the current token is of a named entity type, if so
//push the current state into the queue and add a token reflecting
// any matching entity types.
boolean [] types = tokenTypes[spanOffsets];
for (int i = 0; i < nameFinderME.length; i++) {
if (types[i]){
keywordAttribute.setKeyword(true);
positionIncrementAttribute.setPositionIncrement(0);
tokenQueue.add(captureState());
positionIncrementAttribute.setPositionIncrement(1);
charTermAttribute.setEmpty().append(tokenTypeNames[i]);
}
}
}
spanOffsets++;
return true;
}
#Override
public void close() throws IOException {
super.close();
reset();
}
#Override
public void reset() throws IOException {
super.reset();
this.spanOffsets = 0;
this.spans = null;
}
#Override
public void end() throws IOException {
super.end();
reset();
}
}
here is my test case for following class
#Test
public void testNameFilter() throws IOException {
Reader in = new StringReader(input);
Tokenizer tokenizer = new SentenceTokenizer( detector);
tokenizer.reset();
NameFilter nameFilter = new NameFilter(tokenizer, modelName, nameFinderMES);
nameFilter.reset();
CharTermAttribute charTermAttribute;
PositionIncrementAttribute positionIncrementAttribute;
OffsetAttribute offsetAttribute;
int pass = 0;
while (pass < 2) {
int pos = 0;
int lastStart = 0;
int lastEnd = 0;
//error occur on below invoke
while (nameFilter.incrementToken()) {
}
}
I have added following changes in my code and it work fine but i m now sure it is correct answer
public SentenceTokenizer(Reader reader,SentenceDetector sentenceDetector) {
super();
this.input =reader;
this.sentenceDetector = sentenceDetector;
}

binding is used in WCF as a remoting alternative

If we want to replace remoting to WCF what biding is used ?
If we have used a shared dll beetwen two application in remoting to send message.
how this task can be done in WCF.
The answer would depend on your infrastructure. If your services are all on the same machine, you could use NetNamedPipeBinding. If services and consumers are on different machines, you could use either NetTcpBinding or BasicHttpBinding.
This solved my purpose...
private const int RF_TESTMESSAGE = 0xA123;
const int WM_USER = 0x0400;
const int WM_CUSTOM_MESSAGE = WM_USER + 0x0001;
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int SendMessage(IntPtr hwnd, [MarshalAs(UnmanagedType.U4)] int Msg, IntPtr wParam, int lParam);
public FormVideoApp()
{
InitializeComponent();
lblProcID.Text = string.Format("This process ID: {0}", Process.GetCurrentProcess().Id);
}
private void button1_Click(object sender, EventArgs e)
{
//get this running process
Process proc = Process.GetCurrentProcess();
//get all other (possible) running instances
//Process[] processes = Process.GetProcessesByName(proc.ProcessName);
Process[] processes = Process.GetProcessesByName("Application");
int numberToSend = 1500;
string str = string.Empty;
str = "start";
switch (str)
{
case "start":
numberToSend = 101;
break;
case "stop":
numberToSend = 102;
break;
case "error":
numberToSend = 103;
break;
}
if (processes.Length > 0)
{
//iterate through all running target applications
foreach (Process p in processes)
{
if (p.Id != proc.Id)
{
//now send the RF_TESTMESSAGE to the running instance
//SendMessage(p.MainWindowHandle, RF_TESTMESSAGE, IntPtr.Zero, IntPtr.Zero);
SendMessage(p.MainWindowHandle, WM_CUSTOM_MESSAGE, IntPtr.Zero, numberToSend);
}
}
}
else
{
MessageBox.Show("No other running applications found.");
}
}
protected override void WndProc(ref Message message)
{
//filter the RF_TESTMESSAGE
if (message.Msg == WM_CUSTOM_MESSAGE)
{
int numberReceived = (int)message.LParam;
string str=string.Empty;
//Do ur job with this integer
switch (numberReceived)
{
case 101: str = "start";
break;
case 102: str = "stop";
break;
case 103: str = "error";
break;
}
this.listBox1.Items.Add(str + "Received message RF_TESTMESSAGE");
}
else
{
base.WndProc(ref message);
}
////filter the RF_TESTMESSAGE
//if (message.Msg == RF_TESTMESSAGE)
//{
// //display that we recieved the message, of course we could do
// //something else more important here.
// this.listBox1.Items.Add("Received message RF_TESTMESSAGE");
//}
//be sure to pass along all messages to the base also
//base.WndProc(ref message);
}

What's wrong with this Lucene TokenFilter?

Disclaimer: I've been coding for 36 of the last 41 hours. I have a headache. And I can't figure out why this combining TokenFilter is returning 2 tokens, both the first token from the source stream.
public class TokenCombiner extends TokenFilter {
/*
* Recombines all tokens back into a single token using the specified delimiter.
*/
public TokenCombiner(TokenStream in, int delimiter) {
super(in);
this.delimiter = delimiter;
}
int delimiter;
private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class);
private final OffsetAttribute offsetAtt = addAttribute(OffsetAttribute.class);
private boolean firstToken = true;
int startOffset = 0;
#Override
public final boolean incrementToken() throws IOException {
while (true){
boolean eos = input.incrementToken(); //We have to process tokens even if they return end of file.
CharTermAttribute token = input.getAttribute(CharTermAttribute.class);
if (eos && token.length() == 0) break; //Break early to avoid extra whitespace.
if (firstToken){
startOffset = input.getAttribute(OffsetAttribute.class).startOffset();
firstToken = false;
}else{
termAtt.append(Character.toString((char)delimiter));
}
termAtt.append(token);
if (eos) break;
}
offsetAtt.setOffset(startOffset, input.getAttribute(OffsetAttribute.class).endOffset());
return false;
}
#Override
public void reset() throws IOException {
super.reset();
firstToken = true;
startOffset = 0;
}
}
I think the fundamental problem here, is that you must realize both TokenCombiner and the producer it consumes (input) share and reuse the same attributes! So token == termAtt always (try adding an assert!).
Man, that sucks if you have been coding for 36 hours on a weekend... try this:
public class TokenCombiner extends TokenFilter {
private final StringBuilder sb = new StringBuilder();
private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class);
private final OffsetAttribute offsetAtt = addAttribute(OffsetAttribute.class);
private final char separator;
private boolean consumed; // true if we already consumed
protected TokenCombiner(TokenStream input, char separator) {
super(input);
this.separator = separator;
}
#Override
public final boolean incrementToken() throws IOException {
if (consumed) {
return false; // don't call input.incrementToken() after it returns false
}
consumed = true;
int startOffset = 0;
int endOffset = 0;
boolean found = false; // true if we actually consumed any tokens
while (input.incrementToken()) {
if (!found) {
startOffset = offsetAtt.startOffset();
found = true;
}
sb.append(termAtt);
sb.append(separator);
endOffset = offsetAtt.endOffset();
}
if (found) {
assert sb.length() > 0; // always: because we append separator
sb.setLength(sb.length() - 1);
clearAttributes();
termAtt.setEmpty().append(sb);
offsetAtt.setOffset(startOffset, endOffset);
return true;
} else {
return false;
}
}
#Override
public void reset() throws IOException {
super.reset();
sb.setLength(0);
consumed = false;
}
}