2025年1月8日 星期三

[EnthernetENC] Failed to reacquire a new IP address from the DHCP server

MCU Board               : Raspberry Pi Pico

Ethernet Network Module : ENC28J60 

Firmware                : Arduino

EthernetENC Version     : 2.0.5


Issue: 

After switching to a different network, it fails to reacquire a new IP address from the DHCP server using `Ethernet.begin(mac)` function.


Solution: 

Modify the void UIPEthernetClass::end() function in EthernetENC/src/Ethernet.cpp.

*****

Change: 

    configure(INADDR_NONE, INADDR_NONE, INADDR_NONE, INADDR_NONE);

To:

    configure(INADDR_ANY, INADDR_ANY, INADDR_ANY, INADDR_ANY);

*****


***** 以上方法是試出來的,有沒有 side effect 不知道 😛 *****

2021年7月23日 星期五

[Flutter] 變更執行檔的檔案資訊(版本、描述、著作權)

Change the information of executable file.

找到 flutter 專案底下 windows/runner/Runner.rc

變更版本

#define VERSION_AS_NUMBER 1,0,0
#define VERSION_AS_STRING "1.0.0"

變更其他資訊

BEGIN
   VALUE "CompanyName", "公司名稱" "\0"
   VALUE "FileDescription", "檔案描述" "\0"
   VALUE "FileVersion", VERSION_AS_STRING "\0"
   VALUE "InternalName", "檔案內部名稱" "\0"
   VALUE "LegalCopyright", "著作權" "\0"
   VALUE "OriginalFilename", "原始檔名" "\0"
   VALUE "ProductName", "產品名稱" "\0"
   VALUE "ProductVersion", VERSION_AS_STRING "\0"
END

[Flutter] 變更建立後的執行檔名稱 (windows)

Change the executable name.

在 flutter 專案底下 windows/CMakeLists.txt 檔案,檔案的最下面加入底下這一行

set_target_properties(${BINARY_NAME} PROPERTIES OUTPUT_NAME_RELEASE "New Name")

[Flutter] 變更視窗的大小,並讓他啟動時出現在畫面的正中央 (windows)

Change the form size and make the starting position in the center of the screen

在 flutter 專案底下 windows/runner/main.cpp 檔案,找到底下兩行

Win32Window::Point origin(10, 10);
Win32Window::Size size(1280, 720);
並將其變更如下
int width = 800; // 設定 Form 寬度
int height = 600;  // 設定 Form 高度
int x = (GetSystemMetrics(SM_CXSCREEN) - width) / 2;
int y = (GetSystemMetrics(SM_CYSCREEN) - height) / 2;
Win32Window::Point origin(x, y);
Win32Window::Size size(width, height);

2021年7月20日 星期二

[Flutter] 變更應用程式的視窗標題 (windows)

Change the form title of your Flutter application.

在 flutter 專案底下 windows/runner/main.cpp 檔案,找到並變更底下這一行

window.CreateAndShow(L"New Title", origin, size)

2020年3月26日 星期四

pythonnet 經過 cythonize 之後會出現 ModuleNotFoundError 錯誤

原先的標準寫法如下

import clr
clr.AddReference('MyDLL')
from MyDLL import MyClass
my_obj = MyClass()

但是因為 pythonnet 會去覆寫 __import__ 函式,而 cython 又有自己的一套方式來處理 __import__ 函式,因而導致程式在 cythonize 之後會出現 ModuleNotFoundError 的錯誤

如果要建立 MyClass 的 instance 的話還是可以使用 .net 的 CreateInstance 方法

import clr
asm = clr.AddReference("MyDLL")
my_obj = asm.CreateInstance('MyDLL.MyClass')

2016年9月10日 星期六

解決在ng-repeat中radio未更新ng-model

原先寫法如下,確發生不管怎麼點selectedArea都不會更新
<label ng-repeat="area in areas">
    <input type="radio" ng-model="selectedArea" ng-value="area.Code"> {{area.Name}}
</label>
因為ng-repeat會產生自己的scope所以須使用$parent
<label ng-repeat="area in areas">
    <input type="radio" ng-model="$parent.selectedArea" ng-value="area.Code"> {{area.Name}}
</label>

2016年7月21日 星期四

讓 Web Api 輸出 JSON 格式

Web Api預設會優先輸出XML
有個偷吃步的方法就是乾脆讓程式不支援XML輸出
只要在Global.asax.cs的Application_Start()中加入以下程式碼即可

GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();

2014年12月12日 星期五

[android] camera release crash (相機釋放資源時偶爾會發生程式關閉閃退)

原先釋放相機資源時,偶爾都會發生程式整個跳出關閉
只因原先釋放資源的寫法如下:
_camera.stopPreview();
_camera.release();
_camera = null;

後來看到國外有網友提到,可以在stopPreview之前
先將Preview的Callback拿掉
也就是加入一行_camera.setPreviewCallback(null);
經測試後問題確實順利解決了

因此完整的資源釋放寫法如下:
_camera.setPreviewCallback(null);
_camera.stopPreview();
_camera.release();
_camera = null;

2014年11月28日 星期五

[c/c++] 指標的運算。為什麼指標可以相減確不能相加?

int x = 0;
int *px = &x;
int *py;
假設x所在的記憶體位址是0x1000,又假設int類型的大小為4bytes
當我們執行py = px + 1; 後,py指標中的值會等於 0x1000 + 4 = 0x1004
而執行py = px - 1; 後,py指標中的值會等於 0x1000 - 4 = 0x0FFC

由此可知當一個指標加減一個整數後,其結果還是一個指標,而不是一個整數值
而指標與整數的運算是以該指標的資料型態大小乘上整數後的值做為運算
所以
        結果指標 = 運算指標 +/- 運算值;
求結果指標的值的公式就是
        結果指標的值 = 運算指標的值 +/- (運算值 * 運算指標的資料型態大小)


再來說說指標之間的相減
就剛剛上面公式,利用簡單的數學將運算值移到=號的左邊,將結果指標移到=號的右邊
就可以得到
        運算值 = 運算指標 - 結果指標;
就剛剛求結果指標的值的公式,又可以推導出
        (運算值 * 運算指標的資料型態大小) = 運算指標的值 - 結果指標的值

舉個例子來看
假設有兩個int型態的指標pa與pb,pa指向0x2000而pb指向0x2008
r = pb - pa; 則r會是多少? 答案是2。為什麼不是8呢?
就上面的公式看來
(r * 4bytes) = 0x2008 - 0x2000
所以 r = (0x2008 - 0x2000) / 4 = 8 / 4 = 2

這裡又可以推導出另一個問題,那就是不同型態的指標之間不可以相減
例如:
char* pc;   int* pi;
int r = pi - pc;     // 編譯器會出錯
因為,就上面的公式而言,運算指標與結果指標的資料型態都是相同的,
依照求值的過程中會需要用到指標的資料型態大小,若是資料型態不同,
則編譯器不知道要以哪個為準。(其時把它當作編譯器規定的就好)

最後說明為什麼兩個指標之間不可以相加
因為,由上面的公式推導不出來兩個指標要如何相加,
也就是說兩個指標中的位址相加是無意義的。


以上屬個人觀點,若有錯誤的地方請不吝指教。

2012年11月8日 星期四

將sub-thread(子執行緒)的Method(方法)丟到main-thread(主執行緒)執行

執行MainForm中的_a.Start()會產生一個子執行緒
當執行緒發生例外時會去觸發ErrorEvent事件
若再catch中直接呼叫 this.ErrorEvent(this, new EventArgs()); 則會發生(InvalidOperationException)例外
(呼叫執行緒無法存取此物件,因為此物件屬於另一個執行緒)
因為Label1在主執行緒中被建立,所以不能被子執行緒直接呼叫。

因此我們可以透過Dispatcher物件來處理這個問題

class MainForm : Form
{
    private _a = new A();

    void Main()
    {
        _a.ErrorEvent += new EventHandler(Alert);
        A.Start();
    }
 
    privaet void Alert(object sender, EventArgs e)
    {
        Label1.Text = "發生例外了!!";
    }

}

class A
{
    private Thread _thread = null;

    private Dispatcher dispatcher = Dispatcher.CurrentDispatcher;
    
    public event EventHandler ErrorEvent;



    public void Start()
    {
        if (_thread == null)
        {
            _thread = new Thread(new ThreadStart(ThreadMethod));
            _thread.Start();
        }
    }

    private void ThreadMethod()
    {
        try
        {
            // do something;
        }
        catch (Exception ex)
        {
            //if (this.ErrorEvent != null) this.ErrorEvent(this, new EventArgs()); <= 錯誤
            if (this.ErrorEvent != null) dispatcher.BeginInvoke(this.ErrorEvent, this, new EventArgs());  <= 正確
        }


    }
}

2012年10月6日 星期六

Data Channel Port Range(資料通道連接埠範圍) 設定無效

奇怪~~ 明明將Data Channel Port Range的port設定在5000-5100 相對應的防火牆port也開了

怎麼用filezilla被動連線又出現 '無法取得目錄列表',當把防火牆關閉之後就可以正常取得了

我想問題還是在ftp server上,試著在IIS中將ftp server重新啟動,用netstat檢查一下

發現資料傳輸的port竟然在49319     =口=

怎麼會這樣~~~~ 我不是設定好了嗎? ftp也重開了啊~~ 怎麼會設定無效咧~~

弄了好久終於找到解決的方法了...

原來在IIS中將ftp重新啟動是沒有用的

要到 '服務' 中找到 'Microsoft FTP Service' 然後將此服務重新啟動就完成了

可惡 花了我這麼久的時間 T_T

2012年9月27日 星期四

jQuery ajax post 在IIS中無法存取 WebService (*.asmx)



有某段程式碼如下,在本機測試時沒問題,一放到IIS上就失敗

$.ajax({
type: "POST",
url: "/Services/CommonService.asmx/QueryNation",
data: '',
async: false,
success: function (result) {
var msg = $(result.lastChild).text();
alert(msg);
}
});


有兩種方式解決:

1. 在IIS上設定虛擬目錄,指向存放webservice的資料夾

2. 在web.config上設定webService區段,如下:
<!-- 設定允許Service存取 -->
<configuration>
 <system.web>
    <webServices>
      <protocols>
        <add name="HttpPost" />
      </protocols>
    </webServices>
 </system.web>
</configuration>

2012年9月14日 星期五

替IIS設定網站限制存取IP

先到微軟下載Web Platform後安裝執行

在安裝的項目當中仔細的找一下,會有一個叫IP 及網域限制的項目,找到後並安裝它。

接下來回到IIS設定,在左側點選要限制的站台,然後在右側的檢視功能畫面中找到IP位址及網域限制這個項目並點選開啟它,之後在右側的動作點選新增允許項目,在特定IP位址輸入您要允許的IP後按確定(當然也可以使用IP位址範圍來限制)。

當設定完成之後,必須還要限制除了剛剛設定好的IP之外,其他的任何IP都不得存取此站台,那就在右側的動作點選編輯功能設定,將未指定的用戶端的存取,設定為拒絕後確定。

完成!

注: IIS為7.5

解決:使用者'IIS APPPOOL\ASPNET v4.0'的登入失敗

發生的原因主要是因為網站所使用的'應用程式集區',預設使用'ApplicationPoolIdentity'做為識別,因此當網站使用integrated security=SSPI字串登入SQL Server時就會發生此錯誤。

解決的方法有兩種:
1. 不要使用 integrated security=SSPI 做為驗證的方法,改用 User Id=”xxx”; Password=”ooo” 來登入資料庫。

2. 到IIS應用程式集區,選擇您的網站所使用的集區,按右鍵 -> 進階設定 -> 識別,選擇NetworkService後按確定。接下來使用Microsoft SQL Server Management Studio,登入到您的SQL Server,找到安全性 -> 登入 -> 按右鍵點選’新增登入’-> 點選'搜尋'-> 輸入net ->點選’檢查名稱’ -> 在相符名稱當中選擇’NETWORK SERVICE’ -> 確定 -> 確定 -> 確定。接下來到伺服器角色把'sysadmin'打勾,按確定後完成。(當然伺服器角色的權限可依安全需求變更。)

2011年11月29日 星期二

[asp.net] 永久登入,延長(自訂)表單驗證(Forms Authentication)保存時間

有些網站會提供記錄使用者登入密碼二週或永久
如pchome的 '記住我的密碼' 、 yahoo的 '保持我的登入狀態'

若使用Login控制項時,可以在Login控制項的LoggedIn事件裡面加入下面的程式碼:

// 使用Login控制項,在成功登入之後會自動幫我們建立驗證的cookie
// 所以我們必須拿出來重新修改,改成我們希望延長的時間
HttpCookie cookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];

// 從cookie解碼還原票證
FormsAuthenticationTicket oldTicket = FormsAuthentication.Decrypt(cookie.Value);

// 建立新的票證 註:DateTime.Now.AddYears(1)為票證到期日,也就是希望延長的期限
FormsAuthenticationTicket newTicket = new FormsAuthenticationTicket(oldTicket.Version,
oldTicket.Name, DateTime.Now, DateTime.Now.AddYears(1), oldTicket.IsPersistent, oldTicket.UserData, FormsAuthentication.FormsCookiePath);

// 使用新的票證來建立新的驗證cookie
string cookiestr = FormsAuthentication.Encrypt(newTicket);
HttpCookie newCookie = new HttpCookie(FormsAuthentication.FormsCookieName, cookiestr);
newCookie.Expires = newTicket.Expiration;
newCookie.Path = FormsAuthentication.FormsCookiePath;

// 最後將新的驗證cookie重新寫回給user
Response.Cookies.Add(newCookie);

-----完成-----

2011年11月24日 星期四

submit特定元素的資料

有時候因為某些不可抗拒的因素,而只能將某些html元素寫在某個form當中

例子如下:

<form id="form1" method="post" action="post_target.html">
<input id="txtName" type="text" name="Name">
<input id="txtTel" type="text" name="Tel">
<input id="txtAddr" type="text" name="Address">
<input id="btnSend" type="submit" value="送出">
</form>
此時一按下送出,就會將整個form1的資料送出去

如果希望只送出Name欄位的資料出去該怎麼做呢?
以下為了程式碼的精簡,使用了jQuery來處理dom物件,改寫後的code如下
<form id="form1"> // 將 method="post" action="post_target.html"拿掉
<input id="txtName" type="text" name="Name">
<input id="txtTel" type="text" name="Tel">
<input id="txtAddr" type="text" name="Address">
<input id="btnSend" type="button" value="送出" onclick="doPost();" />
</form>

<script type="text/javascript">
function pay() {
var name= $('#txtName').val();
var form = $('<form method="post" action="post_target.html"></form>');
form.append('<input type="hidden" name="Name" value="' + name + '" />"');
$('body').append(form);
form.submit();
}
</script>

2011年11月23日 星期三

[C#] long(Int64) 與 base64 互轉

// long(Int64) 轉 base64
var buffer1 = BitConverter.GetBytes(long.MaxValue);
string str = Convert.ToBase64String(buffer1);

// base6轉long(Int64)
var buffer2 = Convert.FromBase64String(str);
long val = BitConverter.ToInt64(buffer2, 0);

2011年11月17日 星期四

LINQ動態查詢 使用(PredicateBuilder)

官網抵佳:PredicateBuilder
需使用套件: LINQKit
套件及範例下載位址:在LINQKit頁面的最下方

官網範例如下
IQueryable<SearchProducts>(params string[] keywords)
{
 var predicate = PredicateBuilder.False();
 foreach (string keyword in keywords)
 {
  string temp = keyword; // 很重要!! 一定要加
  predicate = predicate.Or (p => p.Description.Contains (temp));
 }
 return dataContext.Products.Where (predicate);
}

--------------------------------
下面是運作說明

步驟1:建立PredicateBuilder物件(我們需要使用此物建來作查詢條件的串接)
var predicate = PredicateBuilder.False();
步驟2:迴圈加入查詢條件
foreach(string keyword in keywords)
{
  string temp = keyword; // 避免參考到相同變數位址,所以需加上此行
  predicate = predicate.Or (p =< p.Description.Contains (temp));
}
步驟3:執行查詢
dataContext.Products.Where (predicate);
or 使用 dataContext.Products.Where(predicate.Compile());

-----------------完成!!------------------

接下來是運作原理的說明

當只執行
var predicate = PredicateBuilder.False();
dataContext.Products.Where (predicate.Compile());
這段描述看起來會像是 dataContext.Products.Where (src => false);

若是執行
var predicate = PredicateBuilder.False();
predicate = predicate.Or (src => src.keyword == "123");
dataContext.Products.Where (predicate.Compile());
這段描述看起來會像是 dataContext.Products.Where (src => false || src.keyword == "123");

若是執行
var predicate = PredicateBuilder.False();
predicate = predicate.Or (src => src.keyword == "123");
predicate = predicate.And(src => src.id == 5);
dataContext.Products.Where (predicate.Compile());
這段描述看起來會像是 dataContext.Products.Where (src => false || src.keyword == "123" && src.id == 5);

由此可知條件是串接起來的
因此預設選擇PredicateBuilder.False或PredicateBuilder.True就很重要了

舉個例子,如果希望找出keyword1或keyword2,兩個關鍵字只要一個成立即可的結果

範例會像這樣
var predicate = PredicateBuilder.False();
predicate = predicate.Or (src => src.keyword == "123");
predicate = predicate.Or (src => src.keyword == "456");
dataContext.Products.Where (predicate.Compile());
這段描述看起來會像是 dataContext.Products.Where (src => false || src.keyword == "123" ||src.keyword == "456"); //這是正確的結果
若預設選擇PredicateBuilder.True();
這段描述看起來會像是dataContext.Products.Where (src => true || src.keyword == "123" ||src.keyword == "456");
這樣一來查詢的結果永遠會是true,而導致錯誤了

在一個例子,如果希望找出keyword1且keyword2,兩個關鍵字都要成立的結果
範例應該像這樣
var predicate = PredicateBuilder.True();
predicate = predicate.And (src => src.keyword == "123");
predicate = predicate.And (src => src.keyword == "456");
dataContext.Products.Where (predicate.Compile());
這段描述看起來會像是 dataContext.Products.Where (src => true && src.keyword == "123" && src.keyword == "456"); //這是正確的結果
若預設選擇PredicateBuilder.False();
這段描述看起來會像是 dataContext.Products.Where (src => false && src.keyword == "123" && src.keyword == "456");
這樣一來查詢的結果就永遠會是false,而導致錯誤了







2011年10月6日 星期四

WebControl Text屬性 讓Html Tag失效

當使用Asp.net WebControl的Text屬性時

遇到如 Label.Text = "<span style=\"color:red\">HelloWorld</span>";
若我們希望他能夠完整顯示 <span style=\"color:red\">HelloWorld</span>字串
而不是顯示 HelloWorld

則需使用 Server.HtmlEncode 方法

修正後如下
Label.Text = Server.HtmlEncode( "<span style=\"color:red\">HelloWorld</span>");